#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, int groupmatch, int *busy, int *channelmatched, int *groupmatched) |
static int | build_channels (struct zt_chan_conf conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo) |
static int | bump_gains (struct zt_pvt *p) |
static struct zt_pvt * | chandup (struct zt_pvt *src) |
static int | check_for_conference (struct zt_pvt *p) |
static int | conf_add (struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel) |
static int | conf_del (struct zt_pvt *p, struct zt_subchannel *c, int index) |
static int | destroy_channel (struct zt_pvt *prev, struct zt_pvt *cur, int now) |
static void | destroy_zt_pvt (struct zt_pvt **pvt) |
static int | digit_to_dtmfindex (char digit) |
static void | disable_dtmf_detect (struct zt_pvt *p) |
static void * | do_monitor (void *data) |
static void | enable_dtmf_detect (struct zt_pvt *p) |
static char * | event2str (int event) |
static void | fill_rxgain (struct zt_gains *g, float gain, int law) |
static void | fill_txgain (struct zt_gains *g, float gain, int law) |
static struct zt_pvt * | find_channel (int channel) |
static int | get_alarms (struct zt_pvt *p) |
static int | handle_init_event (struct zt_pvt *i, int event) |
static int | handle_zap_show_cadences (int fd, int argc, char *argv[]) |
static int | has_voicemail (struct zt_pvt *p) |
static int | isourconf (struct zt_pvt *p, struct zt_subchannel *c) |
static int | isslavenative (struct zt_pvt *p, struct zt_pvt **out) |
static int | load_module (void) |
static struct zt_pvt * | mkintf (int channel, struct zt_chan_conf conf, struct zt_pri *pri, int reloading) |
static int | my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms) |
static int | my_zt_write (struct zt_pvt *p, unsigned char *buf, int len, int index, int linear) |
static int | process_zap (struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels) |
static int | reload (void) |
static int | reset_conf (struct zt_pvt *p) |
static int | restart_monitor (void) |
static int | restore_conference (struct zt_pvt *p) |
static int | restore_gains (struct zt_pvt *p) |
static int | save_conference (struct zt_pvt *p) |
static int | send_callerid (struct zt_pvt *p) |
static int | send_cwcidspill (struct zt_pvt *p) |
static int | set_actual_gain (int fd, int chan, float rxgain, float txgain, int law) |
static int | set_actual_rxgain (int fd, int chan, float gain, int law) |
static int | set_actual_txgain (int fd, int chan, float gain, int law) |
static int | setup_zap (int reload) |
static void * | ss_thread (void *data) |
static void | swap_subs (struct zt_pvt *p, int a, int b) |
static int | unalloc_sub (struct zt_pvt *p, int x) |
static int | unload_module (void) |
static int | update_conf (struct zt_pvt *p) |
static void | wakeup_sub (struct zt_pvt *p, int a, void *pri) |
static int | zap_destroy_channel (int fd, int argc, char **argv) |
static int | zap_destroy_channel_bynum (int channel) |
static int | zap_fake_event (struct zt_pvt *p, int mode) |
static void | zap_queue_frame (struct zt_pvt *p, struct ast_frame *f, void *pri) |
static int | zap_restart (void) |
static int | zap_restart_cmd (int fd, int argc, char **argv) |
static int | zap_show_channel (int fd, int argc, char **argv) |
static int | zap_show_channels (int fd, int argc, char **argv) |
static int | zap_show_status (int fd, int argc, char *argv[]) |
static char * | zap_sig2str (int sig) |
static int | zt_answer (struct ast_channel *ast) |
static enum ast_bridge_result | zt_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | zt_call (struct ast_channel *ast, char *rdest, int timeout) |
static int | zt_callwait (struct ast_channel *ast) |
static struct zt_chan_conf | zt_chan_conf_default (void) |
static void | zt_close (int fd) |
static int | zt_confmute (struct zt_pvt *p, int muted) |
static int | zt_digit_begin (struct ast_channel *ast, char digit) |
static int | zt_digit_end (struct ast_channel *ast, char digit, unsigned int duration) |
static void | zt_disable_ec (struct zt_pvt *p) |
static void | zt_enable_ec (struct zt_pvt *p) |
static struct ast_frame * | zt_exception (struct ast_channel *ast) |
static int | zt_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static int | zt_func_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len) |
static int | zt_get_event (int fd) |
Avoid the silly zt_getevent which ignores a bunch of events. | |
static int | zt_get_index (struct ast_channel *ast, struct zt_pvt *p, int nullok) |
static void | zt_handle_dtmfup (struct ast_channel *ast, int index, struct ast_frame **dest) |
static struct ast_frame * | zt_handle_event (struct ast_channel *ast) |
static int | zt_hangup (struct ast_channel *ast) |
static int | zt_indicate (struct ast_channel *chan, int condition, const void *data, size_t datalen) |
static void | zt_link (struct zt_pvt *slave, struct zt_pvt *master) |
static struct ast_channel * | zt_new (struct zt_pvt *, int, int, int, int, int) |
static int | zt_open (char *fn) |
static struct ast_frame * | zt_read (struct ast_channel *ast) |
static struct ast_channel * | zt_request (const char *type, int format, void *data, int *cause) |
static int | zt_ring_phone (struct zt_pvt *p) |
static int | zt_sendtext (struct ast_channel *c, const char *text) |
static int | zt_set_hook (int fd, int hs) |
static int | zt_setlinear (int zfd, int linear) |
static int | zt_setoption (struct ast_channel *chan, int option, void *data, int datalen) |
static void | zt_train_ec (struct zt_pvt *p) |
static void | zt_unlink (struct zt_pvt *slave, struct zt_pvt *master, int needlock) |
static int | zt_wait_event (int fd) |
Avoid the silly zt_waitevent which ignores a bunch of events. | |
static int | zt_wink (struct zt_pvt *p, int index) |
static int | zt_write (struct ast_channel *ast, struct ast_frame *frame) |
Variables | |
struct { | |
int alarm | |
char * name | |
} | alarms [] |
static struct zt_ring_cadence | cadences [NUM_CADENCE_MAX] |
static int | cidrings [NUM_CADENCE_MAX] |
cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on. | |
static const char | config [] = "zapata.conf" |
static struct ast_jb_conf | default_jbconf |
static char | defaultcic [64] = "" |
static char | defaultozz [64] = "" |
static char | destroy_channel_usage [] |
static int | distinctiveringaftercid = 0 |
static struct zt_distRings | drings |
static char * | events [] |
static int | firstdigittimeout = 16000 |
Wait up to 16 seconds for first digit (FXO logic). | |
static int | gendigittimeout = 8000 |
How long to wait for following digits (FXO logic). | |
static struct ast_jb_conf | global_jbconf |
static int | ifcount = 0 |
static struct zt_pvt * | ifend |
static struct zt_pvt * | iflist |
static int | matchdigittimeout = 3000 |
How long to wait for an extra digit, if there is an ambiguous match. | |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static int | num_cadence = 4 |
static int | numbufs = 4 |
static char | progzone [10] = "" |
static int | ringt_base = DEFAULT_RINGT |
struct zt_pvt * | round_robin [32] |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char * | subnames [] |
static const char | tdesc [] = "Zapata Telephony Driver" |
static int | user_has_defined_cadences = 0 |
static struct ast_cli_entry | zap_cli [] |
static char | zap_restart_usage [] |
static char | zap_show_cadences_help [] |
static char | zap_show_status_usage [] |
static struct ast_channel_tech | zap_tech |
Connects to the zaptel telephony library as well as libpri. Libpri is optional and needed only if you are going to use ISDN connections.
You need to install libraries before you attempt to compile and install the zaptel channel.
Definition in file chan_zap.c.
#define ASCII_BYTES_PER_CHAR 80 |
Referenced by zt_sendtext().
#define AST_LAW | ( | p | ) | (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
Definition at line 154 of file chan_zap.c.
Referenced by do_monitor(), send_cwcidspill(), ss_thread(), zt_call(), zt_callwait(), and zt_sendtext().
#define CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
#define CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
300 ms
Definition at line 282 of file chan_zap.c.
#define CANBUSYDETECT | ( | p | ) | (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define CANPROGRESSDETECT | ( | p | ) | (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define CHAN_PSEUDO -2 |
Definition at line 196 of file chan_zap.c.
Referenced by build_channels(), enable_dtmf_detect(), mkintf(), process_zap(), zt_new(), and zt_request().
#define CHANNEL_PSEUDO -12 |
Definition at line 152 of file chan_zap.c.
#define CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
#define CONF_USER_REAL (1 << 0) |
Definition at line 406 of file chan_zap.c.
#define CONF_USER_THIRDCALL (1 << 1) |
Definition at line 407 of file chan_zap.c.
#define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
Definition at line 202 of file chan_zap.c.
#define DCHAN_NOTINALARM (1 << 1) |
Definition at line 199 of file chan_zap.c.
#define DCHAN_PROVISIONED (1 << 0) |
Definition at line 198 of file chan_zap.c.
#define DCHAN_UP (1 << 2) |
Definition at line 200 of file chan_zap.c.
#define DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID.
Define if you want to check the hook state for an FXO (FXS signalled) interface before dialing on it. Certain FXO interfaces always think they're out of service with this method however.
Definition at line 150 of file chan_zap.c.
Referenced by zt_chan_conf_default().
#define DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
Definition at line 286 of file chan_zap.c.
#define END_SILENCE_LEN 400 |
Referenced by zt_sendtext().
#define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" |
#define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" |
#define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define GET_CHANNEL | ( | p | ) | ((p)->channel) |
#define HANGUP 1 |
Definition at line 10126 of file chan_zap.c.
Referenced by action_transferhangup(), and zap_fake_event().
#define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
Referenced by build_alerting(), build_connect(), build_connect_acknowledge(), build_disconnect(), build_facility(), build_hold(), build_hold_acknowledge(), build_hold_reject(), build_information(), build_notify(), build_proceeding(), build_progress(), build_release(), build_release_complete(), build_restart(), build_resume(), build_resume_acknowledge(), build_resume_reject(), build_retrieve(), build_retrieve_acknowledge(), build_retrieve_reject(), build_setup(), build_setup_acknowledge(), build_status(), build_status_enquiry(), build_suspend(), build_suspend_acknowledge(), build_suspend_reject(), build_timeout(), build_user_information(), parse_alerting(), parse_connect(), parse_disconnect(), parse_facility(), parse_information(), parse_proceeding(), parse_progress(), parse_release(), parse_release_complete(), parse_restart(), parse_setup(), parse_setup_acknowledge(), parse_status(), and zt_sendtext().
#define HEADER_MS 50 |
Referenced by zt_sendtext().
#define ISTRUNK | ( | p | ) |
#define MASK_AVAIL (1 << 0) |
Channel available for PRI use
Definition at line 279 of file chan_zap.c.
#define MASK_INUSE (1 << 1) |
Channel currently in use
Definition at line 280 of file chan_zap.c.
#define MAX_CHANLIST_LEN 80 |
The length of the parameters list of 'zapchan'.
Definition at line 10480 of file chan_zap.c.
Referenced by process_zap().
#define MAX_CHANNELS 672 |
No more than a DS3 per trunk group
Definition at line 194 of file chan_zap.c.
Referenced by mkintf().
#define MAX_SLAVES 4 |
Definition at line 409 of file chan_zap.c.
Referenced by isslavenative(), update_conf(), zap_show_channel(), zt_link(), and zt_unlink().
#define MIN_MS_SINCE_FLASH ( (2000) ) |
#define NEED_MFDETECT | ( | p | ) | (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) |
Signaling types that need to use MF detection should be placed in this macro.
Definition at line 157 of file chan_zap.c.
Referenced by ss_thread(), and zt_new().
#define NUM_CADENCE_MAX 25 |
#define NUM_DCHANS 4 |
No more than 4 d-channels
Definition at line 193 of file chan_zap.c.
#define NUM_SPANS 32 |
Definition at line 192 of file chan_zap.c.
#define POLARITY_IDLE 0 |
Definition at line 364 of file chan_zap.c.
Referenced by unalloc_sub(), zt_handle_event(), and zt_hangup().
#define POLARITY_REV 1 |
Definition at line 365 of file chan_zap.c.
Referenced by handle_init_event(), and zt_handle_event().
#define READ_SIZE 160 |
Chunk size to read -- we use 20ms chunks to make things happy.
Definition at line 277 of file chan_zap.c.
Referenced by my_zt_write(), process_zap(), send_cwcidspill(), zt_callwait(), zt_open(), zt_read(), zt_sendtext(), and zt_setoption().
#define sig2str zap_sig2str |
Definition at line 1219 of file chan_zap.c.
Referenced by action_zapshowchannels(), build_channels(), handle_init_event(), mkintf(), ss_thread(), zap_show_channel(), and zt_handle_event().
#define SIG_E911 (0x1000000 | ZT_SIG_EM) |
Definition at line 172 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EM ZT_SIG_EM |
Definition at line 167 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EM_E1 ZT_SIG_EM_E1 |
Definition at line 188 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EMWINK (0x0100000 | ZT_SIG_EM) |
Definition at line 168 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATB (0x0800000 | ZT_SIG_EM) |
Definition at line 171 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATD (0x0200000 | ZT_SIG_EM) |
Definition at line 169 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
Definition at line 170 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM) |
Definition at line 173 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FGC_CAMA (0x4000000 | ZT_SIG_EM) |
Definition at line 174 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM) |
Definition at line 175 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FXOGS ZT_SIG_FXOGS |
Definition at line 180 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
#define SIG_FXOKS ZT_SIG_FXOKS |
Definition at line 181 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
#define SIG_FXOLS ZT_SIG_FXOLS |
Definition at line 179 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
#define SIG_FXSGS ZT_SIG_FXSGS |
Definition at line 177 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_indicate().
#define SIG_FXSKS ZT_SIG_FXSKS |
Definition at line 178 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), and zt_request().
#define SIG_FXSLS ZT_SIG_FXSLS |
Definition at line 176 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_indicate().
#define SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) |
Definition at line 189 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), and zap_sig2str().
#define SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS) |
Definition at line 190 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), and zap_sig2str().
#define SIG_PRI ZT_SIG_CLEAR |
Definition at line 182 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_digit_begin(), zt_digit_end(), zt_enable_ec(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), zt_read(), and zt_write().
#define SIG_SF ZT_SIG_SF |
Definition at line 183 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATB (0x0800000 | ZT_SIG_SF) |
Definition at line 187 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) |
Definition at line 185 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF) |
Definition at line 186 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SFWINK (0x0100000 | ZT_SIG_SF) |
Definition at line 184 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SMDI_MD_WAIT_TIMEOUT 1500 |
#define SUB_CALLWAIT 1 |
Call-Waiting call on hold
Definition at line 360 of file chan_zap.c.
#define SUB_REAL 0 |
Active call
Definition at line 359 of file chan_zap.c.
#define SUB_THREEWAY 2 |
Three-way call
Definition at line 361 of file chan_zap.c.
#define tdesc "Zapata Telephony" |
Definition at line 11446 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 10307 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::cidspill, destroy_zt_pvt(), free, iflist, master, zt_pvt::next, zt_pvt::owner, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, zt_subchannel::zfd, and zt_close().
10308 { 10309 int x = 0; 10310 struct zt_pvt *p, *pl; 10311 #ifdef HAVE_PRI 10312 int i; 10313 for (i = 0; i < NUM_SPANS; i++) { 10314 if (pris[i].master != AST_PTHREADT_NULL) 10315 pthread_cancel(pris[i].master); 10316 } 10317 ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 10318 ast_unregister_application(zap_send_keypad_facility_app); 10319 #endif 10320 ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 10321 ast_manager_unregister( "ZapDialOffhook" ); 10322 ast_manager_unregister( "ZapHangup" ); 10323 ast_manager_unregister( "ZapTransfer" ); 10324 ast_manager_unregister( "ZapDNDoff" ); 10325 ast_manager_unregister( "ZapDNDon" ); 10326 ast_manager_unregister("ZapShowChannels"); 10327 ast_manager_unregister("ZapRestart"); 10328 ast_channel_unregister(&zap_tech); 10329 ast_mutex_lock(&iflock); 10330 /* Hangup all interfaces if they have an owner */ 10331 p = iflist; 10332 while (p) { 10333 if (p->owner) 10334 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 10335 p = p->next; 10336 } 10337 ast_mutex_unlock(&iflock); 10338 ast_mutex_lock(&monlock); 10339 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 10340 pthread_cancel(monitor_thread); 10341 pthread_kill(monitor_thread, SIGURG); 10342 pthread_join(monitor_thread, NULL); 10343 } 10344 monitor_thread = AST_PTHREADT_STOP; 10345 ast_mutex_unlock(&monlock); 10346 10347 ast_mutex_lock(&iflock); 10348 /* Destroy all the interfaces and free their memory */ 10349 p = iflist; 10350 while (p) { 10351 /* Free any callerid */ 10352 if (p->cidspill) 10353 free(p->cidspill); 10354 /* Close the zapata thingy */ 10355 if (p->subs[SUB_REAL].zfd > -1) 10356 zt_close(p->subs[SUB_REAL].zfd); 10357 pl = p; 10358 p = p->next; 10359 x++; 10360 /* Free associated memory */ 10361 if (pl) 10362 destroy_zt_pvt(&pl); 10363 ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x); 10364 } 10365 iflist = NULL; 10366 ifcount = 0; 10367 ast_mutex_unlock(&iflock); 10368 #ifdef HAVE_PRI 10369 for (i = 0; i < NUM_SPANS; i++) { 10370 if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) 10371 pthread_join(pris[i].master, NULL); 10372 zt_close(pris[i].fds[i]); 10373 } 10374 #endif 10375 return 0; 10376 }
static struct ast_frame* __zt_exception | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 4486 of file chan_zap.c.
References ast_channel::_state, ast_bridged_channel(), AST_CONTROL_UNHOLD, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_pvt::callwaitingrepeat, zt_pvt::channel, zt_pvt::cidcwexpire, ast_frame::data, ast_frame::datalen, ast_frame::delivery, zt_pvt::dialing, event2str(), zt_subchannel::f, zt_pvt::fake_event, ast_channel::fds, zt_pvt::flashtime, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, zt_subchannel::needanswer, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::oprmode, option_debug, option_verbose, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, ast_frame::samples, ast_frame::src, SUB_REAL, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_disable_ec(), zt_get_event(), zt_get_index(), zt_handle_event(), zt_ring_phone(), and zt_set_hook().
Referenced by zt_exception(), and zt_read().
04487 { 04488 struct zt_pvt *p = ast->tech_pvt; 04489 int res; 04490 int usedindex=-1; 04491 int index; 04492 struct ast_frame *f; 04493 04494 04495 index = zt_get_index(ast, p, 1); 04496 04497 p->subs[index].f.frametype = AST_FRAME_NULL; 04498 p->subs[index].f.datalen = 0; 04499 p->subs[index].f.samples = 0; 04500 p->subs[index].f.mallocd = 0; 04501 p->subs[index].f.offset = 0; 04502 p->subs[index].f.subclass = 0; 04503 p->subs[index].f.delivery = ast_tv(0,0); 04504 p->subs[index].f.src = "zt_exception"; 04505 p->subs[index].f.data = NULL; 04506 04507 04508 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) { 04509 /* If nobody owns us, absorb the event appropriately, otherwise 04510 we loop indefinitely. This occurs when, during call waiting, the 04511 other end hangs up our channel so that it no longer exists, but we 04512 have neither FLASH'd nor ONHOOK'd to signify our desire to 04513 change to the other channel. */ 04514 if (p->fake_event) { 04515 res = p->fake_event; 04516 p->fake_event = 0; 04517 } else 04518 res = zt_get_event(p->subs[SUB_REAL].zfd); 04519 /* Switch to real if there is one and this isn't something really silly... */ 04520 if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) && 04521 (res != ZT_EVENT_HOOKCOMPLETE)) { 04522 ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res); 04523 p->owner = p->subs[SUB_REAL].owner; 04524 if (p->owner && ast_bridged_channel(p->owner)) 04525 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04526 p->subs[SUB_REAL].needunhold = 1; 04527 } 04528 switch (res) { 04529 case ZT_EVENT_ONHOOK: 04530 zt_disable_ec(p); 04531 if (p->owner) { 04532 if (option_verbose > 2) 04533 ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name); 04534 zt_ring_phone(p); 04535 p->callwaitingrepeat = 0; 04536 p->cidcwexpire = 0; 04537 } else 04538 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04539 update_conf(p); 04540 break; 04541 case ZT_EVENT_RINGOFFHOOK: 04542 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 04543 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 04544 p->subs[SUB_REAL].needanswer = 1; 04545 p->dialing = 0; 04546 } 04547 break; 04548 case ZT_EVENT_HOOKCOMPLETE: 04549 case ZT_EVENT_RINGERON: 04550 case ZT_EVENT_RINGEROFF: 04551 /* Do nothing */ 04552 break; 04553 case ZT_EVENT_WINKFLASH: 04554 gettimeofday(&p->flashtime, NULL); 04555 if (p->owner) { 04556 if (option_verbose > 2) 04557 ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 04558 if (p->owner->_state != AST_STATE_UP) { 04559 /* Answer if necessary */ 04560 usedindex = zt_get_index(p->owner, p, 0); 04561 if (usedindex > -1) { 04562 p->subs[usedindex].needanswer = 1; 04563 } 04564 ast_setstate(p->owner, AST_STATE_UP); 04565 } 04566 p->callwaitingrepeat = 0; 04567 p->cidcwexpire = 0; 04568 if (ast_bridged_channel(p->owner)) 04569 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04570 p->subs[SUB_REAL].needunhold = 1; 04571 } else 04572 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04573 update_conf(p); 04574 break; 04575 default: 04576 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 04577 } 04578 f = &p->subs[index].f; 04579 return f; 04580 } 04581 if (!(p->radio || (p->oprmode < 0)) && option_debug) 04582 ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 04583 /* If it's not us, return NULL immediately */ 04584 if (ast != p->owner) { 04585 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 04586 f = &p->subs[index].f; 04587 return f; 04588 } 04589 f = zt_handle_event(ast); 04590 return f; 04591 }
static int action_transfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10194 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), TRANSFER, and zap_fake_event().
Referenced by load_module().
10195 { 10196 struct zt_pvt *p = NULL; 10197 const char *channel = astman_get_header(m, "ZapChannel"); 10198 10199 if (ast_strlen_zero(channel)) { 10200 astman_send_error(s, m, "No channel specified"); 10201 return 0; 10202 } 10203 p = find_channel(atoi(channel)); 10204 if (!p) { 10205 astman_send_error(s, m, "No such channel"); 10206 return 0; 10207 } 10208 zap_fake_event(p,TRANSFER); 10209 astman_send_ack(s, m, "ZapTransfer"); 10210 return 0; 10211 }
static int action_transferhangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10213 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), HANGUP, and zap_fake_event().
Referenced by load_module().
10214 { 10215 struct zt_pvt *p = NULL; 10216 const char *channel = astman_get_header(m, "ZapChannel"); 10217 10218 if (ast_strlen_zero(channel)) { 10219 astman_send_error(s, m, "No channel specified"); 10220 return 0; 10221 } 10222 p = find_channel(atoi(channel)); 10223 if (!p) { 10224 astman_send_error(s, m, "No such channel"); 10225 return 0; 10226 } 10227 zap_fake_event(p,HANGUP); 10228 astman_send_ack(s, m, "ZapHangup"); 10229 return 0; 10230 }
static int action_zapdialoffhook | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10232 of file chan_zap.c.
References AST_FRAME_DTMF, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), zt_pvt::owner, and zap_queue_frame().
Referenced by load_module().
10233 { 10234 struct zt_pvt *p = NULL; 10235 const char *channel = astman_get_header(m, "ZapChannel"); 10236 const char *number = astman_get_header(m, "Number"); 10237 int i; 10238 10239 if (ast_strlen_zero(channel)) { 10240 astman_send_error(s, m, "No channel specified"); 10241 return 0; 10242 } 10243 if (ast_strlen_zero(number)) { 10244 astman_send_error(s, m, "No number specified"); 10245 return 0; 10246 } 10247 p = find_channel(atoi(channel)); 10248 if (!p) { 10249 astman_send_error(s, m, "No such channel"); 10250 return 0; 10251 } 10252 if (!p->owner) { 10253 astman_send_error(s, m, "Channel does not have it's owner"); 10254 return 0; 10255 } 10256 for (i = 0; i < strlen(number); i++) { 10257 struct ast_frame f = { AST_FRAME_DTMF, number[i] }; 10258 zap_queue_frame(p, &f, NULL); 10259 } 10260 astman_send_ack(s, m, "ZapDialOffhook"); 10261 return 0; 10262 }
static int action_zapdndoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10175 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, and find_channel().
Referenced by load_module().
10176 { 10177 struct zt_pvt *p = NULL; 10178 const char *channel = astman_get_header(m, "ZapChannel"); 10179 10180 if (ast_strlen_zero(channel)) { 10181 astman_send_error(s, m, "No channel specified"); 10182 return 0; 10183 } 10184 p = find_channel(atoi(channel)); 10185 if (!p) { 10186 astman_send_error(s, m, "No such channel"); 10187 return 0; 10188 } 10189 p->dnd = 0; 10190 astman_send_ack(s, m, "DND Disabled"); 10191 return 0; 10192 }
static int action_zapdndon | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10156 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, and find_channel().
Referenced by load_module().
10157 { 10158 struct zt_pvt *p = NULL; 10159 const char *channel = astman_get_header(m, "ZapChannel"); 10160 10161 if (ast_strlen_zero(channel)) { 10162 astman_send_error(s, m, "No channel specified"); 10163 return 0; 10164 } 10165 p = find_channel(atoi(channel)); 10166 if (!p) { 10167 astman_send_error(s, m, "No such channel"); 10168 return 0; 10169 } 10170 p->dnd = 1; 10171 astman_send_ack(s, m, "DND Enabled"); 10172 return 0; 10173 }
static int action_zaprestart | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 9783 of file chan_zap.c.
References astman_send_ack(), astman_send_error(), and zap_restart().
Referenced by load_module().
09784 { 09785 if (zap_restart() != 0) { 09786 astman_send_error(s, m, "Failed rereading zaptel configuration"); 09787 return 1; 09788 } 09789 astman_send_ack(s, m, "ZapRestart: Success"); 09790 return 0; 09791 }
static int action_zapshowchannels | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 10264 of file chan_zap.c.
References alarm, alarm2str(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), zt_pvt::channel, zt_pvt::context, zt_pvt::dnd, get_alarms(), iflist, zt_pvt::next, zt_pvt::sig, and sig2str.
Referenced by load_module().
10265 { 10266 struct zt_pvt *tmp = NULL; 10267 const char *id = astman_get_header(m, "ActionID"); 10268 char idText[256] = ""; 10269 10270 astman_send_ack(s, m, "Zapata channel status will follow"); 10271 if (!ast_strlen_zero(id)) 10272 snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id); 10273 10274 ast_mutex_lock(&iflock); 10275 10276 tmp = iflist; 10277 while (tmp) { 10278 if (tmp->channel > 0) { 10279 int alarm = get_alarms(tmp); 10280 astman_append(s, 10281 "Event: ZapShowChannels\r\n" 10282 "Channel: %d\r\n" 10283 "Signalling: %s\r\n" 10284 "Context: %s\r\n" 10285 "DND: %s\r\n" 10286 "Alarm: %s\r\n" 10287 "%s" 10288 "\r\n", 10289 tmp->channel, sig2str(tmp->sig), tmp->context, 10290 tmp->dnd ? "Enabled" : "Disabled", 10291 alarm2str(alarm), idText); 10292 } 10293 10294 tmp = tmp->next; 10295 } 10296 10297 ast_mutex_unlock(&iflock); 10298 10299 astman_append(s, 10300 "Event: ZapShowChannelsComplete\r\n" 10301 "%s" 10302 "\r\n", 10303 idText); 10304 return 0; 10305 }
static char* alarm2str | ( | int | alarm | ) | [static] |
Definition at line 1130 of file chan_zap.c.
References alarms.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
01131 { 01132 int x; 01133 for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) { 01134 if (alarms[x].alarm & alarm) 01135 return alarms[x].name; 01136 } 01137 return alarm ? "Unknown Alarm" : "No Alarm"; 01138 }
static int alloc_sub | ( | struct zt_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 928 of file chan_zap.c.
References ast_log(), zt_subchannel::chan, zt_pvt::channel, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::subs, zt_subchannel::zfd, zt_close(), and zt_open().
Referenced by ss_thread(), zt_handle_event(), and zt_request().
00929 { 00930 ZT_BUFFERINFO bi; 00931 int res; 00932 if (p->subs[x].zfd < 0) { 00933 p->subs[x].zfd = zt_open("/dev/zap/pseudo"); 00934 if (p->subs[x].zfd > -1) { 00935 res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi); 00936 if (!res) { 00937 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 00938 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 00939 bi.numbufs = numbufs; 00940 res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi); 00941 if (res < 0) { 00942 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x); 00943 } 00944 } else 00945 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x); 00946 if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) { 00947 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd); 00948 zt_close(p->subs[x].zfd); 00949 p->subs[x].zfd = -1; 00950 return -1; 00951 } 00952 if (option_debug) 00953 ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan); 00954 return 0; 00955 } else 00956 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 00957 return -1; 00958 } 00959 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel); 00960 return -1; 00961 }
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 3483 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_indicate(), ast_log(), ast_mutex_unlock(), ast_queue_control(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_RINGING, ast_channel::cdr, ast_channel::lock, LOG_DEBUG, LOG_WARNING, zt_subchannel::owner, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), unalloc_sub(), and zt_subchannel::zfd.
03484 { 03485 /* In order to transfer, we need at least one of the channels to 03486 actually be in a call bridge. We can't conference two applications 03487 together (but then, why would we want to?) */ 03488 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 03489 /* The three-way person we're about to transfer to could still be in MOH, so 03490 stop if now if appropriate */ 03491 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 03492 ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 03493 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 03494 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 03495 } 03496 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) { 03497 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 03498 } 03499 if (p->subs[SUB_REAL].owner->cdr) { 03500 /* Move CDR from second channel to current one */ 03501 p->subs[SUB_THREEWAY].owner->cdr = 03502 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr); 03503 p->subs[SUB_REAL].owner->cdr = NULL; 03504 } 03505 if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) { 03506 /* Move CDR from second channel's bridge to current one */ 03507 p->subs[SUB_THREEWAY].owner->cdr = 03508 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr); 03509 ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL; 03510 } 03511 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 03512 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03513 ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name); 03514 return -1; 03515 } 03516 /* Orphan the channel after releasing the lock */ 03517 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03518 unalloc_sub(p, SUB_THREEWAY); 03519 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 03520 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 03521 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 03522 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 03523 } 03524 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) { 03525 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 03526 } 03527 if (p->subs[SUB_THREEWAY].owner->cdr) { 03528 /* Move CDR from second channel to current one */ 03529 p->subs[SUB_REAL].owner->cdr = 03530 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr); 03531 p->subs[SUB_THREEWAY].owner->cdr = NULL; 03532 } 03533 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) { 03534 /* Move CDR from second channel's bridge to current one */ 03535 p->subs[SUB_REAL].owner->cdr = 03536 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr); 03537 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL; 03538 } 03539 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 03540 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03541 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name); 03542 return -1; 03543 } 03544 /* Three-way is now the REAL */ 03545 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03546 ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock); 03547 unalloc_sub(p, SUB_THREEWAY); 03548 /* Tell the caller not to hangup */ 03549 return 1; 03550 } else { 03551 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 03552 p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name); 03553 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03554 return -1; 03555 } 03556 return 0; 03557 }
static int available | ( | struct zt_pvt * | p, | |
int | channelmatch, | |||
int | groupmatch, | |||
int * | busy, | |||
int * | channelmatched, | |||
int * | groupmatched | |||
) | [inline, static] |
Definition at line 7551 of file chan_zap.c.
References ast_channel::_state, ast_log(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::callwaiting, zt_pvt::channel, zt_pvt::dnd, zt_pvt::group, zt_pvt::guardtime, zt_subchannel::inthreeway, LOG_DEBUG, LOG_WARNING, zt_pvt::oprmode, zt_pvt::outgoing, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_request().
07552 { 07553 int res; 07554 ZT_PARAMS par; 07555 07556 /* First, check group matching */ 07557 if (groupmatch) { 07558 if ((p->group & groupmatch) != groupmatch) 07559 return 0; 07560 *groupmatched = 1; 07561 } 07562 /* Check to see if we have a channel match */ 07563 if (channelmatch != -1) { 07564 if (p->channel != channelmatch) 07565 return 0; 07566 *channelmatched = 1; 07567 } 07568 /* We're at least busy at this point */ 07569 if (busy) { 07570 if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS)) 07571 *busy = 1; 07572 } 07573 /* If do not disturb, definitely not */ 07574 if (p->dnd) 07575 return 0; 07576 /* If guard time, definitely not */ 07577 if (p->guardtime && (time(NULL) < p->guardtime)) 07578 return 0; 07579 07580 /* If no owner definitely available */ 07581 if (!p->owner) { 07582 #ifdef HAVE_PRI 07583 /* Trust PRI */ 07584 if (p->pri) { 07585 if (p->resetting || p->call) 07586 return 0; 07587 else 07588 return 1; 07589 } 07590 #endif 07591 if (!(p->radio || (p->oprmode < 0))) 07592 { 07593 if (!p->sig || (p->sig == SIG_FXSLS)) 07594 return 1; 07595 /* Check hook state */ 07596 if (p->subs[SUB_REAL].zfd > -1) 07597 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 07598 else { 07599 /* Assume not off hook on CVRS */ 07600 res = 0; 07601 par.rxisoffhook = 0; 07602 } 07603 if (res) { 07604 ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel); 07605 } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 07606 /* When "onhook" that means no battery on the line, and thus 07607 it is out of service..., if it's on a TDM card... If it's a channel 07608 bank, there is no telling... */ 07609 if (par.rxbits > -1) 07610 return 1; 07611 if (par.rxisoffhook) 07612 return 1; 07613 else 07614 #ifdef ZAP_CHECK_HOOKSTATE 07615 return 0; 07616 #else 07617 return 1; 07618 #endif 07619 } else if (par.rxisoffhook) { 07620 ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel); 07621 /* Not available when the other end is off hook */ 07622 return 0; 07623 } 07624 } 07625 return 1; 07626 } 07627 07628 /* If it's not an FXO, forget about call wait */ 07629 if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 07630 return 0; 07631 07632 if (!p->callwaiting) { 07633 /* If they don't have call waiting enabled, then for sure they're unavailable at this point */ 07634 return 0; 07635 } 07636 07637 if (p->subs[SUB_CALLWAIT].zfd > -1) { 07638 /* If there is already a call waiting call, then we can't take a second one */ 07639 return 0; 07640 } 07641 07642 if ((p->owner->_state != AST_STATE_UP) && 07643 ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) { 07644 /* If the current call is not up, then don't allow the call */ 07645 return 0; 07646 } 07647 if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) { 07648 /* Can't take a call wait when the three way calling hasn't been merged yet. */ 07649 return 0; 07650 } 07651 /* We're cool */ 07652 return 1; 07653 }
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 10388 of file chan_zap.c.
References ast_log(), ast_strdupa, ast_verbose(), zt_chan_conf::chan, CHAN_PSEUDO, LOG_ERROR, LOG_WARNING, mkintf(), option_verbose, zt_pvt::sig, sig2str, strsep(), and VERBOSE_PREFIX_3.
Referenced by process_zap().
10389 { 10390 char *c, *chan; 10391 int x, start, finish; 10392 struct zt_pvt *tmp; 10393 #ifdef HAVE_PRI 10394 struct zt_pri *pri; 10395 int trunkgroup, y; 10396 #endif 10397 10398 if ((reload == 0) && (conf.chan.sig < 0)) { 10399 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 10400 return -1; 10401 } 10402 10403 c = ast_strdupa(value); 10404 10405 #ifdef HAVE_PRI 10406 pri = NULL; 10407 if (iscrv) { 10408 if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) { 10409 ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno); 10410 return -1; 10411 } 10412 if (trunkgroup < 1) { 10413 ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno); 10414 return -1; 10415 } 10416 c += y; 10417 for (y = 0; y < NUM_SPANS; y++) { 10418 if (pris[y].trunkgroup == trunkgroup) { 10419 pri = pris + y; 10420 break; 10421 } 10422 } 10423 if (!pri) { 10424 ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno); 10425 return -1; 10426 } 10427 } 10428 #endif 10429 10430 while ((chan = strsep(&c, ","))) { 10431 if (sscanf(chan, "%d-%d", &start, &finish) == 2) { 10432 /* Range */ 10433 } else if (sscanf(chan, "%d", &start)) { 10434 /* Just one */ 10435 finish = start; 10436 } else if (!strcasecmp(chan, "pseudo")) { 10437 finish = start = CHAN_PSEUDO; 10438 if (found_pseudo) 10439 *found_pseudo = 1; 10440 } else { 10441 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan); 10442 return -1; 10443 } 10444 if (finish < start) { 10445 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 10446 x = finish; 10447 finish = start; 10448 start = x; 10449 } 10450 10451 for (x = start; x <= finish; x++) { 10452 #ifdef HAVE_PRI 10453 tmp = mkintf(x, conf, pri, reload); 10454 #else 10455 tmp = mkintf(x, conf, NULL, reload); 10456 #endif 10457 10458 if (tmp) { 10459 if (option_verbose > 2) { 10460 #ifdef HAVE_PRI 10461 if (pri) 10462 ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig)); 10463 else 10464 #endif 10465 ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig)); 10466 } 10467 } else { 10468 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n", 10469 (reload == 1) ? "reconfigure" : "register", value); 10470 return -1; 10471 } 10472 } 10473 } 10474 10475 return 0; 10476 }
static int bump_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1581 of file chan_zap.c.
References ast_log(), zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, zt_pvt::txgain, and zt_subchannel::zfd.
Referenced by ss_thread().
01582 { 01583 int res; 01584 01585 /* Bump receive gain by 5.0db */ 01586 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law); 01587 if (res) { 01588 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno)); 01589 return -1; 01590 } 01591 01592 return 0; 01593 }
Definition at line 7655 of file chan_zap.c.
References ast_log(), ast_malloc, ast_mutex_init(), zt_pvt::destroy, destroy_zt_pvt(), iflist, zt_pvt::lock, LOG_ERROR, LOG_WARNING, zt_pvt::next, SUB_REAL, zt_pvt::subs, zt_subchannel::zfd, and zt_open().
Referenced by zt_request().
07656 { 07657 struct zt_pvt *p; 07658 ZT_BUFFERINFO bi; 07659 int res; 07660 07661 if ((p = ast_malloc(sizeof(*p)))) { 07662 memcpy(p, src, sizeof(struct zt_pvt)); 07663 ast_mutex_init(&p->lock); 07664 p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo"); 07665 /* Allocate a zapata structure */ 07666 if (p->subs[SUB_REAL].zfd < 0) { 07667 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 07668 destroy_zt_pvt(&p); 07669 return NULL; 07670 } 07671 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07672 if (!res) { 07673 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07674 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07675 bi.numbufs = numbufs; 07676 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07677 if (res < 0) { 07678 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n"); 07679 } 07680 } else 07681 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n"); 07682 } 07683 p->destroy = 1; 07684 p->next = iflist; 07685 iflist = p; 07686 return p; 07687 }
static int check_for_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3559 of file chan_zap.c.
References ast_log(), ast_verbose(), zt_pvt::channel, zt_pvt::confno, zt_subchannel::curconf, LOG_WARNING, zt_pvt::master, option_verbose, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, and zt_subchannel::zfd.
Referenced by zt_handle_event().
03560 { 03561 ZT_CONFINFO ci; 03562 /* Fine if we already have a master, etc */ 03563 if (p->master || (p->confno > -1)) 03564 return 0; 03565 memset(&ci, 0, sizeof(ci)); 03566 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 03567 ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel); 03568 return 0; 03569 } 03570 /* If we have no master and don't have a confno, then 03571 if we're in a conference, it's probably a MeetMe room or 03572 some such, so don't let us 3-way out! */ 03573 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 03574 if (option_verbose > 2) 03575 ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n"); 03576 return 1; 03577 } 03578 return 0; 03579 }
static int conf_add | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index, | |||
int | slavechannel | |||
) | [static] |
Definition at line 1221 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().
01222 { 01223 /* If the conference already exists, and we're already in it 01224 don't bother doing anything */ 01225 ZT_CONFINFO zi; 01226 01227 memset(&zi, 0, sizeof(zi)); 01228 zi.chan = 0; 01229 01230 if (slavechannel > 0) { 01231 /* If we have only one slave, do a digital mon */ 01232 zi.confmode = ZT_CONF_DIGITALMON; 01233 zi.confno = slavechannel; 01234 } else { 01235 if (!index) { 01236 /* Real-side and pseudo-side both participate in conference */ 01237 zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER | 01238 ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 01239 } else 01240 zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER; 01241 zi.confno = p->confno; 01242 } 01243 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode)) 01244 return 0; 01245 if (c->zfd < 0) 01246 return 0; 01247 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01248 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno); 01249 return -1; 01250 } 01251 if (slavechannel < 1) { 01252 p->confno = zi.confno; 01253 } 01254 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01255 ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01256 return 0; 01257 }
static int conf_del | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index | |||
) | [static] |
Definition at line 1270 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().
01271 { 01272 ZT_CONFINFO zi; 01273 if (/* Can't delete if there's no zfd */ 01274 (c->zfd < 0) || 01275 /* Don't delete from the conference if it's not our conference */ 01276 !isourconf(p, c) 01277 /* Don't delete if we don't think it's conferenced at all (implied) */ 01278 ) return 0; 01279 memset(&zi, 0, sizeof(zi)); 01280 zi.chan = 0; 01281 zi.confno = 0; 01282 zi.confmode = 0; 01283 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01284 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01285 return -1; 01286 } 01287 ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01288 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01289 return 0; 01290 }
Definition at line 2220 of file chan_zap.c.
References destroy_zt_pvt(), iflist, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::prev, SUB_REAL, zt_pvt::subs, zt_subchannel::zfd, and zt_close().
Referenced by zap_destroy_channel_bynum(), zap_restart(), and zt_hangup().
02221 { 02222 int owned = 0; 02223 int i = 0; 02224 02225 if (!now) { 02226 if (cur->owner) { 02227 owned = 1; 02228 } 02229 02230 for (i = 0; i < 3; i++) { 02231 if (cur->subs[i].owner) { 02232 owned = 1; 02233 } 02234 } 02235 if (!owned) { 02236 if (prev) { 02237 prev->next = cur->next; 02238 if (prev->next) 02239 prev->next->prev = prev; 02240 else 02241 ifend = prev; 02242 } else { 02243 iflist = cur->next; 02244 if (iflist) 02245 iflist->prev = NULL; 02246 else 02247 ifend = NULL; 02248 } 02249 if (cur->subs[SUB_REAL].zfd > -1) { 02250 zt_close(cur->subs[SUB_REAL].zfd); 02251 } 02252 destroy_zt_pvt(&cur); 02253 } 02254 } else { 02255 if (prev) { 02256 prev->next = cur->next; 02257 if (prev->next) 02258 prev->next->prev = prev; 02259 else 02260 ifend = prev; 02261 } else { 02262 iflist = cur->next; 02263 if (iflist) 02264 iflist->prev = NULL; 02265 else 02266 ifend = NULL; 02267 } 02268 if (cur->subs[SUB_REAL].zfd > -1) { 02269 zt_close(cur->subs[SUB_REAL].zfd); 02270 } 02271 destroy_zt_pvt(&cur); 02272 } 02273 return 0; 02274 }
static void destroy_zt_pvt | ( | struct zt_pvt ** | pvt | ) | [static] |
Definition at line 2205 of file chan_zap.c.
References ast_mutex_destroy(), ast_smdi_interface_destroy(), ASTOBJ_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().
02206 { 02207 struct zt_pvt *p = *pvt; 02208 /* Remove channel from the list */ 02209 if (p->prev) 02210 p->prev->next = p->next; 02211 if (p->next) 02212 p->next->prev = p->prev; 02213 if (p->use_smdi) 02214 ASTOBJ_UNREF(p->smdi_iface, ast_smdi_interface_destroy); 02215 ast_mutex_destroy(&p->lock); 02216 free(p); 02217 *pvt = NULL; 02218 }
static int digit_to_dtmfindex | ( | char | digit | ) | [static] |
Definition at line 983 of file chan_zap.c.
Referenced by zt_digit_begin().
00984 { 00985 if (isdigit(digit)) 00986 return ZT_TONE_DTMF_BASE + (digit - '0'); 00987 else if (digit >= 'A' && digit <= 'D') 00988 return ZT_TONE_DTMF_A + (digit - 'A'); 00989 else if (digit >= 'a' && digit <= 'd') 00990 return ZT_TONE_DTMF_A + (digit - 'a'); 00991 else if (digit == '*') 00992 return ZT_TONE_DTMF_s; 00993 else if (digit == '#') 00994 return ZT_TONE_DTMF_p; 00995 else 00996 return -1; 00997 }
static void disable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3102 of file chan_zap.c.
References ast_dsp_set_features(), zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_bridge().
03103 { 03104 #ifdef ZT_TONEDETECT 03105 int val; 03106 #endif 03107 03108 p->ignoredtmf = 1; 03109 03110 #ifdef ZT_TONEDETECT 03111 val = 0; 03112 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03113 #endif 03114 if (!p->hardwaredtmf && p->dsp) { 03115 p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT; 03116 ast_dsp_set_features(p->dsp, p->dsp_features); 03117 } 03118 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 6760 of file chan_zap.c.
References ast_app_has_voicemail(), ast_calloc, ast_fdisset(), AST_LAW, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), zt_pvt::channel, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, event2str(), pollfd::events, pollfd::fd, free, handle_init_event(), iflist, last, LOG_DEBUG, LOG_WARNING, zt_pvt::mailbox, MAX_CALLERID_SIZE, zt_pvt::msgstate, zt_pvt::next, zt_pvt::onhooktime, option_debug, zt_subchannel::owner, zt_pvt::owner, poll(), POLLIN, POLLPRI, zt_pvt::radio, pollfd::revents, zt_pvt::sig, SUB_REAL, zt_pvt::subs, vmwi_generate(), zt_subchannel::zfd, and zt_get_event().
06761 { 06762 int count, res, res2, spoint, pollres=0; 06763 struct zt_pvt *i; 06764 struct zt_pvt *last = NULL; 06765 time_t thispass = 0, lastpass = 0; 06766 int found; 06767 char buf[1024]; 06768 struct pollfd *pfds=NULL; 06769 int lastalloc = -1; 06770 /* This thread monitors all the frame relay interfaces which are not yet in use 06771 (and thus do not have a separate thread) indefinitely */ 06772 /* From here on out, we die whenever asked */ 06773 #if 0 06774 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 06775 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 06776 return NULL; 06777 } 06778 ast_log(LOG_DEBUG, "Monitor starting...\n"); 06779 #endif 06780 for (;;) { 06781 /* Lock the interface list */ 06782 ast_mutex_lock(&iflock); 06783 if (!pfds || (lastalloc != ifcount)) { 06784 if (pfds) 06785 free(pfds); 06786 if (ifcount) { 06787 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) { 06788 ast_mutex_unlock(&iflock); 06789 return NULL; 06790 } 06791 } 06792 lastalloc = ifcount; 06793 } 06794 /* Build the stuff we're going to poll on, that is the socket of every 06795 zt_pvt that does not have an associated owner channel */ 06796 count = 0; 06797 i = iflist; 06798 while (i) { 06799 if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) { 06800 if (!i->owner && !i->subs[SUB_REAL].owner) { 06801 /* This needs to be watched, as it lacks an owner */ 06802 pfds[count].fd = i->subs[SUB_REAL].zfd; 06803 pfds[count].events = POLLPRI; 06804 pfds[count].revents = 0; 06805 /* Message waiting or r2 channels also get watched for reading */ 06806 if (i->cidspill) 06807 pfds[count].events |= POLLIN; 06808 count++; 06809 } 06810 } 06811 i = i->next; 06812 } 06813 /* Okay, now that we know what to do, release the interface lock */ 06814 ast_mutex_unlock(&iflock); 06815 06816 pthread_testcancel(); 06817 /* Wait at least a second for something to happen */ 06818 res = poll(pfds, count, 1000); 06819 pthread_testcancel(); 06820 /* Okay, poll has finished. Let's see what happened. */ 06821 if (res < 0) { 06822 if ((errno != EAGAIN) && (errno != EINTR)) 06823 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 06824 continue; 06825 } 06826 /* Alright, lock the interface list again, and let's look and see what has 06827 happened */ 06828 ast_mutex_lock(&iflock); 06829 found = 0; 06830 spoint = 0; 06831 lastpass = thispass; 06832 thispass = time(NULL); 06833 i = iflist; 06834 while (i) { 06835 if (thispass != lastpass) { 06836 if (!found && ((i == last) || ((i == iflist) && !last))) { 06837 last = i; 06838 if (last) { 06839 if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) && 06840 (last->sig & __ZT_SIG_FXO)) { 06841 res = ast_app_has_voicemail(last->mailbox, NULL); 06842 if (last->msgstate != res) { 06843 int x; 06844 ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel); 06845 x = ZT_FLUSH_BOTH; 06846 res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 06847 if (res2) 06848 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel); 06849 if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) { 06850 /* Turn on on hook transfer for 4 seconds */ 06851 x = 4000; 06852 ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x); 06853 last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last)); 06854 last->cidpos = 0; 06855 last->msgstate = res; 06856 last->onhooktime = thispass; 06857 } 06858 found ++; 06859 } 06860 } 06861 last = last->next; 06862 } 06863 } 06864 } 06865 if ((i->subs[SUB_REAL].zfd > -1) && i->sig) { 06866 if (i->radio && !i->owner) 06867 { 06868 res = zt_get_event(i->subs[SUB_REAL].zfd); 06869 if (res) 06870 { 06871 if (option_debug) 06872 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 06873 /* Don't hold iflock while handling init events */ 06874 ast_mutex_unlock(&iflock); 06875 handle_init_event(i, res); 06876 ast_mutex_lock(&iflock); 06877 } 06878 i = i->next; 06879 continue; 06880 } 06881 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint); 06882 if (pollres & POLLIN) { 06883 if (i->owner || i->subs[SUB_REAL].owner) { 06884 #ifdef HAVE_PRI 06885 if (!i->pri) 06886 #endif 06887 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd); 06888 i = i->next; 06889 continue; 06890 } 06891 if (!i->cidspill) { 06892 ast_log(LOG_WARNING, "Whoa.... I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd); 06893 i = i->next; 06894 continue; 06895 } 06896 res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf)); 06897 if (res > 0) { 06898 /* We read some number of bytes. Write an equal amount of data */ 06899 if (res > i->cidlen - i->cidpos) 06900 res = i->cidlen - i->cidpos; 06901 res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res); 06902 if (res2 > 0) { 06903 i->cidpos += res2; 06904 if (i->cidpos >= i->cidlen) { 06905 free(i->cidspill); 06906 i->cidspill = 0; 06907 i->cidpos = 0; 06908 i->cidlen = 0; 06909 } 06910 } else { 06911 ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno)); 06912 i->msgstate = -1; 06913 } 06914 } else { 06915 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 06916 } 06917 if (option_debug) 06918 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 06919 /* Don't hold iflock while handling init events -- race with chlock */ 06920 ast_mutex_unlock(&iflock); 06921 handle_init_event(i, res); 06922 ast_mutex_lock(&iflock); 06923 } 06924 if (pollres & POLLPRI) { 06925 if (i->owner || i->subs[SUB_REAL].owner) { 06926 #ifdef HAVE_PRI 06927 if (!i->pri) 06928 #endif 06929 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd); 06930 i = i->next; 06931 continue; 06932 } 06933 res = zt_get_event(i->subs[SUB_REAL].zfd); 06934 if (option_debug) 06935 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 06936 /* Don't hold iflock while handling init events */ 06937 ast_mutex_unlock(&iflock); 06938 handle_init_event(i, res); 06939 ast_mutex_lock(&iflock); 06940 } 06941 } 06942 i=i->next; 06943 } 06944 ast_mutex_unlock(&iflock); 06945 } 06946 /* Never reached */ 06947 return NULL; 06948 06949 }
static void enable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3120 of file chan_zap.c.
References ast_dsp_set_features(), CHAN_PSEUDO, zt_pvt::channel, zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_bridge().
03121 { 03122 #ifdef ZT_TONEDETECT 03123 int val; 03124 #endif 03125 03126 if (p->channel == CHAN_PSEUDO) 03127 return; 03128 03129 p->ignoredtmf = 0; 03130 03131 #ifdef ZT_TONEDETECT 03132 val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 03133 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03134 #endif 03135 if (!p->hardwaredtmf && p->dsp) { 03136 p->dsp_features |= DSP_FEATURE_DTMF_DETECT; 03137 ast_dsp_set_features(p->dsp, p->dsp_features); 03138 } 03139 }
static char* event2str | ( | int | event | ) | [static] |
Definition at line 1140 of file chan_zap.c.
Referenced by __zt_exception(), do_monitor(), ss_thread(), and zt_handle_event().
01141 { 01142 static char buf[256]; 01143 if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1)) 01144 return events[event]; 01145 sprintf(buf, "Event %d", event); /* safe */ 01146 return buf; 01147 }
static void fill_rxgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1505 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_rxgain().
01506 { 01507 int j; 01508 int k; 01509 float linear_gain = pow(10.0, gain / 20.0); 01510 01511 switch (law) { 01512 case ZT_LAW_ALAW: 01513 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01514 if (gain) { 01515 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01516 if (k > 32767) k = 32767; 01517 if (k < -32767) k = -32767; 01518 g->rxgain[j] = AST_LIN2A(k); 01519 } else { 01520 g->rxgain[j] = j; 01521 } 01522 } 01523 break; 01524 case ZT_LAW_MULAW: 01525 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01526 if (gain) { 01527 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01528 if (k > 32767) k = 32767; 01529 if (k < -32767) k = -32767; 01530 g->rxgain[j] = AST_LIN2MU(k); 01531 } else { 01532 g->rxgain[j] = j; 01533 } 01534 } 01535 break; 01536 } 01537 }
static void fill_txgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1471 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_txgain().
01472 { 01473 int j; 01474 int k; 01475 float linear_gain = pow(10.0, gain / 20.0); 01476 01477 switch (law) { 01478 case ZT_LAW_ALAW: 01479 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01480 if (gain) { 01481 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01482 if (k > 32767) k = 32767; 01483 if (k < -32767) k = -32767; 01484 g->txgain[j] = AST_LIN2A(k); 01485 } else { 01486 g->txgain[j] = j; 01487 } 01488 } 01489 break; 01490 case ZT_LAW_MULAW: 01491 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01492 if (gain) { 01493 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01494 if (k > 32767) k = 32767; 01495 if (k < -32767) k = -32767; 01496 g->txgain[j] = AST_LIN2MU(k); 01497 } else { 01498 g->txgain[j] = j; 01499 } 01500 } 01501 break; 01502 } 01503 }
static struct zt_pvt* find_channel | ( | int | channel | ) | [static, read] |
Definition at line 10144 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().
10145 { 10146 struct zt_pvt *p = iflist; 10147 while (p) { 10148 if (p->channel == channel) { 10149 break; 10150 } 10151 p = p->next; 10152 } 10153 return p; 10154 }
static int get_alarms | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3581 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_WARNING, zt_pvt::span, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
03582 { 03583 int res; 03584 ZT_SPANINFO zi; 03585 memset(&zi, 0, sizeof(zi)); 03586 zi.spanno = p->span; 03587 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi); 03588 if (res < 0) { 03589 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 03590 return 0; 03591 } 03592 return zi.alarms; 03593 }
static int handle_init_event | ( | struct zt_pvt * | i, | |
int | event | |||
) | [static] |
Definition at line 6559 of file chan_zap.c.
References alarm2str(), ast_hangup(), ast_log(), ast_pthread_create, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verbose(), zt_pvt::channel, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::cidspill, EVENT_FLAG_SYSTEM, free, get_alarms(), has_voicemail(), zt_pvt::immediate, zt_pvt::inalarm, LOG_NOTICE, LOG_WARNING, manager_event(), zt_pvt::polarity, POLARITY_REV, zt_pvt::radio, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ss_thread(), SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_2, zap_destroy_channel_bynum(), zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_new(), and zt_set_hook().
Referenced by do_monitor().
06560 { 06561 int res; 06562 pthread_t threadid; 06563 pthread_attr_t attr; 06564 struct ast_channel *chan; 06565 pthread_attr_init(&attr); 06566 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06567 /* Handle an event on a given channel for the monitor thread. */ 06568 switch (event) { 06569 case ZT_EVENT_NONE: 06570 case ZT_EVENT_BITSCHANGED: 06571 break; 06572 case ZT_EVENT_WINKFLASH: 06573 case ZT_EVENT_RINGOFFHOOK: 06574 if (i->inalarm) break; 06575 if (i->radio) break; 06576 /* Got a ring/answer. What kind of channel are we? */ 06577 switch (i->sig) { 06578 case SIG_FXOLS: 06579 case SIG_FXOGS: 06580 case SIG_FXOKS: 06581 res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06582 if (res && (errno == EBUSY)) 06583 break; 06584 if (i->cidspill) { 06585 /* Cancel VMWI spill */ 06586 free(i->cidspill); 06587 i->cidspill = NULL; 06588 } 06589 if (i->immediate) { 06590 zt_enable_ec(i); 06591 /* The channel is immediately up. Start right away */ 06592 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 06593 chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0); 06594 if (!chan) { 06595 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 06596 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06597 if (res < 0) 06598 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06599 } 06600 } else { 06601 /* Check for callerid, digits, etc */ 06602 chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0); 06603 if (chan) { 06604 if (has_voicemail(i)) 06605 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 06606 else 06607 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 06608 if (res < 0) 06609 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 06610 if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06611 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06612 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06613 if (res < 0) 06614 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06615 ast_hangup(chan); 06616 } 06617 } else 06618 ast_log(LOG_WARNING, "Unable to create channel\n"); 06619 } 06620 break; 06621 case SIG_FXSLS: 06622 case SIG_FXSGS: 06623 case SIG_FXSKS: 06624 i->ringt = i->ringt_base; 06625 /* Fall through */ 06626 case SIG_EMWINK: 06627 case SIG_FEATD: 06628 case SIG_FEATDMF: 06629 case SIG_FEATDMF_TA: 06630 case SIG_E911: 06631 case SIG_FGC_CAMA: 06632 case SIG_FGC_CAMAMF: 06633 case SIG_FEATB: 06634 case SIG_EM: 06635 case SIG_EM_E1: 06636 case SIG_SFWINK: 06637 case SIG_SF_FEATD: 06638 case SIG_SF_FEATDMF: 06639 case SIG_SF_FEATB: 06640 case SIG_SF: 06641 /* Check for callerid, digits, etc */ 06642 chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0); 06643 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06644 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06645 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06646 if (res < 0) 06647 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06648 ast_hangup(chan); 06649 } else if (!chan) { 06650 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 06651 } 06652 break; 06653 default: 06654 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06655 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06656 if (res < 0) 06657 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06658 return -1; 06659 } 06660 break; 06661 case ZT_EVENT_NOALARM: 06662 i->inalarm = 0; 06663 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); 06664 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 06665 "Channel: %d\r\n", i->channel); 06666 break; 06667 case ZT_EVENT_ALARM: 06668 i->inalarm = 1; 06669 res = get_alarms(i); 06670 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res)); 06671 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 06672 "Alarm: %s\r\n" 06673 "Channel: %d\r\n", 06674 alarm2str(res), i->channel); 06675 /* fall thru intentionally */ 06676 case ZT_EVENT_ONHOOK: 06677 if (i->radio) 06678 break; 06679 /* Back on hook. Hang up. */ 06680 switch (i->sig) { 06681 case SIG_FXOLS: 06682 case SIG_FXOGS: 06683 case SIG_FEATD: 06684 case SIG_FEATDMF: 06685 case SIG_FEATDMF_TA: 06686 case SIG_E911: 06687 case SIG_FGC_CAMA: 06688 case SIG_FGC_CAMAMF: 06689 case SIG_FEATB: 06690 case SIG_EM: 06691 case SIG_EM_E1: 06692 case SIG_EMWINK: 06693 case SIG_SF_FEATD: 06694 case SIG_SF_FEATDMF: 06695 case SIG_SF_FEATB: 06696 case SIG_SF: 06697 case SIG_SFWINK: 06698 case SIG_FXSLS: 06699 case SIG_FXSGS: 06700 case SIG_FXSKS: 06701 case SIG_GR303FXSKS: 06702 zt_disable_ec(i); 06703 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06704 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06705 break; 06706 case SIG_GR303FXOKS: 06707 case SIG_FXOKS: 06708 zt_disable_ec(i); 06709 /* Diddle the battery for the zhone */ 06710 #ifdef ZHONE_HACK 06711 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06712 usleep(1); 06713 #endif 06714 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06715 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06716 break; 06717 case SIG_PRI: 06718 zt_disable_ec(i); 06719 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06720 break; 06721 default: 06722 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06723 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06724 return -1; 06725 } 06726 break; 06727 case ZT_EVENT_POLARITY: 06728 switch (i->sig) { 06729 case SIG_FXSLS: 06730 case SIG_FXSKS: 06731 case SIG_FXSGS: 06732 if (i->cid_start == CID_START_POLARITY) { 06733 i->polarity = POLARITY_REV; 06734 ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity " 06735 "CID detection on channel %d\n", 06736 i->channel); 06737 chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0); 06738 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06739 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06740 } 06741 } 06742 break; 06743 default: 06744 ast_log(LOG_WARNING, "handle_init_event detected " 06745 "polarity reversal on non-FXO (SIG_FXS) " 06746 "interface %d\n", i->channel); 06747 } 06748 break; 06749 case ZT_EVENT_REMOVED: /* destroy channel */ 06750 ast_log(LOG_NOTICE, 06751 "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 06752 i->channel); 06753 zap_destroy_channel_bynum(i->channel); 06754 break; 06755 } 06756 pthread_attr_destroy(&attr); 06757 return 0; 06758 }
static int handle_zap_show_cadences | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 9988 of file chan_zap.c.
References ast_cli(), COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, and term_color().
09989 { 09990 int i, j; 09991 for (i = 0; i < num_cadence; i++) { 09992 char output[1024]; 09993 char tmp[16], tmp2[64]; 09994 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 09995 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 09996 09997 for (j = 0; j < 16; j++) { 09998 if (cadences[i].ringcadence[j] == 0) 09999 break; 10000 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 10001 if (cidrings[i] * 2 - 1 == j) 10002 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 10003 else 10004 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 10005 if (j != 0) 10006 strncat(output, ",", sizeof(output) - strlen(output) - 1); 10007 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 10008 } 10009 ast_cli(fd,"%s\n",output); 10010 } 10011 return 0; 10012 }
static int has_voicemail | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1702 of file chan_zap.c.
References ast_app_has_voicemail(), and zt_pvt::mailbox.
01703 { 01704 01705 return ast_app_has_voicemail(p->mailbox, NULL); 01706 }
static int isourconf | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c | |||
) | [static] |
Definition at line 1259 of file chan_zap.c.
References zt_pvt::channel, zt_pvt::confno, and zt_subchannel::curconf.
Referenced by conf_del().
01260 { 01261 /* If they're listening to our channel, they're ours */ 01262 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON)) 01263 return 1; 01264 /* If they're a talker on our (allocated) conference, they're ours */ 01265 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER)) 01266 return 1; 01267 return 0; 01268 }
Definition at line 1292 of file chan_zap.c.
References zt_subchannel::inthreeway, zt_pvt::law, MAX_SLAVES, zt_pvt::slaves, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by update_conf().
01293 { 01294 int x; 01295 int useslavenative; 01296 struct zt_pvt *slave = NULL; 01297 /* Start out optimistic */ 01298 useslavenative = 1; 01299 /* Update conference state in a stateless fashion */ 01300 for (x = 0; x < 3; x++) { 01301 /* Any three-way calling makes slave native mode *definitely* out 01302 of the question */ 01303 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) 01304 useslavenative = 0; 01305 } 01306 /* If we don't have any 3-way calls, check to see if we have 01307 precisely one slave */ 01308 if (useslavenative) { 01309 for (x = 0; x < MAX_SLAVES; x++) { 01310 if (p->slaves[x]) { 01311 if (slave) { 01312 /* Whoops already have a slave! No 01313 slave native and stop right away */ 01314 slave = NULL; 01315 useslavenative = 0; 01316 break; 01317 } else { 01318 /* We have one slave so far */ 01319 slave = p->slaves[x]; 01320 } 01321 } 01322 } 01323 } 01324 /* If no slave, slave native definitely out */ 01325 if (!slave) 01326 useslavenative = 0; 01327 else if (slave->law != p->law) { 01328 useslavenative = 0; 01329 slave = NULL; 01330 } 01331 if (out) 01332 *out = slave; 01333 return useslavenative; 01334 }
static int load_module | ( | void | ) | [static] |
Definition at line 11281 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, and setup_zap().
11282 { 11283 int res; 11284 11285 #ifdef HAVE_PRI 11286 int y,i; 11287 memset(pris, 0, sizeof(pris)); 11288 for (y = 0; y < NUM_SPANS; y++) { 11289 ast_mutex_init(&pris[y].lock); 11290 pris[y].offset = -1; 11291 pris[y].master = AST_PTHREADT_NULL; 11292 for (i = 0; i < NUM_DCHANS; i++) 11293 pris[y].fds[i] = -1; 11294 } 11295 pri_set_error(zt_pri_error); 11296 pri_set_message(zt_pri_message); 11297 ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec, 11298 zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip); 11299 #endif 11300 res = setup_zap(0); 11301 /* Make sure we can register our Zap channel type */ 11302 if (res) 11303 return AST_MODULE_LOAD_DECLINE; 11304 if (ast_channel_register(&zap_tech)) { 11305 ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n"); 11306 __unload_module(); 11307 return -1; 11308 } 11309 #ifdef HAVE_PRI 11310 ast_string_field_init(&inuse, 16); 11311 ast_string_field_set(&inuse, name, "GR-303InUse"); 11312 ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 11313 #endif 11314 ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 11315 11316 memset(round_robin, 0, sizeof(round_robin)); 11317 ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" ); 11318 ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" ); 11319 ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" ); 11320 ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" ); 11321 ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" ); 11322 ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels"); 11323 ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)"); 11324 11325 return res; 11326 }
static struct zt_pvt* mkintf | ( | int | channel, | |
struct zt_chan_conf | conf, | |||
struct zt_pri * | pri, | |||
int | reloading | |||
) | [static, read] |
Definition at line 7096 of file chan_zap.c.
References zt_pvt::accountcode, zt_pvt::adsi, zt_pvt::amaflags, zt_pvt::answeronpolarityswitch, ast_calloc, ast_dsp_digitmode(), ast_log(), ast_mutex_init(), ast_smdi_interface_find(), ast_strlen_zero(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::callgroup, zt_pvt::callprogress, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::callwaitingcallerid, zt_pvt::cancallforward, zt_pvt::canpark, zt_chan_conf::chan, CHAN_PSEUDO, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, CID_SIG_SMDI, zt_pvt::cid_signalling, zt_pvt::cid_start, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, zt_pvt::defcontext, zt_pvt::destroy, destroy_zt_pvt(), drings, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echotraining, zt_pvt::firstradio, zt_pvt::group, zt_pvt::hanguponpolarityswitch, zt_pvt::hidecallerid, iflist, zt_pvt::immediate, zt_pvt::inalarm, zt_pvt::language, zt_pvt::law, zt_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, zt_pvt::mailbox, MAX_CHANNELS, zt_pvt::mohinterpret, zt_pvt::mohsuggest, zt_pvt::msgstate, zt_pvt::next, zt_pvt::onhooktime, zt_pvt::outsigmod, zt_pvt::permcallwaiting, zt_pvt::permhidecallerid, zt_pvt::pickupgroup, zt_pvt::polarityonanswerdelay, zt_pvt::prev, zt_pvt::priexclusive, zt_pvt::priindication_oob, zt_pvt::propconfno, zt_pvt::pulse, zt_pvt::radio, zt_pvt::restrictcid, zt_pvt::ringt_base, zt_pvt::rxgain, zt_pvt::sendcalleridafter, set_actual_gain(), zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::smdi_iface, zt_chan_conf::smdi_port, zt_pvt::span, zt_pvt::stripmsd, SUB_REAL, zt_pvt::subs, zt_pvt::threewaycalling, zt_chan_conf::timing, zt_pvt::tonezone, zt_pvt::transfer, zt_pvt::transfertobusy, zt_pvt::txgain, update_conf(), zt_pvt::use_callerid, zt_pvt::use_callingpres, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_open(), and zt_set_hook().
Referenced by build_channels(), and process_zap().
07097 { 07098 /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */ 07099 struct zt_pvt *tmp = NULL, *tmp2, *prev = NULL; 07100 char fn[80]; 07101 #if 1 07102 struct zt_bufferinfo bi; 07103 #endif 07104 struct zt_spaninfo si; 07105 int res; 07106 int span=0; 07107 int here = 0; 07108 int x; 07109 struct zt_pvt **wlist; 07110 struct zt_pvt **wend; 07111 ZT_PARAMS p; 07112 07113 wlist = &iflist; 07114 wend = &ifend; 07115 07116 #ifdef HAVE_PRI 07117 if (pri) { 07118 wlist = &pri->crvs; 07119 wend = &pri->crvend; 07120 } 07121 #endif 07122 07123 tmp2 = *wlist; 07124 prev = NULL; 07125 07126 while (tmp2) { 07127 if (!tmp2->destroy) { 07128 if (tmp2->channel == channel) { 07129 tmp = tmp2; 07130 here = 1; 07131 break; 07132 } 07133 if (tmp2->channel > channel) { 07134 break; 07135 } 07136 } 07137 prev = tmp2; 07138 tmp2 = tmp2->next; 07139 } 07140 07141 if (!here && !reloading) { 07142 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 07143 destroy_zt_pvt(&tmp); 07144 return NULL; 07145 } 07146 ast_mutex_init(&tmp->lock); 07147 ifcount++; 07148 for (x = 0; x < 3; x++) 07149 tmp->subs[x].zfd = -1; 07150 tmp->channel = channel; 07151 } 07152 07153 if (tmp) { 07154 if (!here) { 07155 if ((channel != CHAN_PSEUDO) && !pri) { 07156 snprintf(fn, sizeof(fn), "%d", channel); 07157 /* Open non-blocking */ 07158 if (!here) 07159 tmp->subs[SUB_REAL].zfd = zt_open(fn); 07160 /* Allocate a zapata structure */ 07161 if (tmp->subs[SUB_REAL].zfd < 0) { 07162 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); 07163 destroy_zt_pvt(&tmp); 07164 return NULL; 07165 } 07166 memset(&p, 0, sizeof(p)); 07167 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07168 if (res < 0) { 07169 ast_log(LOG_ERROR, "Unable to get parameters\n"); 07170 destroy_zt_pvt(&tmp); 07171 return NULL; 07172 } 07173 if (p.sigtype != (conf.chan.sig & 0x3ffff)) { 07174 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)); 07175 destroy_zt_pvt(&tmp); 07176 return NULL; 07177 } 07178 tmp->law = p.curlaw; 07179 tmp->span = p.spanno; 07180 span = p.spanno - 1; 07181 } else { 07182 if (channel == CHAN_PSEUDO) 07183 conf.chan.sig = 0; 07184 else if ((conf.chan.sig != SIG_FXOKS) && (conf.chan.sig != SIG_FXSKS)) { 07185 ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n"); 07186 return NULL; 07187 } 07188 } 07189 #ifdef HAVE_PRI 07190 if ((conf.chan.sig == SIG_PRI) || (conf.chan.sig == SIG_GR303FXOKS) || (conf.chan.sig == SIG_GR303FXSKS)) { 07191 int offset; 07192 int myswitchtype; 07193 int matchesdchan; 07194 int x,y; 07195 offset = 0; 07196 if ((conf.chan.sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) { 07197 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 07198 destroy_zt_pvt(&tmp); 07199 return NULL; 07200 } 07201 if (span >= NUM_SPANS) { 07202 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 07203 destroy_zt_pvt(&tmp); 07204 return NULL; 07205 } else { 07206 si.spanno = 0; 07207 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07208 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07209 destroy_zt_pvt(&tmp); 07210 return NULL; 07211 } 07212 /* Store the logical span first based upon the real span */ 07213 tmp->logicalspan = pris[span].prilogicalspan; 07214 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 07215 if (span < 0) { 07216 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 07217 destroy_zt_pvt(&tmp); 07218 return NULL; 07219 } 07220 if (conf.chan.sig == SIG_PRI) 07221 myswitchtype = conf.pri.switchtype; 07222 else 07223 myswitchtype = PRI_SWITCH_GR303_TMC; 07224 /* Make sure this isn't a d-channel */ 07225 matchesdchan=0; 07226 for (x = 0; x < NUM_SPANS; x++) { 07227 for (y = 0; y < NUM_DCHANS; y++) { 07228 if (pris[x].dchannels[y] == tmp->channel) { 07229 matchesdchan = 1; 07230 break; 07231 } 07232 } 07233 } 07234 offset = p.chanpos; 07235 if (!matchesdchan) { 07236 if (pris[span].nodetype && (pris[span].nodetype != conf.pri.nodetype)) { 07237 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype)); 07238 destroy_zt_pvt(&tmp); 07239 return NULL; 07240 } 07241 if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) { 07242 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype)); 07243 destroy_zt_pvt(&tmp); 07244 return NULL; 07245 } 07246 if ((pris[span].dialplan) && (pris[span].dialplan != conf.pri.dialplan)) { 07247 ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan)); 07248 destroy_zt_pvt(&tmp); 07249 return NULL; 07250 } 07251 if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf.pri.idledial)) { 07252 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf.pri.idledial); 07253 destroy_zt_pvt(&tmp); 07254 return NULL; 07255 } 07256 if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf.pri.idleext)) { 07257 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf.pri.idleext); 07258 destroy_zt_pvt(&tmp); 07259 return NULL; 07260 } 07261 if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) { 07262 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused); 07263 destroy_zt_pvt(&tmp); 07264 return NULL; 07265 } 07266 if (pris[span].minidle && (pris[span].minidle != conf.pri.minidle)) { 07267 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf.pri.minidle); 07268 destroy_zt_pvt(&tmp); 07269 return NULL; 07270 } 07271 if (pris[span].numchans >= MAX_CHANNELS) { 07272 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 07273 pris[span].trunkgroup); 07274 destroy_zt_pvt(&tmp); 07275 return NULL; 07276 } 07277 pris[span].nodetype = conf.pri.nodetype; 07278 pris[span].switchtype = myswitchtype; 07279 pris[span].nsf = conf.pri.nsf; 07280 pris[span].dialplan = conf.pri.dialplan; 07281 pris[span].localdialplan = conf.pri.localdialplan; 07282 pris[span].pvts[pris[span].numchans++] = tmp; 07283 pris[span].minunused = conf.pri.minunused; 07284 pris[span].minidle = conf.pri.minidle; 07285 pris[span].overlapdial = conf.pri.overlapdial; 07286 pris[span].facilityenable = conf.pri.facilityenable; 07287 ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial)); 07288 ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext)); 07289 ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix)); 07290 ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix)); 07291 ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix)); 07292 ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix)); 07293 ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix)); 07294 pris[span].resetinterval = conf.pri.resetinterval; 07295 07296 tmp->pri = &pris[span]; 07297 tmp->prioffset = offset; 07298 tmp->call = NULL; 07299 } else { 07300 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset); 07301 destroy_zt_pvt(&tmp); 07302 return NULL; 07303 } 07304 } 07305 } else { 07306 tmp->prioffset = 0; 07307 } 07308 #endif 07309 } else { 07310 conf.chan.sig = tmp->sig; 07311 conf.chan.radio = tmp->radio; 07312 memset(&p, 0, sizeof(p)); 07313 if (tmp->subs[SUB_REAL].zfd > -1) 07314 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07315 } 07316 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 07317 if ((conf.chan.sig == SIG_FXSKS) || (conf.chan.sig == SIG_FXSLS) || 07318 (conf.chan.sig == SIG_EM) || (conf.chan.sig == SIG_EM_E1) || (conf.chan.sig == SIG_EMWINK) || 07319 (conf.chan.sig == SIG_FEATD) || (conf.chan.sig == SIG_FEATDMF) || (conf.chan.sig == SIG_FEATDMF_TA) || 07320 (conf.chan.sig == SIG_FEATB) || (conf.chan.sig == SIG_E911) || 07321 (conf.chan.sig == SIG_SF) || (conf.chan.sig == SIG_SFWINK) || (conf.chan.sig == SIG_FGC_CAMA) || (conf.chan.sig == SIG_FGC_CAMAMF) || 07322 (conf.chan.sig == SIG_SF_FEATD) || (conf.chan.sig == SIG_SF_FEATDMF) || 07323 (conf.chan.sig == SIG_SF_FEATB)) { 07324 p.starttime = 250; 07325 } 07326 if (conf.chan.radio) { 07327 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 07328 p.channo = channel; 07329 p.rxwinktime = 1; 07330 p.rxflashtime = 1; 07331 p.starttime = 1; 07332 p.debouncetime = 5; 07333 } 07334 if (!conf.chan.radio) { 07335 p.channo = channel; 07336 /* Override timing settings based on config file */ 07337 if (conf.timing.prewinktime >= 0) 07338 p.prewinktime = conf.timing.prewinktime; 07339 if (conf.timing.preflashtime >= 0) 07340 p.preflashtime = conf.timing.preflashtime; 07341 if (conf.timing.winktime >= 0) 07342 p.winktime = conf.timing.winktime; 07343 if (conf.timing.flashtime >= 0) 07344 p.flashtime = conf.timing.flashtime; 07345 if (conf.timing.starttime >= 0) 07346 p.starttime = conf.timing.starttime; 07347 if (conf.timing.rxwinktime >= 0) 07348 p.rxwinktime = conf.timing.rxwinktime; 07349 if (conf.timing.rxflashtime >= 0) 07350 p.rxflashtime = conf.timing.rxflashtime; 07351 if (conf.timing.debouncetime >= 0) 07352 p.debouncetime = conf.timing.debouncetime; 07353 } 07354 07355 /* dont set parms on a pseudo-channel (or CRV) */ 07356 if (tmp->subs[SUB_REAL].zfd >= 0) 07357 { 07358 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p); 07359 if (res < 0) { 07360 ast_log(LOG_ERROR, "Unable to set parameters\n"); 07361 destroy_zt_pvt(&tmp); 07362 return NULL; 07363 } 07364 } 07365 #if 1 07366 if (!here && (tmp->subs[SUB_REAL].zfd > -1)) { 07367 memset(&bi, 0, sizeof(bi)); 07368 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07369 if (!res) { 07370 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07371 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07372 bi.numbufs = numbufs; 07373 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07374 if (res < 0) { 07375 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel); 07376 } 07377 } else 07378 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel); 07379 } 07380 #endif 07381 tmp->immediate = conf.chan.immediate; 07382 tmp->transfertobusy = conf.chan.transfertobusy; 07383 tmp->sig = conf.chan.sig; 07384 tmp->outsigmod = conf.chan.outsigmod; 07385 tmp->radio = conf.chan.radio; 07386 tmp->ringt_base = ringt_base; 07387 tmp->firstradio = 0; 07388 if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS)) 07389 tmp->permcallwaiting = conf.chan.callwaiting; 07390 else 07391 tmp->permcallwaiting = 0; 07392 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 07393 tmp->destroy = 0; 07394 tmp->drings = drings; 07395 tmp->usedistinctiveringdetection = conf.chan.usedistinctiveringdetection; 07396 tmp->callwaitingcallerid = conf.chan.callwaitingcallerid; 07397 tmp->threewaycalling = conf.chan.threewaycalling; 07398 tmp->adsi = conf.chan.adsi; 07399 tmp->use_smdi = conf.chan.use_smdi; 07400 tmp->permhidecallerid = conf.chan.hidecallerid; 07401 tmp->callreturn = conf.chan.callreturn; 07402 tmp->echocancel = conf.chan.echocancel; 07403 tmp->echotraining = conf.chan.echotraining; 07404 tmp->pulse = conf.chan.pulse; 07405 tmp->echocanbridged = conf.chan.echocanbridged; 07406 tmp->busydetect = conf.chan.busydetect; 07407 tmp->busycount = conf.chan.busycount; 07408 tmp->busy_tonelength = conf.chan.busy_tonelength; 07409 tmp->busy_quietlength = conf.chan.busy_quietlength; 07410 tmp->callprogress = conf.chan.callprogress; 07411 tmp->cancallforward = conf.chan.cancallforward; 07412 tmp->dtmfrelax = conf.chan.dtmfrelax; 07413 tmp->callwaiting = tmp->permcallwaiting; 07414 tmp->hidecallerid = tmp->permhidecallerid; 07415 tmp->channel = channel; 07416 tmp->stripmsd = conf.chan.stripmsd; 07417 tmp->use_callerid = conf.chan.use_callerid; 07418 tmp->cid_signalling = conf.chan.cid_signalling; 07419 tmp->cid_start = conf.chan.cid_start; 07420 tmp->zaptrcallerid = conf.chan.zaptrcallerid; 07421 tmp->restrictcid = conf.chan.restrictcid; 07422 tmp->use_callingpres = conf.chan.use_callingpres; 07423 tmp->priindication_oob = conf.chan.priindication_oob; 07424 tmp->priexclusive = conf.chan.priexclusive; 07425 if (tmp->usedistinctiveringdetection) { 07426 if (!tmp->use_callerid) { 07427 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 07428 tmp->use_callerid = 1; 07429 } 07430 } 07431 07432 if (tmp->cid_signalling == CID_SIG_SMDI) { 07433 if (!tmp->use_smdi) { 07434 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n"); 07435 tmp->use_smdi = 1; 07436 } 07437 } 07438 if (tmp->use_smdi) { 07439 tmp->smdi_iface = ast_smdi_interface_find(conf.smdi_port); 07440 if (!(tmp->smdi_iface)) { 07441 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n"); 07442 tmp->use_smdi = 0; 07443 } 07444 } 07445 07446 ast_copy_string(tmp->accountcode, conf.chan.accountcode, sizeof(tmp->accountcode)); 07447 tmp->amaflags = conf.chan.amaflags; 07448 if (!here) { 07449 tmp->confno = -1; 07450 tmp->propconfno = -1; 07451 } 07452 tmp->canpark = conf.chan.canpark; 07453 tmp->transfer = conf.chan.transfer; 07454 ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext)); 07455 ast_copy_string(tmp->language, conf.chan.language, sizeof(tmp->language)); 07456 ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret)); 07457 ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest)); 07458 ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context)); 07459 ast_copy_string(tmp->cid_num, conf.chan.cid_num, sizeof(tmp->cid_num)); 07460 tmp->cid_ton = 0; 07461 ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name)); 07462 ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox)); 07463 tmp->msgstate = -1; 07464 tmp->group = conf.chan.group; 07465 tmp->callgroup = conf.chan.callgroup; 07466 tmp->pickupgroup= conf.chan.pickupgroup; 07467 tmp->rxgain = conf.chan.rxgain; 07468 tmp->txgain = conf.chan.txgain; 07469 tmp->tonezone = conf.chan.tonezone; 07470 tmp->onhooktime = time(NULL); 07471 if (tmp->subs[SUB_REAL].zfd > -1) { 07472 set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law); 07473 if (tmp->dsp) 07474 ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 07475 update_conf(tmp); 07476 if (!here) { 07477 if (conf.chan.sig != SIG_PRI) 07478 /* Hang it up to be sure it's good */ 07479 zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK); 07480 } 07481 ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone); 07482 #ifdef HAVE_PRI 07483 /* the dchannel is down so put the channel in alarm */ 07484 if (tmp->pri && !pri_is_up(tmp->pri)) 07485 tmp->inalarm = 1; 07486 else 07487 tmp->inalarm = 0; 07488 #endif 07489 memset(&si, 0, sizeof(si)); 07490 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07491 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07492 destroy_zt_pvt(&tmp); 07493 return NULL; 07494 } 07495 if (si.alarms) tmp->inalarm = 1; 07496 } 07497 07498 tmp->polarityonanswerdelay = conf.chan.polarityonanswerdelay; 07499 tmp->answeronpolarityswitch = conf.chan.answeronpolarityswitch; 07500 tmp->hanguponpolarityswitch = conf.chan.hanguponpolarityswitch; 07501 tmp->sendcalleridafter = conf.chan.sendcalleridafter; 07502 07503 } 07504 if (tmp && !here) { 07505 /* nothing on the iflist */ 07506 if (!*wlist) { 07507 *wlist = tmp; 07508 tmp->prev = NULL; 07509 tmp->next = NULL; 07510 *wend = tmp; 07511 } else { 07512 /* at least one member on the iflist */ 07513 struct zt_pvt *working = *wlist; 07514 07515 /* check if we maybe have to put it on the begining */ 07516 if (working->channel > tmp->channel) { 07517 tmp->next = *wlist; 07518 tmp->prev = NULL; 07519 (*wlist)->prev = tmp; 07520 *wlist = tmp; 07521 } else { 07522 /* go through all the members and put the member in the right place */ 07523 while (working) { 07524 /* in the middle */ 07525 if (working->next) { 07526 if (working->channel < tmp->channel && working->next->channel > tmp->channel) { 07527 tmp->next = working->next; 07528 tmp->prev = working; 07529 working->next->prev = tmp; 07530 working->next = tmp; 07531 break; 07532 } 07533 } else { 07534 /* the last */ 07535 if (working->channel < tmp->channel) { 07536 working->next = tmp; 07537 tmp->next = NULL; 07538 tmp->prev = working; 07539 *wend = tmp; 07540 break; 07541 } 07542 } 07543 working = working->next; 07544 } 07545 } 07546 } 07547 } 07548 return tmp; 07549 }
static int my_getsigstr | ( | struct ast_channel * | chan, | |
char * | str, | |||
const char * | term, | |||
int | ms | |||
) | [static] |
Definition at line 5363 of file chan_zap.c.
References ast_waitfordigit().
Referenced by ss_thread().
05364 { 05365 char c; 05366 05367 *str = 0; /* start with empty output buffer */ 05368 for (;;) 05369 { 05370 /* Wait for the first digit (up to specified ms). */ 05371 c = ast_waitfordigit(chan, ms); 05372 /* if timeout, hangup or error, return as such */ 05373 if (c < 1) 05374 return c; 05375 *str++ = c; 05376 *str = 0; 05377 if (strchr(term, c)) 05378 return 1; 05379 } 05380 }
static int my_zt_write | ( | struct zt_pvt * | p, | |
unsigned char * | buf, | |||
int | len, | |||
int | index, | |||
int | linear | |||
) | [static] |
Definition at line 4890 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_DEBUG, option_debug, READ_SIZE, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_write().
04891 { 04892 int sent=0; 04893 int size; 04894 int res; 04895 int fd; 04896 fd = p->subs[index].zfd; 04897 while (len) { 04898 size = len; 04899 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 04900 size = (linear ? READ_SIZE * 2 : READ_SIZE); 04901 res = write(fd, buf, size); 04902 if (res != size) { 04903 if (option_debug) 04904 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 04905 return sent; 04906 } 04907 len -= size; 04908 buf += size; 04909 } 04910 return sent; 04911 }
static int process_zap | ( | struct zt_chan_conf * | confp, | |
struct ast_variable * | v, | |||
int | reload, | |||
int | skipchannels | |||
) | [static] |
Definition at line 10481 of file chan_zap.c.
References zt_pvt::accountcode, zt_pvt::adsi, zt_pvt::amaflags, zt_pvt::answeronpolarityswitch, ast_callerid_split(), ast_cdr_amaflags2int(), ast_get_group(), ast_jb_read_conf(), ast_log(), ast_strlen_zero(), ast_true(), ast_verbose(), build_channels(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::callgroup, zt_pvt::callprogress, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::callwaitingcallerid, zt_pvt::cancallforward, zt_pvt::canpark, zt_chan_conf::chan, CHAN_PSEUDO, zt_pvt::cid_name, zt_pvt::cid_num, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, CID_START_RING, zt_pvt::context, ringContextData::contextData, drings, DSP_DIGITMODE_RELAXDTMF, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echotraining, global_jbconf, zt_pvt::group, zt_pvt::hanguponpolarityswitch, HAVE_PRI, zt_pvt::hidecallerid, zt_pvt::hidecalleridname, zt_pvt::immediate, zt_pvt::language, ast_variable::lineno, LOG_ERROR, LOG_WARNING, zt_pvt::mailbox, MAX_CHANLIST_LEN, mkintf(), zt_pvt::mohinterpret, zt_pvt::mohsuggest, ast_variable::name, ast_variable::next, NUM_CADENCE_MAX, option_verbose, zt_pvt::outsigmod, zt_pvt::pickupgroup, zt_pvt::polarityonanswerdelay, zt_pvt::priexclusive, zt_pvt::priindication_oob, zt_pvt::pulse, zt_pvt::radio, READ_SIZE, zt_pvt::restrictcid, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::rxgain, zt_pvt::sendcalleridafter, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SFWINK, zt_chan_conf::smdi_port, zt_pvt::stripmsd, strsep(), zt_pvt::threewaycalling, zt_chan_conf::timing, zt_pvt::tonezone, zt_pvt::transfer, zt_pvt::transfertobusy, zt_pvt::txgain, zt_pvt::use_callerid, zt_pvt::use_callingpres, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, ast_variable::value, VERBOSE_PREFIX_3, and zt_pvt::zaptrcallerid.
Referenced by setup_zap().
10482 { 10483 struct zt_pvt *tmp; 10484 char *ringc; /* temporary string for parsing the dring number. */ 10485 int y; 10486 int found_pseudo = 0; 10487 char zapchan[MAX_CHANLIST_LEN] = {}; 10488 10489 for (; v; v = v->next) { 10490 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 10491 continue; 10492 10493 /* Create the interface list */ 10494 if (!strcasecmp(v->name, "channel") 10495 #ifdef HAVE_PRI 10496 || !strcasecmp(v->name, "crv") 10497 #endif 10498 ) { 10499 int iscrv; 10500 if (skipchannels) 10501 continue; 10502 iscrv = !strcasecmp(v->name, "crv"); 10503 if (build_channels(*confp, iscrv, v->value, reload, v->lineno, &found_pseudo)) 10504 return -1; 10505 } else if (!strcasecmp(v->name, "zapchan")) { 10506 ast_copy_string(zapchan, v->value, sizeof(zapchan)); 10507 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 10508 if (ast_true(v->value)) 10509 confp->chan.usedistinctiveringdetection = 1; 10510 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) { 10511 if (ast_true(v->value)) 10512 distinctiveringaftercid = 1; 10513 } else if (!strcasecmp(v->name, "dring1context")) { 10514 ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData)); 10515 } else if (!strcasecmp(v->name, "dring2context")) { 10516 ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData)); 10517 } else if (!strcasecmp(v->name, "dring3context")) { 10518 ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData)); 10519 } else if (!strcasecmp(v->name, "dring1")) { 10520 ringc = v->value; 10521 sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]); 10522 } else if (!strcasecmp(v->name, "dring2")) { 10523 ringc = v->value; 10524 sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]); 10525 } else if (!strcasecmp(v->name, "dring3")) { 10526 ringc = v->value; 10527 sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]); 10528 } else if (!strcasecmp(v->name, "usecallerid")) { 10529 confp->chan.use_callerid = ast_true(v->value); 10530 } else if (!strcasecmp(v->name, "cidsignalling")) { 10531 if (!strcasecmp(v->value, "bell")) 10532 confp->chan.cid_signalling = CID_SIG_BELL; 10533 else if (!strcasecmp(v->value, "v23")) 10534 confp->chan.cid_signalling = CID_SIG_V23; 10535 else if (!strcasecmp(v->value, "dtmf")) 10536 confp->chan.cid_signalling = CID_SIG_DTMF; 10537 else if (!strcasecmp(v->value, "smdi")) 10538 confp->chan.cid_signalling = CID_SIG_SMDI; 10539 else if (!strcasecmp(v->value, "v23_jp")) 10540 confp->chan.cid_signalling = CID_SIG_V23_JP; 10541 else if (ast_true(v->value)) 10542 confp->chan.cid_signalling = CID_SIG_BELL; 10543 } else if (!strcasecmp(v->name, "cidstart")) { 10544 if (!strcasecmp(v->value, "ring")) 10545 confp->chan.cid_start = CID_START_RING; 10546 else if (!strcasecmp(v->value, "polarity")) 10547 confp->chan.cid_start = CID_START_POLARITY; 10548 else if (ast_true(v->value)) 10549 confp->chan.cid_start = CID_START_RING; 10550 } else if (!strcasecmp(v->name, "threewaycalling")) { 10551 confp->chan.threewaycalling = ast_true(v->value); 10552 } else if (!strcasecmp(v->name, "cancallforward")) { 10553 confp->chan.cancallforward = ast_true(v->value); 10554 } else if (!strcasecmp(v->name, "relaxdtmf")) { 10555 if (ast_true(v->value)) 10556 confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 10557 else 10558 confp->chan.dtmfrelax = 0; 10559 } else if (!strcasecmp(v->name, "mailbox")) { 10560 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox)); 10561 } else if (!strcasecmp(v->name, "adsi")) { 10562 confp->chan.adsi = ast_true(v->value); 10563 } else if (!strcasecmp(v->name, "usesmdi")) { 10564 confp->chan.use_smdi = ast_true(v->value); 10565 } else if (!strcasecmp(v->name, "smdiport")) { 10566 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port)); 10567 } else if (!strcasecmp(v->name, "transfer")) { 10568 confp->chan.transfer = ast_true(v->value); 10569 } else if (!strcasecmp(v->name, "canpark")) { 10570 confp->chan.canpark = ast_true(v->value); 10571 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 10572 confp->chan.echocanbridged = ast_true(v->value); 10573 } else if (!strcasecmp(v->name, "busydetect")) { 10574 confp->chan.busydetect = ast_true(v->value); 10575 } else if (!strcasecmp(v->name, "busycount")) { 10576 confp->chan.busycount = atoi(v->value); 10577 } else if (!strcasecmp(v->name, "busypattern")) { 10578 if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) { 10579 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n"); 10580 } 10581 } else if (!strcasecmp(v->name, "callprogress")) { 10582 if (ast_true(v->value)) 10583 confp->chan.callprogress |= 1; 10584 else 10585 confp->chan.callprogress &= ~1; 10586 } else if (!strcasecmp(v->name, "faxdetect")) { 10587 if (!strcasecmp(v->value, "incoming")) { 10588 confp->chan.callprogress |= 4; 10589 confp->chan.callprogress &= ~2; 10590 } else if (!strcasecmp(v->value, "outgoing")) { 10591 confp->chan.callprogress &= ~4; 10592 confp->chan.callprogress |= 2; 10593 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 10594 confp->chan.callprogress |= 6; 10595 else 10596 confp->chan.callprogress &= ~6; 10597 } else if (!strcasecmp(v->name, "echocancel")) { 10598 if (!ast_strlen_zero(v->value)) { 10599 y = atoi(v->value); 10600 } else 10601 y = 0; 10602 if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024)) 10603 confp->chan.echocancel = y; 10604 else { 10605 confp->chan.echocancel = ast_true(v->value); 10606 if (confp->chan.echocancel) 10607 confp->chan.echocancel=128; 10608 } 10609 } else if (!strcasecmp(v->name, "echotraining")) { 10610 if (sscanf(v->value, "%d", &y) == 1) { 10611 if ((y < 10) || (y > 4000)) { 10612 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno); 10613 } else { 10614 confp->chan.echotraining = y; 10615 } 10616 } else if (ast_true(v->value)) { 10617 confp->chan.echotraining = 400; 10618 } else 10619 confp->chan.echotraining = 0; 10620 } else if (!strcasecmp(v->name, "hidecallerid")) { 10621 confp->chan.hidecallerid = ast_true(v->value); 10622 } else if (!strcasecmp(v->name, "hidecalleridname")) { 10623 confp->chan.hidecalleridname = ast_true(v->value); 10624 } else if (!strcasecmp(v->name, "pulsedial")) { 10625 confp->chan.pulse = ast_true(v->value); 10626 } else if (!strcasecmp(v->name, "callreturn")) { 10627 confp->chan.callreturn = ast_true(v->value); 10628 } else if (!strcasecmp(v->name, "callwaiting")) { 10629 confp->chan.callwaiting = ast_true(v->value); 10630 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 10631 confp->chan.callwaitingcallerid = ast_true(v->value); 10632 } else if (!strcasecmp(v->name, "context")) { 10633 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context)); 10634 } else if (!strcasecmp(v->name, "language")) { 10635 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language)); 10636 } else if (!strcasecmp(v->name, "progzone")) { 10637 ast_copy_string(progzone, v->value, sizeof(progzone)); 10638 } else if (!strcasecmp(v->name, "mohinterpret") 10639 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) { 10640 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret)); 10641 } else if (!strcasecmp(v->name, "mohsuggest")) { 10642 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest)); 10643 } else if (!strcasecmp(v->name, "stripmsd")) { 10644 confp->chan.stripmsd = atoi(v->value); 10645 } else if (!strcasecmp(v->name, "jitterbuffers")) { 10646 numbufs = atoi(v->value); 10647 } else if (!strcasecmp(v->name, "group")) { 10648 confp->chan.group = ast_get_group(v->value); 10649 } else if (!strcasecmp(v->name, "callgroup")) { 10650 confp->chan.callgroup = ast_get_group(v->value); 10651 } else if (!strcasecmp(v->name, "pickupgroup")) { 10652 confp->chan.pickupgroup = ast_get_group(v->value); 10653 } else if (!strcasecmp(v->name, "immediate")) { 10654 confp->chan.immediate = ast_true(v->value); 10655 } else if (!strcasecmp(v->name, "transfertobusy")) { 10656 confp->chan.transfertobusy = ast_true(v->value); 10657 } else if (!strcasecmp(v->name, "rxgain")) { 10658 if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) { 10659 ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value); 10660 } 10661 } else if (!strcasecmp(v->name, "txgain")) { 10662 if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) { 10663 ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value); 10664 } 10665 } else if (!strcasecmp(v->name, "tonezone")) { 10666 if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) { 10667 ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value); 10668 } 10669 } else if (!strcasecmp(v->name, "callerid")) { 10670 if (!strcasecmp(v->value, "asreceived")) { 10671 confp->chan.cid_num[0] = '\0'; 10672 confp->chan.cid_name[0] = '\0'; 10673 } else { 10674 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num)); 10675 } 10676 } else if (!strcasecmp(v->name, "fullname")) { 10677 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name)); 10678 } else if (!strcasecmp(v->name, "cid_number")) { 10679 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num)); 10680 } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) { 10681 confp->chan.zaptrcallerid = ast_true(v->value); 10682 } else if (!strcasecmp(v->name, "restrictcid")) { 10683 confp->chan.restrictcid = ast_true(v->value); 10684 } else if (!strcasecmp(v->name, "usecallingpres")) { 10685 confp->chan.use_callingpres = ast_true(v->value); 10686 } else if (!strcasecmp(v->name, "accountcode")) { 10687 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode)); 10688 } else if (!strcasecmp(v->name, "amaflags")) { 10689 y = ast_cdr_amaflags2int(v->value); 10690 if (y < 0) 10691 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 10692 else 10693 confp->chan.amaflags = y; 10694 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 10695 confp->chan.polarityonanswerdelay = atoi(v->value); 10696 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 10697 confp->chan.answeronpolarityswitch = ast_true(v->value); 10698 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 10699 confp->chan.hanguponpolarityswitch = ast_true(v->value); 10700 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 10701 confp->chan.sendcalleridafter = atoi(v->value); 10702 } else if (!reload){ 10703 if (!strcasecmp(v->name, "signalling")) { 10704 confp->chan.outsigmod = -1; 10705 if (!strcasecmp(v->value, "em")) { 10706 confp->chan.sig = SIG_EM; 10707 } else if (!strcasecmp(v->value, "em_e1")) { 10708 confp->chan.sig = SIG_EM_E1; 10709 } else if (!strcasecmp(v->value, "em_w")) { 10710 confp->chan.sig = SIG_EMWINK; 10711 confp->chan.radio = 0; 10712 } else if (!strcasecmp(v->value, "fxs_ls")) { 10713 confp->chan.sig = SIG_FXSLS; 10714 confp->chan.radio = 0; 10715 } else if (!strcasecmp(v->value, "fxs_gs")) { 10716 confp->chan.sig = SIG_FXSGS; 10717 confp->chan.radio = 0; 10718 } else if (!strcasecmp(v->value, "fxs_ks")) { 10719 confp->chan.sig = SIG_FXSKS; 10720 confp->chan.radio = 0; 10721 } else if (!strcasecmp(v->value, "fxo_ls")) { 10722 confp->chan.sig = SIG_FXOLS; 10723 confp->chan.radio = 0; 10724 } else if (!strcasecmp(v->value, "fxo_gs")) { 10725 confp->chan.sig = SIG_FXOGS; 10726 confp->chan.radio = 0; 10727 } else if (!strcasecmp(v->value, "fxo_ks")) { 10728 confp->chan.sig = SIG_FXOKS; 10729 confp->chan.radio = 0; 10730 } else if (!strcasecmp(v->value, "fxs_rx")) { 10731 confp->chan.sig = SIG_FXSKS; 10732 confp->chan.radio = 1; 10733 } else if (!strcasecmp(v->value, "fxo_rx")) { 10734 confp->chan.sig = SIG_FXOLS; 10735 confp->chan.radio = 1; 10736 } else if (!strcasecmp(v->value, "fxs_tx")) { 10737 confp->chan.sig = SIG_FXSLS; 10738 confp->chan.radio = 1; 10739 } else if (!strcasecmp(v->value, "fxo_tx")) { 10740 confp->chan.sig = SIG_FXOGS; 10741 confp->chan.radio = 1; 10742 } else if (!strcasecmp(v->value, "em_rx")) { 10743 confp->chan.sig = SIG_EM; 10744 confp->chan.radio = 1; 10745 } else if (!strcasecmp(v->value, "em_tx")) { 10746 confp->chan.sig = SIG_EM; 10747 confp->chan.radio = 1; 10748 } else if (!strcasecmp(v->value, "em_rxtx")) { 10749 confp->chan.sig = SIG_EM; 10750 confp->chan.radio = 2; 10751 } else if (!strcasecmp(v->value, "em_txrx")) { 10752 confp->chan.sig = SIG_EM; 10753 confp->chan.radio = 2; 10754 } else if (!strcasecmp(v->value, "sf")) { 10755 confp->chan.sig = SIG_SF; 10756 confp->chan.radio = 0; 10757 } else if (!strcasecmp(v->value, "sf_w")) { 10758 confp->chan.sig = SIG_SFWINK; 10759 confp->chan.radio = 0; 10760 } else if (!strcasecmp(v->value, "sf_featd")) { 10761 confp->chan.sig = SIG_FEATD; 10762 confp->chan.radio = 0; 10763 } else if (!strcasecmp(v->value, "sf_featdmf")) { 10764 confp->chan.sig = SIG_FEATDMF; 10765 confp->chan.radio = 0; 10766 } else if (!strcasecmp(v->value, "sf_featb")) { 10767 confp->chan.sig = SIG_SF_FEATB; 10768 confp->chan.radio = 0; 10769 } else if (!strcasecmp(v->value, "sf")) { 10770 confp->chan.sig = SIG_SF; 10771 confp->chan.radio = 0; 10772 } else if (!strcasecmp(v->value, "sf_rx")) { 10773 confp->chan.sig = SIG_SF; 10774 confp->chan.radio = 1; 10775 } else if (!strcasecmp(v->value, "sf_tx")) { 10776 confp->chan.sig = SIG_SF; 10777 confp->chan.radio = 1; 10778 } else if (!strcasecmp(v->value, "sf_rxtx")) { 10779 confp->chan.sig = SIG_SF; 10780 confp->chan.radio = 2; 10781 } else if (!strcasecmp(v->value, "sf_txrx")) { 10782 confp->chan.sig = SIG_SF; 10783 confp->chan.radio = 2; 10784 } else if (!strcasecmp(v->value, "featd")) { 10785 confp->chan.sig = SIG_FEATD; 10786 confp->chan.radio = 0; 10787 } else if (!strcasecmp(v->value, "featdmf")) { 10788 confp->chan.sig = SIG_FEATDMF; 10789 confp->chan.radio = 0; 10790 } else if (!strcasecmp(v->value, "featdmf_ta")) { 10791 confp->chan.sig = SIG_FEATDMF_TA; 10792 confp->chan.radio = 0; 10793 } else if (!strcasecmp(v->value, "e911")) { 10794 confp->chan.sig = SIG_E911; 10795 confp->chan.radio = 0; 10796 } else if (!strcasecmp(v->value, "fgccama")) { 10797 confp->chan.sig = SIG_FGC_CAMA; 10798 confp->chan.radio = 0; 10799 } else if (!strcasecmp(v->value, "fgccamamf")) { 10800 confp->chan.sig = SIG_FGC_CAMAMF; 10801 confp->chan.radio = 0; 10802 } else if (!strcasecmp(v->value, "featb")) { 10803 confp->chan.sig = SIG_FEATB; 10804 confp->chan.radio = 0; 10805 #ifdef HAVE_PRI 10806 } else if (!strcasecmp(v->value, "pri_net")) { 10807 confp->chan.radio = 0; 10808 confp->chan.sig = SIG_PRI; 10809 confp->pri.nodetype = PRI_NETWORK; 10810 } else if (!strcasecmp(v->value, "pri_cpe")) { 10811 confp->chan.sig = SIG_PRI; 10812 confp->chan.radio = 0; 10813 confp->pri.nodetype = PRI_CPE; 10814 } else if (!strcasecmp(v->value, "gr303fxoks_net")) { 10815 confp->chan.sig = SIG_GR303FXOKS; 10816 confp->chan.radio = 0; 10817 confp->pri.nodetype = PRI_NETWORK; 10818 } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) { 10819 confp->chan.sig = SIG_GR303FXSKS; 10820 confp->chan.radio = 0; 10821 confp->pri.nodetype = PRI_CPE; 10822 #endif 10823 } else { 10824 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 10825 } 10826 } else if (!strcasecmp(v->name, "outsignalling")) { 10827 if (!strcasecmp(v->value, "em")) { 10828 confp->chan.outsigmod = SIG_EM; 10829 } else if (!strcasecmp(v->value, "em_e1")) { 10830 confp->chan.outsigmod = SIG_EM_E1; 10831 } else if (!strcasecmp(v->value, "em_w")) { 10832 confp->chan.outsigmod = SIG_EMWINK; 10833 } else if (!strcasecmp(v->value, "sf")) { 10834 confp->chan.outsigmod = SIG_SF; 10835 } else if (!strcasecmp(v->value, "sf_w")) { 10836 confp->chan.outsigmod = SIG_SFWINK; 10837 } else if (!strcasecmp(v->value, "sf_featd")) { 10838 confp->chan.outsigmod = SIG_FEATD; 10839 } else if (!strcasecmp(v->value, "sf_featdmf")) { 10840 confp->chan.outsigmod = SIG_FEATDMF; 10841 } else if (!strcasecmp(v->value, "sf_featb")) { 10842 confp->chan.outsigmod = SIG_SF_FEATB; 10843 } else if (!strcasecmp(v->value, "sf")) { 10844 confp->chan.outsigmod = SIG_SF; 10845 } else if (!strcasecmp(v->value, "featd")) { 10846 confp->chan.outsigmod = SIG_FEATD; 10847 } else if (!strcasecmp(v->value, "featdmf")) { 10848 confp->chan.outsigmod = SIG_FEATDMF; 10849 } else if (!strcasecmp(v->value, "featdmf_ta")) { 10850 confp->chan.outsigmod = SIG_FEATDMF_TA; 10851 } else if (!strcasecmp(v->value, "e911")) { 10852 confp->chan.outsigmod = SIG_E911; 10853 } else if (!strcasecmp(v->value, "fgccama")) { 10854 confp->chan.outsigmod = SIG_FGC_CAMA; 10855 } else if (!strcasecmp(v->value, "fgccamamf")) { 10856 confp->chan.outsigmod = SIG_FGC_CAMAMF; 10857 } else if (!strcasecmp(v->value, "featb")) { 10858 confp->chan.outsigmod = SIG_FEATB; 10859 } else { 10860 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 10861 } 10862 #ifdef HAVE_PRI 10863 } else if (!strcasecmp(v->name, "pridialplan")) { 10864 if (!strcasecmp(v->value, "national")) { 10865 confp->pri.dialplan = PRI_NATIONAL_ISDN + 1; 10866 } else if (!strcasecmp(v->value, "unknown")) { 10867 confp->pri.dialplan = PRI_UNKNOWN + 1; 10868 } else if (!strcasecmp(v->value, "private")) { 10869 confp->pri.dialplan = PRI_PRIVATE + 1; 10870 } else if (!strcasecmp(v->value, "international")) { 10871 confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1; 10872 } else if (!strcasecmp(v->value, "local")) { 10873 confp->pri.dialplan = PRI_LOCAL_ISDN + 1; 10874 } else if (!strcasecmp(v->value, "dynamic")) { 10875 confp->pri.dialplan = -1; 10876 } else { 10877 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 10878 } 10879 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 10880 if (!strcasecmp(v->value, "national")) { 10881 confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1; 10882 } else if (!strcasecmp(v->value, "unknown")) { 10883 confp->pri.localdialplan = PRI_UNKNOWN + 1; 10884 } else if (!strcasecmp(v->value, "private")) { 10885 confp->pri.localdialplan = PRI_PRIVATE + 1; 10886 } else if (!strcasecmp(v->value, "international")) { 10887 confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1; 10888 } else if (!strcasecmp(v->value, "local")) { 10889 confp->pri.localdialplan = PRI_LOCAL_ISDN + 1; 10890 } else if (!strcasecmp(v->value, "dynamic")) { 10891 confp->pri.localdialplan = -1; 10892 } else { 10893 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 10894 } 10895 } else if (!strcasecmp(v->name, "switchtype")) { 10896 if (!strcasecmp(v->value, "national")) 10897 confp->pri.switchtype = PRI_SWITCH_NI2; 10898 else if (!strcasecmp(v->value, "ni1")) 10899 confp->pri.switchtype = PRI_SWITCH_NI1; 10900 else if (!strcasecmp(v->value, "dms100")) 10901 confp->pri.switchtype = PRI_SWITCH_DMS100; 10902 else if (!strcasecmp(v->value, "4ess")) 10903 confp->pri.switchtype = PRI_SWITCH_ATT4ESS; 10904 else if (!strcasecmp(v->value, "5ess")) 10905 confp->pri.switchtype = PRI_SWITCH_LUCENT5E; 10906 else if (!strcasecmp(v->value, "euroisdn")) 10907 confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1; 10908 else if (!strcasecmp(v->value, "qsig")) 10909 confp->pri.switchtype = PRI_SWITCH_QSIG; 10910 else { 10911 ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value); 10912 return -1; 10913 } 10914 } else if (!strcasecmp(v->name, "nsf")) { 10915 if (!strcasecmp(v->value, "sdn")) 10916 confp->pri.nsf = PRI_NSF_SDN; 10917 else if (!strcasecmp(v->value, "megacom")) 10918 confp->pri.nsf = PRI_NSF_MEGACOM; 10919 else if (!strcasecmp(v->value, "tollfreemegacom")) 10920 confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM; 10921 else if (!strcasecmp(v->value, "accunet")) 10922 confp->pri.nsf = PRI_NSF_ACCUNET; 10923 else if (!strcasecmp(v->value, "none")) 10924 confp->pri.nsf = PRI_NSF_NONE; 10925 else { 10926 ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value); 10927 confp->pri.nsf = PRI_NSF_NONE; 10928 } 10929 } else if (!strcasecmp(v->name, "priindication")) { 10930 if (!strcasecmp(v->value, "outofband")) 10931 confp->chan.priindication_oob = 1; 10932 else if (!strcasecmp(v->value, "inband")) 10933 confp->chan.priindication_oob = 0; 10934 else 10935 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n", 10936 v->value, v->lineno); 10937 } else if (!strcasecmp(v->name, "priexclusive")) { 10938 confp->chan.priexclusive = ast_true(v->value); 10939 } else if (!strcasecmp(v->name, "internationalprefix")) { 10940 ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix)); 10941 } else if (!strcasecmp(v->name, "nationalprefix")) { 10942 ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix)); 10943 } else if (!strcasecmp(v->name, "localprefix")) { 10944 ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix)); 10945 } else if (!strcasecmp(v->name, "privateprefix")) { 10946 ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix)); 10947 } else if (!strcasecmp(v->name, "unknownprefix")) { 10948 ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix)); 10949 } else if (!strcasecmp(v->name, "resetinterval")) { 10950 if (!strcasecmp(v->value, "never")) 10951 confp->pri.resetinterval = -1; 10952 else if (atoi(v->value) >= 60) 10953 confp->pri.resetinterval = atoi(v->value); 10954 else 10955 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n", 10956 v->value, v->lineno); 10957 } else if (!strcasecmp(v->name, "minunused")) { 10958 confp->pri.minunused = atoi(v->value); 10959 } else if (!strcasecmp(v->name, "minidle")) { 10960 confp->pri.minidle = atoi(v->value); 10961 } else if (!strcasecmp(v->name, "idleext")) { 10962 ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext)); 10963 } else if (!strcasecmp(v->name, "idledial")) { 10964 ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial)); 10965 } else if (!strcasecmp(v->name, "overlapdial")) { 10966 confp->pri.overlapdial = ast_true(v->value); 10967 } else if (!strcasecmp(v->name, "pritimer")) { 10968 #ifdef PRI_GETSET_TIMERS 10969 char *timerc, *c; 10970 int timer, timeridx; 10971 c = v->value; 10972 timerc = strsep(&c, ","); 10973 if (timerc) { 10974 timer = atoi(c); 10975 if (!timer) 10976 ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc); 10977 else { 10978 if ((timeridx = pri_timer2idx(timerc)) >= 0) 10979 pritimers[timeridx] = timer; 10980 else 10981 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc); 10982 } 10983 } else 10984 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value); 10985 10986 } else if (!strcasecmp(v->name, "facilityenable")) { 10987 confp->pri.facilityenable = ast_true(v->value); 10988 #endif /* PRI_GETSET_TIMERS */ 10989 #endif /* HAVE_PRI */ 10990 } else if (!strcasecmp(v->name, "cadence")) { 10991 /* setup to scan our argument */ 10992 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 10993 int i; 10994 struct zt_ring_cadence new_cadence; 10995 int cid_location = -1; 10996 int firstcadencepos = 0; 10997 char original_args[80]; 10998 int cadence_is_ok = 1; 10999 11000 ast_copy_string(original_args, v->value, sizeof(original_args)); 11001 /* 16 cadences allowed (8 pairs) */ 11002 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]); 11003 11004 /* Cadence must be even (on/off) */ 11005 if (element_count % 2 == 1) { 11006 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args); 11007 cadence_is_ok = 0; 11008 } 11009 11010 /* Ring cadences cannot be negative */ 11011 for (i = 0; i < element_count; i++) { 11012 if (c[i] == 0) { 11013 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args); 11014 cadence_is_ok = 0; 11015 break; 11016 } else if (c[i] < 0) { 11017 if (i % 2 == 1) { 11018 /* Silence duration, negative possibly okay */ 11019 if (cid_location == -1) { 11020 cid_location = i; 11021 c[i] *= -1; 11022 } else { 11023 ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args); 11024 cadence_is_ok = 0; 11025 break; 11026 } 11027 } else { 11028 if (firstcadencepos == 0) { 11029 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 11030 /* duration will be passed negative to the zaptel driver */ 11031 } else { 11032 ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args); 11033 cadence_is_ok = 0; 11034 break; 11035 } 11036 } 11037 } 11038 } 11039 11040 /* Substitute our scanned cadence */ 11041 for (i = 0; i < 16; i++) { 11042 new_cadence.ringcadence[i] = c[i]; 11043 } 11044 11045 if (cadence_is_ok) { 11046 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 11047 if (element_count < 2) { 11048 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args); 11049 } else { 11050 if (cid_location == -1) { 11051 /* user didn't say; default to first pause */ 11052 cid_location = 1; 11053 } else { 11054 /* convert element_index to cidrings value */ 11055 cid_location = (cid_location + 1) / 2; 11056 } 11057 /* ---we like their cadence; try to install it--- */ 11058 if (!user_has_defined_cadences++) 11059 /* this is the first user-defined cadence; clear the default user cadences */ 11060 num_cadence = 0; 11061 if ((num_cadence+1) >= NUM_CADENCE_MAX) 11062 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args); 11063 else { 11064 cadences[num_cadence] = new_cadence; 11065 cidrings[num_cadence++] = cid_location; 11066 if (option_verbose > 2) 11067 ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args); 11068 } 11069 } 11070 } 11071 } else if (!strcasecmp(v->name, "ringtimeout")) { 11072 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 11073 } else if (!strcasecmp(v->name, "prewink")) { 11074 confp->timing.prewinktime = atoi(v->value); 11075 } else if (!strcasecmp(v->name, "preflash")) { 11076 confp->timing.preflashtime = atoi(v->value); 11077 } else if (!strcasecmp(v->name, "wink")) { 11078 confp->timing.winktime = atoi(v->value); 11079 } else if (!strcasecmp(v->name, "flash")) { 11080 confp->timing.flashtime = atoi(v->value); 11081 } else if (!strcasecmp(v->name, "start")) { 11082 confp->timing.starttime = atoi(v->value); 11083 } else if (!strcasecmp(v->name, "rxwink")) { 11084 confp->timing.rxwinktime = atoi(v->value); 11085 } else if (!strcasecmp(v->name, "rxflash")) { 11086 confp->timing.rxflashtime = atoi(v->value); 11087 } else if (!strcasecmp(v->name, "debounce")) { 11088 confp->timing.debouncetime = atoi(v->value); 11089 } else if (!strcasecmp(v->name, "toneduration")) { 11090 int toneduration; 11091 int ctlfd; 11092 int res; 11093 struct zt_dialparams dps; 11094 11095 ctlfd = open("/dev/zap/ctl", O_RDWR); 11096 if (ctlfd == -1) { 11097 ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n"); 11098 return -1; 11099 } 11100 11101 toneduration = atoi(v->value); 11102 if (toneduration > -1) { 11103 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 11104 res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps); 11105 if (res < 0) { 11106 ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration); 11107 return -1; 11108 } 11109 } 11110 close(ctlfd); 11111 } else if (!strcasecmp(v->name, "defaultcic")) { 11112 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 11113 } else if (!strcasecmp(v->name, "defaultozz")) { 11114 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 11115 } 11116 } else if (!skipchannels) 11117 ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 11118 } 11119 if (zapchan[0]) { 11120 /* The user has set 'zapchan' */ 11121 /*< \todo pass proper line number instead of 0 */ 11122 if (build_channels(*confp, 0, zapchan, reload, 0, &found_pseudo)) { 11123 return -1; 11124 } 11125 } 11126 /*< \todo why check for the pseudo in the per-channel section. 11127 * Any actual use for manual setup of the pseudo channel? */ 11128 if (!found_pseudo && reload == 0) { 11129 /* Make sure pseudo isn't a member of any groups if 11130 we're automatically making it. */ 11131 11132 confp->chan.group = 0; 11133 confp->chan.callgroup = 0; 11134 confp->chan.pickupgroup = 0; 11135 11136 tmp = mkintf(CHAN_PSEUDO, *confp, NULL, reload); 11137 11138 if (tmp) { 11139 if (option_verbose > 2) 11140 ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n"); 11141 } else { 11142 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 11143 } 11144 } 11145 return 0; 11146 }
static int reload | ( | void | ) | [static] |
Definition at line 11427 of file chan_zap.c.
References ast_log(), LOG_WARNING, and setup_zap().
11428 { 11429 int res = 0; 11430 11431 res = setup_zap(1); 11432 if (res) { 11433 ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n"); 11434 return -1; 11435 } 11436 return 0; 11437 }
static int reset_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1336 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::confno, zt_subchannel::curconf, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_hangup().
01337 { 01338 ZT_CONFINFO zi; 01339 memset(&zi, 0, sizeof(zi)); 01340 p->confno = -1; 01341 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf)); 01342 if (p->subs[SUB_REAL].zfd > -1) { 01343 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi)) 01344 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel); 01345 } 01346 return 0; 01347 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 6951 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, and LOG_WARNING.
06952 { 06953 pthread_attr_t attr; 06954 pthread_attr_init(&attr); 06955 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06956 /* If we're supposed to be stopped -- stay stopped */ 06957 if (monitor_thread == AST_PTHREADT_STOP) 06958 return 0; 06959 ast_mutex_lock(&monlock); 06960 if (monitor_thread == pthread_self()) { 06961 ast_mutex_unlock(&monlock); 06962 ast_log(LOG_WARNING, "Cannot kill myself\n"); 06963 return -1; 06964 } 06965 if (monitor_thread != AST_PTHREADT_NULL) { 06966 /* Wake up the thread */ 06967 pthread_kill(monitor_thread, SIGURG); 06968 } else { 06969 /* Start a new monitor */ 06970 if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) { 06971 ast_mutex_unlock(&monlock); 06972 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 06973 pthread_attr_destroy(&attr); 06974 return -1; 06975 } 06976 } 06977 ast_mutex_unlock(&monlock); 06978 pthread_attr_destroy(&attr); 06979 return 0; 06980 }
static int restore_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1668 of file chan_zap.c.
References ast_log(), LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by send_callerid(), zt_handle_event(), and zt_read().
01669 { 01670 int res; 01671 if (p->saveconf.confmode) { 01672 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf); 01673 p->saveconf.confmode = 0; 01674 if (res) { 01675 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno)); 01676 return -1; 01677 } 01678 } 01679 if (option_debug) 01680 ast_log(LOG_DEBUG, "Restored conferencing\n"); 01681 return 0; 01682 }
static int restore_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1595 of file chan_zap.c.
References ast_log(), zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, zt_pvt::txgain, and zt_subchannel::zfd.
Referenced by ss_thread(), and zt_hangup().
01596 { 01597 int res; 01598 01599 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01600 if (res) { 01601 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno)); 01602 return -1; 01603 } 01604 01605 return 0; 01606 }
static int save_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1640 of file chan_zap.c.
References ast_log(), LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_callwait(), and zt_handle_event().
01641 { 01642 struct zt_confinfo c; 01643 int res; 01644 if (p->saveconf.confmode) { 01645 ast_log(LOG_WARNING, "Can't save conference -- already in use\n"); 01646 return -1; 01647 } 01648 p->saveconf.chan = 0; 01649 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf); 01650 if (res) { 01651 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno)); 01652 p->saveconf.confmode = 0; 01653 return -1; 01654 } 01655 c.chan = 0; 01656 c.confno = 0; 01657 c.confmode = ZT_CONF_NORMAL; 01658 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c); 01659 if (res) { 01660 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno)); 01661 return -1; 01662 } 01663 if (option_debug) 01664 ast_log(LOG_DEBUG, "Disabled conferencing\n"); 01665 return 0; 01666 }
static int send_callerid | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1708 of file chan_zap.c.
References ast_log(), zt_pvt::callwaitcas, CIDCW_EXPIRE_SAMPLES, zt_pvt::cidcwexpire, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, free, zt_subchannel::linear, LOG_WARNING, restore_conference(), SUB_REAL, zt_pvt::subs, zt_subchannel::zfd, and zt_setlinear().
Referenced by send_cwcidspill(), zt_call(), zt_callwait(), and zt_read().
01709 { 01710 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */ 01711 int res; 01712 /* Take out of linear mode if necessary */ 01713 if (p->subs[SUB_REAL].linear) { 01714 p->subs[SUB_REAL].linear = 0; 01715 zt_setlinear(p->subs[SUB_REAL].zfd, 0); 01716 } 01717 while (p->cidpos < p->cidlen) { 01718 res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos); 01719 if (res < 0) { 01720 if (errno == EAGAIN) 01721 return 0; 01722 else { 01723 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 01724 return -1; 01725 } 01726 } 01727 if (!res) 01728 return 0; 01729 p->cidpos += res; 01730 } 01731 free(p->cidspill); 01732 p->cidspill = NULL; 01733 if (p->callwaitcas) { 01734 /* Wait for CID/CW to expire */ 01735 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES; 01736 } else 01737 restore_conference(p); 01738 return 0; 01739 }
static int send_cwcidspill | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1686 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().
01687 { 01688 p->callwaitcas = 0; 01689 p->cidcwexpire = 0; 01690 if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) 01691 return -1; 01692 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p)); 01693 /* Make sure we account for the end */ 01694 p->cidlen += READ_SIZE * 4; 01695 p->cidpos = 0; 01696 send_callerid(p); 01697 if (option_verbose > 2) 01698 ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num); 01699 return 0; 01700 }
static int set_actual_gain | ( | int | fd, | |
int | chan, | |||
float | rxgain, | |||
float | txgain, | |||
int | law | |||
) | [static] |
Definition at line 1576 of file chan_zap.c.
References set_actual_rxgain(), and set_actual_txgain().
Referenced by bump_gains(), mkintf(), restore_gains(), and zt_call().
01577 { 01578 return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law); 01579 }
static int set_actual_rxgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1558 of file chan_zap.c.
References ast_log(), fill_rxgain(), and LOG_DEBUG.
Referenced by set_actual_gain(), and zt_setoption().
01559 { 01560 struct zt_gains g; 01561 int res; 01562 01563 memset(&g, 0, sizeof(g)); 01564 g.chan = chan; 01565 res = ioctl(fd, ZT_GETGAINS, &g); 01566 if (res) { 01567 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01568 return res; 01569 } 01570 01571 fill_rxgain(&g, gain, law); 01572 01573 return ioctl(fd, ZT_SETGAINS, &g); 01574 }
static int set_actual_txgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1539 of file chan_zap.c.
References ast_log(), fill_txgain(), LOG_DEBUG, and option_debug.
Referenced by set_actual_gain(), and zt_setoption().
01540 { 01541 struct zt_gains g; 01542 int res; 01543 01544 memset(&g, 0, sizeof(g)); 01545 g.chan = chan; 01546 res = ioctl(fd, ZT_GETGAINS, &g); 01547 if (res) { 01548 if (option_debug) 01549 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01550 return res; 01551 } 01552 01553 fill_txgain(&g, gain, law); 01554 01555 return ioctl(fd, ZT_SETGAINS, &g); 01556 }
static int setup_zap | ( | int | reload | ) | [static] |
Definition at line 11148 of file chan_zap.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), global_jbconf, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, option_verbose, process_zap(), restart_monitor(), ast_variable::value, VERBOSE_PREFIX_2, and zt_chan_conf_default().
Referenced by load_module(), reload(), and zap_restart().
11149 { 11150 struct ast_config *cfg; 11151 struct ast_variable *v; 11152 struct zt_chan_conf conf = zt_chan_conf_default(); 11153 int res; 11154 11155 #ifdef HAVE_PRI 11156 char *c; 11157 int spanno; 11158 int i, x; 11159 int logicalspan; 11160 int trunkgroup; 11161 int dchannels[NUM_DCHANS]; 11162 #endif 11163 11164 cfg = ast_config_load(config); 11165 11166 /* Error if we have no config file */ 11167 if (!cfg) { 11168 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 11169 return 0; 11170 } 11171 11172 /* It's a little silly to lock it, but we mind as well just to be sure */ 11173 ast_mutex_lock(&iflock); 11174 #ifdef HAVE_PRI 11175 if (!reload) { 11176 /* Process trunkgroups first */ 11177 v = ast_variable_browse(cfg, "trunkgroups"); 11178 while (v) { 11179 if (!strcasecmp(v->name, "trunkgroup")) { 11180 trunkgroup = atoi(v->value); 11181 if (trunkgroup > 0) { 11182 if ((c = strchr(v->value, ','))) { 11183 i = 0; 11184 memset(dchannels, 0, sizeof(dchannels)); 11185 while (c && (i < NUM_DCHANS)) { 11186 dchannels[i] = atoi(c + 1); 11187 if (dchannels[i] < 0) { 11188 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); 11189 } else 11190 i++; 11191 c = strchr(c + 1, ','); 11192 } 11193 if (i) { 11194 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 11195 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); 11196 } else if (option_verbose > 1) 11197 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"); 11198 } else 11199 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno); 11200 } else 11201 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno); 11202 } else 11203 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno); 11204 } else if (!strcasecmp(v->name, "spanmap")) { 11205 spanno = atoi(v->value); 11206 if (spanno > 0) { 11207 if ((c = strchr(v->value, ','))) { 11208 trunkgroup = atoi(c + 1); 11209 if (trunkgroup > 0) { 11210 if ((c = strchr(c + 1, ','))) 11211 logicalspan = atoi(c + 1); 11212 else 11213 logicalspan = 0; 11214 if (logicalspan >= 0) { 11215 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 11216 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 11217 } else if (option_verbose > 1) 11218 ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 11219 } else 11220 ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno); 11221 } else 11222 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno); 11223 } else 11224 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno); 11225 } else 11226 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno); 11227 } else { 11228 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 11229 } 11230 v = v->next; 11231 } 11232 } 11233 #endif 11234 11235 /* Copy the default jb config over global_jbconf */ 11236 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 11237 11238 v = ast_variable_browse(cfg, "channels"); 11239 res = process_zap(&conf, v, reload, 0); 11240 ast_mutex_unlock(&iflock); 11241 ast_config_destroy(cfg); 11242 if (res) 11243 return res; 11244 cfg = ast_config_load("users.conf"); 11245 if (cfg) { 11246 char *cat; 11247 const char *chans; 11248 process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1); 11249 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 11250 if (!strcasecmp(cat, "general")) 11251 continue; 11252 chans = ast_variable_retrieve(cfg, cat, "zapchan"); 11253 if (!ast_strlen_zero(chans)) { 11254 /** \todo At this point we should probably 11255 * duplicate conf, and pass a copy, to prevent 11256 * one section from affecting another 11257 */ 11258 process_zap(&conf, ast_variable_browse(cfg, cat), reload, 0); 11259 } 11260 } 11261 ast_config_destroy(cfg); 11262 } 11263 #ifdef HAVE_PRI 11264 if (!reload) { 11265 for (x = 0; x < NUM_SPANS; x++) { 11266 if (pris[x].pvts[0]) { 11267 if (start_pri(pris + x)) { 11268 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 11269 return -1; 11270 } else if (option_verbose > 1) 11271 ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1); 11272 } 11273 } 11274 } 11275 #endif 11276 /* And start the monitor for the first time */ 11277 restart_monitor(); 11278 return 0; 11279 }
static void * ss_thread | ( | void * | data | ) | [static] |
Definition at line 5400 of file chan_zap.c.
References ast_channel::_state, alloc_sub(), ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_CONTROL_RING, AST_CONTROL_UNHOLD, ast_db_put(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_free(), ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_read(), ast_safe_sleep(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), ast_shrink_phone_number(), ast_smdi_md_message_destroy(), ast_smdi_md_message_wait(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitfor(), ast_waitfordigit(), ast_waitstream(), ASTOBJ_UNREF, bump_gains(), zt_pvt::call_forward, callerid_feed(), callerid_feed_jp(), callerid_free(), callerid_get(), callerid_get_dtmf(), callerid_new(), ast_smdi_md_message::calling_st, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, CID_START_RING, zt_pvt::context, ast_channel::context, ringContextData::contextData, zt_pvt::defcontext, zt_pvt::dnd, zt_pvt::dop, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, zt_pvt::dtmfrelax, event2str(), EVENT_FLAG_SYSTEM, ast_channel::exten, zt_pvt::exten, exten, ast_frame::frametype, free, func, ast_smdi_md_message::fwd_st, ast_channel::hangupcause, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, zt_pvt::lastcid_num, len, zt_subchannel::linear, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), my_getsigstr(), name, NEED_MFDETECT, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), restore_gains(), distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::smdi_iface, SMDI_MD_WAIT_TIMEOUT, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech, ast_channel::tech_pvt, zt_pvt::transfer, ast_smdi_md_message::type, unalloc_sub(), zt_pvt::use_callerid, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_enable_ec(), zt_get_event(), zt_get_index(), zt_set_hook(), zt_setlinear(), zt_wait_event(), and zt_wink().
Referenced by handle_init_event(), and zt_handle_event().
05401 { 05402 struct ast_channel *chan = data; 05403 struct zt_pvt *p = chan->tech_pvt; 05404 char exten[AST_MAX_EXTENSION] = ""; 05405 char exten2[AST_MAX_EXTENSION] = ""; 05406 unsigned char buf[256]; 05407 char dtmfcid[300]; 05408 char dtmfbuf[300]; 05409 struct callerid_state *cs = NULL; 05410 char *name = NULL, *number = NULL; 05411 int distMatches; 05412 int curRingData[3]; 05413 int receivedRingT; 05414 int counter1; 05415 int counter; 05416 int samples = 0; 05417 struct ast_smdi_md_message *smdi_msg = NULL; 05418 int flags; 05419 int i; 05420 int timeout; 05421 int getforward = 0; 05422 char *s1, *s2; 05423 int len = 0; 05424 int res; 05425 int index; 05426 05427 /* in the bizarre case where the channel has become a zombie before we 05428 even get started here, abort safely 05429 */ 05430 if (!p) { 05431 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 05432 ast_hangup(chan); 05433 return NULL; 05434 } 05435 05436 if (option_verbose > 2) 05437 ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name); 05438 index = zt_get_index(chan, p, 1); 05439 if (index < 0) { 05440 ast_log(LOG_WARNING, "Huh?\n"); 05441 ast_hangup(chan); 05442 return NULL; 05443 } 05444 if (p->dsp) 05445 ast_dsp_digitreset(p->dsp); 05446 switch (p->sig) { 05447 #ifdef HAVE_PRI 05448 case SIG_PRI: 05449 /* Now loop looking for an extension */ 05450 ast_copy_string(exten, p->exten, sizeof(exten)); 05451 len = strlen(exten); 05452 res = 0; 05453 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05454 if (len && !ast_ignore_pattern(chan->context, exten)) 05455 tone_zone_play_tone(p->subs[index].zfd, -1); 05456 else 05457 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05458 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) 05459 timeout = matchdigittimeout; 05460 else 05461 timeout = gendigittimeout; 05462 res = ast_waitfordigit(chan, timeout); 05463 if (res < 0) { 05464 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05465 ast_hangup(chan); 05466 return NULL; 05467 } else if (res) { 05468 exten[len++] = res; 05469 exten[len] = '\0'; 05470 } else 05471 break; 05472 } 05473 /* if no extension was received ('unspecified') on overlap call, use the 's' extension */ 05474 if (ast_strlen_zero(exten)) { 05475 if (option_verbose > 2) 05476 ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n"); 05477 exten[0] = 's'; 05478 exten[1] = '\0'; 05479 } 05480 tone_zone_play_tone(p->subs[index].zfd, -1); 05481 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 05482 /* Start the real PBX */ 05483 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05484 if (p->dsp) ast_dsp_digitreset(p->dsp); 05485 zt_enable_ec(p); 05486 ast_setstate(chan, AST_STATE_RING); 05487 res = ast_pbx_run(chan); 05488 if (res) { 05489 ast_log(LOG_WARNING, "PBX exited non-zero!\n"); 05490 } 05491 } else { 05492 ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context); 05493 chan->hangupcause = AST_CAUSE_UNALLOCATED; 05494 ast_hangup(chan); 05495 p->exten[0] = '\0'; 05496 /* Since we send release complete here, we won't get one */ 05497 p->call = NULL; 05498 } 05499 return NULL; 05500 break; 05501 #endif 05502 case SIG_FEATD: 05503 case SIG_FEATDMF: 05504 case SIG_FEATDMF_TA: 05505 case SIG_E911: 05506 case SIG_FGC_CAMAMF: 05507 case SIG_FEATB: 05508 case SIG_EMWINK: 05509 case SIG_SF_FEATD: 05510 case SIG_SF_FEATDMF: 05511 case SIG_SF_FEATB: 05512 case SIG_SFWINK: 05513 if (zt_wink(p, index)) 05514 return NULL; 05515 /* Fall through */ 05516 case SIG_EM: 05517 case SIG_EM_E1: 05518 case SIG_SF: 05519 case SIG_FGC_CAMA: 05520 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05521 if (p->dsp) 05522 ast_dsp_digitreset(p->dsp); 05523 /* set digit mode appropriately */ 05524 if (p->dsp) { 05525 if (NEED_MFDETECT(p)) 05526 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05527 else 05528 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05529 } 05530 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 05531 /* Wait for the first digit only if immediate=no */ 05532 if (!p->immediate) 05533 /* Wait for the first digit (up to 5 seconds). */ 05534 res = ast_waitfordigit(chan, 5000); 05535 else 05536 res = 0; 05537 if (res > 0) { 05538 /* save first char */ 05539 dtmfbuf[0] = res; 05540 switch (p->sig) { 05541 case SIG_FEATD: 05542 case SIG_SF_FEATD: 05543 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05544 if (res > 0) 05545 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05546 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05547 break; 05548 case SIG_FEATDMF_TA: 05549 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05550 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05551 if (zt_wink(p, index)) return NULL; 05552 dtmfbuf[0] = 0; 05553 /* Wait for the first digit (up to 5 seconds). */ 05554 res = ast_waitfordigit(chan, 5000); 05555 if (res <= 0) break; 05556 dtmfbuf[0] = res; 05557 /* fall through intentionally */ 05558 case SIG_FEATDMF: 05559 case SIG_E911: 05560 case SIG_FGC_CAMAMF: 05561 case SIG_SF_FEATDMF: 05562 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05563 /* if international caca, do it again to get real ANO */ 05564 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14)) 05565 { 05566 if (zt_wink(p, index)) return NULL; 05567 dtmfbuf[0] = 0; 05568 /* Wait for the first digit (up to 5 seconds). */ 05569 res = ast_waitfordigit(chan, 5000); 05570 if (res <= 0) break; 05571 dtmfbuf[0] = res; 05572 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05573 } 05574 if (res > 0) { 05575 /* if E911, take off hook */ 05576 if (p->sig == SIG_E911) 05577 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05578 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 05579 } 05580 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05581 break; 05582 case SIG_FEATB: 05583 case SIG_SF_FEATB: 05584 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05585 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05586 break; 05587 case SIG_EMWINK: 05588 /* if we received a '*', we are actually receiving Feature Group D 05589 dial syntax, so use that mode; otherwise, fall through to normal 05590 mode 05591 */ 05592 if (res == '*') { 05593 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05594 if (res > 0) 05595 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05596 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05597 break; 05598 } 05599 default: 05600 /* If we got the first digit, get the rest */ 05601 len = 1; 05602 dtmfbuf[len] = '\0'; 05603 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05604 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05605 timeout = matchdigittimeout; 05606 } else { 05607 timeout = gendigittimeout; 05608 } 05609 res = ast_waitfordigit(chan, timeout); 05610 if (res < 0) { 05611 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05612 ast_hangup(chan); 05613 return NULL; 05614 } else if (res) { 05615 dtmfbuf[len++] = res; 05616 dtmfbuf[len] = '\0'; 05617 } else { 05618 break; 05619 } 05620 } 05621 break; 05622 } 05623 } 05624 if (res == -1) { 05625 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 05626 ast_hangup(chan); 05627 return NULL; 05628 } else if (res < 0) { 05629 ast_log(LOG_DEBUG, "Got hung up before digits finished\n"); 05630 ast_hangup(chan); 05631 return NULL; 05632 } 05633 05634 if (p->sig == SIG_FGC_CAMA) { 05635 char anibuf[100]; 05636 05637 if (ast_safe_sleep(chan,1000) == -1) { 05638 ast_hangup(chan); 05639 return NULL; 05640 } 05641 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05642 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05643 res = my_getsigstr(chan, anibuf, "#", 10000); 05644 if ((res > 0) && (strlen(anibuf) > 2)) { 05645 if (anibuf[strlen(anibuf) - 1] == '#') 05646 anibuf[strlen(anibuf) - 1] = 0; 05647 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 05648 } 05649 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05650 } 05651 05652 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 05653 if (ast_strlen_zero(exten)) 05654 ast_copy_string(exten, "s", sizeof(exten)); 05655 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 05656 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 05657 if (exten[0] == '*') { 05658 char *stringp=NULL; 05659 ast_copy_string(exten2, exten, sizeof(exten2)); 05660 /* Parse out extension and callerid */ 05661 stringp=exten2 +1; 05662 s1 = strsep(&stringp, "*"); 05663 s2 = strsep(&stringp, "*"); 05664 if (s2) { 05665 if (!ast_strlen_zero(p->cid_num)) 05666 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05667 else 05668 ast_set_callerid(chan, s1, NULL, s1); 05669 ast_copy_string(exten, s2, sizeof(exten)); 05670 } else 05671 ast_copy_string(exten, s1, sizeof(exten)); 05672 } else if (p->sig == SIG_FEATD) 05673 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05674 } 05675 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05676 if (exten[0] == '*') { 05677 char *stringp=NULL; 05678 ast_copy_string(exten2, exten, sizeof(exten2)); 05679 /* Parse out extension and callerid */ 05680 stringp=exten2 +1; 05681 s1 = strsep(&stringp, "#"); 05682 s2 = strsep(&stringp, "#"); 05683 if (s2) { 05684 if (!ast_strlen_zero(p->cid_num)) 05685 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05686 else 05687 if (*(s1 + 2)) 05688 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 05689 ast_copy_string(exten, s2 + 1, sizeof(exten)); 05690 } else 05691 ast_copy_string(exten, s1 + 2, sizeof(exten)); 05692 } else 05693 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05694 } 05695 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) { 05696 if (exten[0] == '*') { 05697 char *stringp=NULL; 05698 ast_copy_string(exten2, exten, sizeof(exten2)); 05699 /* Parse out extension and callerid */ 05700 stringp=exten2 +1; 05701 s1 = strsep(&stringp, "#"); 05702 s2 = strsep(&stringp, "#"); 05703 if (s2 && (*(s2 + 1) == '0')) { 05704 if (*(s2 + 2)) 05705 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 05706 } 05707 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 05708 else ast_copy_string(exten, "911", sizeof(exten)); 05709 } else 05710 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 05711 } 05712 if (p->sig == SIG_FEATB) { 05713 if (exten[0] == '*') { 05714 char *stringp=NULL; 05715 ast_copy_string(exten2, exten, sizeof(exten2)); 05716 /* Parse out extension and callerid */ 05717 stringp=exten2 +1; 05718 s1 = strsep(&stringp, "#"); 05719 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 05720 } else 05721 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 05722 } 05723 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05724 zt_wink(p, index); 05725 /* some switches require a minimum guard time between 05726 the last FGD wink and something that answers 05727 immediately. This ensures it */ 05728 if (ast_safe_sleep(chan,100)) return NULL; 05729 } 05730 zt_enable_ec(p); 05731 if (NEED_MFDETECT(p)) { 05732 if (p->dsp) { 05733 if (!p->hardwaredtmf) 05734 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05735 else { 05736 ast_dsp_free(p->dsp); 05737 p->dsp = NULL; 05738 } 05739 } 05740 } 05741 05742 if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) { 05743 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05744 if (p->dsp) ast_dsp_digitreset(p->dsp); 05745 res = ast_pbx_run(chan); 05746 if (res) { 05747 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05748 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05749 } 05750 return NULL; 05751 } else { 05752 if (option_verbose > 2) 05753 ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 05754 sleep(2); 05755 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO); 05756 if (res < 0) 05757 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 05758 else 05759 sleep(1); 05760 res = ast_streamfile(chan, "ss-noservice", chan->language); 05761 if (res >= 0) 05762 ast_waitstream(chan, ""); 05763 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05764 ast_hangup(chan); 05765 return NULL; 05766 } 05767 break; 05768 case SIG_FXOLS: 05769 case SIG_FXOGS: 05770 case SIG_FXOKS: 05771 /* Read the first digit */ 05772 timeout = firstdigittimeout; 05773 /* If starting a threeway call, never timeout on the first digit so someone 05774 can use flash-hook as a "hold" feature */ 05775 if (p->subs[SUB_THREEWAY].owner) 05776 timeout = 999999; 05777 while (len < AST_MAX_EXTENSION-1) { 05778 /* Read digit unless it's supposed to be immediate, in which case the 05779 only answer is 's' */ 05780 if (p->immediate) 05781 res = 's'; 05782 else 05783 res = ast_waitfordigit(chan, timeout); 05784 timeout = 0; 05785 if (res < 0) { 05786 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05787 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05788 ast_hangup(chan); 05789 return NULL; 05790 } else if (res) { 05791 exten[len++]=res; 05792 exten[len] = '\0'; 05793 } 05794 if (!ast_ignore_pattern(chan->context, exten)) 05795 tone_zone_play_tone(p->subs[index].zfd, -1); 05796 else 05797 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05798 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) { 05799 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05800 if (getforward) { 05801 /* Record this as the forwarding extension */ 05802 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 05803 if (option_verbose > 2) 05804 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 05805 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05806 if (res) 05807 break; 05808 usleep(500000); 05809 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05810 sleep(1); 05811 memset(exten, 0, sizeof(exten)); 05812 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05813 len = 0; 05814 getforward = 0; 05815 } else { 05816 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05817 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05818 if (!ast_strlen_zero(p->cid_num)) { 05819 if (!p->hidecallerid) 05820 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05821 else 05822 ast_set_callerid(chan, NULL, NULL, p->cid_num); 05823 } 05824 if (!ast_strlen_zero(p->cid_name)) { 05825 if (!p->hidecallerid) 05826 ast_set_callerid(chan, NULL, p->cid_name, NULL); 05827 } 05828 ast_setstate(chan, AST_STATE_RING); 05829 zt_enable_ec(p); 05830 res = ast_pbx_run(chan); 05831 if (res) { 05832 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05833 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05834 } 05835 return NULL; 05836 } 05837 } else { 05838 /* It's a match, but they just typed a digit, and there is an ambiguous match, 05839 so just set the timeout to matchdigittimeout and wait some more */ 05840 timeout = matchdigittimeout; 05841 } 05842 } else if (res == 0) { 05843 ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n"); 05844 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05845 zt_wait_event(p->subs[index].zfd); 05846 ast_hangup(chan); 05847 return NULL; 05848 } else if (p->callwaiting && !strcmp(exten, "*70")) { 05849 if (option_verbose > 2) 05850 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 05851 /* Disable call waiting if enabled */ 05852 p->callwaiting = 0; 05853 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05854 if (res) { 05855 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05856 chan->name, strerror(errno)); 05857 } 05858 len = 0; 05859 ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len); 05860 memset(exten, 0, sizeof(exten)); 05861 timeout = firstdigittimeout; 05862 05863 } else if (!strcmp(exten,ast_pickup_ext())) { 05864 /* Scan all channels and see if any there 05865 * ringing channqels with that have call groups 05866 * that equal this channels pickup group 05867 */ 05868 if (index == SUB_REAL) { 05869 /* Switch us from Third call to Call Wait */ 05870 if (p->subs[SUB_THREEWAY].owner) { 05871 /* If you make a threeway call and the *8# a call, it should actually 05872 look like a callwait */ 05873 alloc_sub(p, SUB_CALLWAIT); 05874 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 05875 unalloc_sub(p, SUB_THREEWAY); 05876 } 05877 zt_enable_ec(p); 05878 if (ast_pickup_call(chan)) { 05879 ast_log(LOG_DEBUG, "No call pickup possible...\n"); 05880 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05881 zt_wait_event(p->subs[index].zfd); 05882 } 05883 ast_hangup(chan); 05884 return NULL; 05885 } else { 05886 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 05887 ast_hangup(chan); 05888 return NULL; 05889 } 05890 05891 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 05892 if (option_verbose > 2) 05893 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 05894 /* Disable Caller*ID if enabled */ 05895 p->hidecallerid = 1; 05896 if (chan->cid.cid_num) 05897 free(chan->cid.cid_num); 05898 chan->cid.cid_num = NULL; 05899 if (chan->cid.cid_name) 05900 free(chan->cid.cid_name); 05901 chan->cid.cid_name = NULL; 05902 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05903 if (res) { 05904 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05905 chan->name, strerror(errno)); 05906 } 05907 len = 0; 05908 memset(exten, 0, sizeof(exten)); 05909 timeout = firstdigittimeout; 05910 } else if (p->callreturn && !strcmp(exten, "*69")) { 05911 res = 0; 05912 if (!ast_strlen_zero(p->lastcid_num)) { 05913 res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language); 05914 } 05915 if (!res) 05916 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05917 break; 05918 } else if (!strcmp(exten, "*78")) { 05919 /* Do not disturb */ 05920 if (option_verbose > 2) 05921 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel); 05922 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 05923 "Channel: Zap/%d\r\n" 05924 "Status: enabled\r\n", p->channel); 05925 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05926 p->dnd = 1; 05927 getforward = 0; 05928 memset(exten, 0, sizeof(exten)); 05929 len = 0; 05930 } else if (!strcmp(exten, "*79")) { 05931 /* Do not disturb */ 05932 if (option_verbose > 2) 05933 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel); 05934 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 05935 "Channel: Zap/%d\r\n" 05936 "Status: disabled\r\n", p->channel); 05937 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05938 p->dnd = 0; 05939 getforward = 0; 05940 memset(exten, 0, sizeof(exten)); 05941 len = 0; 05942 } else if (p->cancallforward && !strcmp(exten, "*72")) { 05943 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05944 getforward = 1; 05945 memset(exten, 0, sizeof(exten)); 05946 len = 0; 05947 } else if (p->cancallforward && !strcmp(exten, "*73")) { 05948 if (option_verbose > 2) 05949 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel); 05950 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05951 memset(p->call_forward, 0, sizeof(p->call_forward)); 05952 getforward = 0; 05953 memset(exten, 0, sizeof(exten)); 05954 len = 0; 05955 } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 05956 p->subs[SUB_THREEWAY].owner && 05957 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 05958 /* This is a three way call, the main call being a real channel, 05959 and we're parking the first call. */ 05960 ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL); 05961 if (option_verbose > 2) 05962 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 05963 break; 05964 } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) { 05965 if (option_verbose > 2) 05966 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num); 05967 res = ast_db_put("blacklist", p->lastcid_num, "1"); 05968 if (!res) { 05969 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05970 memset(exten, 0, sizeof(exten)); 05971 len = 0; 05972 } 05973 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 05974 if (option_verbose > 2) 05975 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 05976 /* Enable Caller*ID if enabled */ 05977 p->hidecallerid = 0; 05978 if (chan->cid.cid_num) 05979 free(chan->cid.cid_num); 05980 chan->cid.cid_num = NULL; 05981 if (chan->cid.cid_name) 05982 free(chan->cid.cid_name); 05983 chan->cid.cid_name = NULL; 05984 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 05985 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05986 if (res) { 05987 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05988 chan->name, strerror(errno)); 05989 } 05990 len = 0; 05991 memset(exten, 0, sizeof(exten)); 05992 timeout = firstdigittimeout; 05993 } else if (!strcmp(exten, "*0")) { 05994 struct ast_channel *nbridge = 05995 p->subs[SUB_THREEWAY].owner; 05996 struct zt_pvt *pbridge = NULL; 05997 /* set up the private struct of the bridged one, if any */ 05998 if (nbridge && ast_bridged_channel(nbridge)) 05999 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 06000 if (nbridge && pbridge && 06001 (nbridge->tech == &zap_tech) && 06002 (ast_bridged_channel(nbridge)->tech == &zap_tech) && 06003 ISTRUNK(pbridge)) { 06004 int func = ZT_FLASH; 06005 /* Clear out the dial buffer */ 06006 p->dop.dialstr[0] = '\0'; 06007 /* flash hookswitch */ 06008 if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 06009 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 06010 nbridge->name, strerror(errno)); 06011 } 06012 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06013 unalloc_sub(p, SUB_THREEWAY); 06014 p->owner = p->subs[SUB_REAL].owner; 06015 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 06016 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 06017 ast_hangup(chan); 06018 return NULL; 06019 } else { 06020 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06021 zt_wait_event(p->subs[index].zfd); 06022 tone_zone_play_tone(p->subs[index].zfd, -1); 06023 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06024 unalloc_sub(p, SUB_THREEWAY); 06025 p->owner = p->subs[SUB_REAL].owner; 06026 ast_hangup(chan); 06027 return NULL; 06028 } 06029 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 06030 ((exten[0] != '*') || (strlen(exten) > 2))) { 06031 if (option_debug) 06032 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); 06033 break; 06034 } 06035 if (!timeout) 06036 timeout = gendigittimeout; 06037 if (len && !ast_ignore_pattern(chan->context, exten)) 06038 tone_zone_play_tone(p->subs[index].zfd, -1); 06039 } 06040 break; 06041 case SIG_FXSLS: 06042 case SIG_FXSGS: 06043 case SIG_FXSKS: 06044 #ifdef HAVE_PRI 06045 if (p->pri) { 06046 /* This is a GR-303 trunk actually. Wait for the first ring... */ 06047 struct ast_frame *f; 06048 int res; 06049 time_t start; 06050 06051 time(&start); 06052 ast_setstate(chan, AST_STATE_RING); 06053 while (time(NULL) < start + 3) { 06054 res = ast_waitfor(chan, 1000); 06055 if (res) { 06056 f = ast_read(chan); 06057 if (!f) { 06058 ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n"); 06059 ast_hangup(chan); 06060 return NULL; 06061 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) { 06062 res = 1; 06063 } else 06064 res = 0; 06065 ast_frfree(f); 06066 if (res) { 06067 ast_log(LOG_DEBUG, "Got ring!\n"); 06068 res = 0; 06069 break; 06070 } 06071 } 06072 } 06073 } 06074 #endif 06075 /* check for SMDI messages */ 06076 if (p->use_smdi && p->smdi_iface) { 06077 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT); 06078 06079 if (smdi_msg != NULL) { 06080 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 06081 06082 if (smdi_msg->type == 'B') 06083 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 06084 else if (smdi_msg->type == 'N') 06085 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 06086 06087 ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name); 06088 } else { 06089 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 06090 } 06091 } 06092 06093 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 06094 number = smdi_msg->calling_st; 06095 06096 /* If we want caller id, we're in a prering state due to a polarity reversal 06097 * and we're set to use a polarity reversal to trigger the start of caller id, 06098 * grab the caller id and wait for ringing to start... */ 06099 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) { 06100 /* If set to use DTMF CID signalling, listen for DTMF */ 06101 if (p->cid_signalling == CID_SIG_DTMF) { 06102 int i = 0; 06103 cs = NULL; 06104 ast_log(LOG_DEBUG, "Receiving DTMF cid on " 06105 "channel %s\n", chan->name); 06106 zt_setlinear(p->subs[index].zfd, 0); 06107 res = 2000; 06108 for (;;) { 06109 struct ast_frame *f; 06110 res = ast_waitfor(chan, res); 06111 if (res <= 0) { 06112 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 06113 "Exiting simple switch\n"); 06114 ast_hangup(chan); 06115 return NULL; 06116 } 06117 f = ast_read(chan); 06118 if (f->frametype == AST_FRAME_DTMF) { 06119 dtmfbuf[i++] = f->subclass; 06120 ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass); 06121 res = 2000; 06122 } 06123 ast_frfree(f); 06124 if (chan->_state == AST_STATE_RING || 06125 chan->_state == AST_STATE_RINGING) 06126 break; /* Got ring */ 06127 } 06128 dtmfbuf[i] = '\0'; 06129 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06130 /* Got cid and ring. */ 06131 ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf); 06132 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 06133 ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 06134 dtmfcid, flags); 06135 /* If first byte is NULL, we have no cid */ 06136 if (!ast_strlen_zero(dtmfcid)) 06137 number = dtmfcid; 06138 else 06139 number = NULL; 06140 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 06141 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 06142 cs = callerid_new(p->cid_signalling); 06143 if (cs) { 06144 samples = 0; 06145 #if 1 06146 bump_gains(p); 06147 #endif 06148 /* Take out of linear mode for Caller*ID processing */ 06149 zt_setlinear(p->subs[index].zfd, 0); 06150 06151 /* First we wait and listen for the Caller*ID */ 06152 for (;;) { 06153 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06154 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06155 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06156 callerid_free(cs); 06157 ast_hangup(chan); 06158 return NULL; 06159 } 06160 if (i & ZT_IOMUX_SIGEVENT) { 06161 res = zt_get_event(p->subs[index].zfd); 06162 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06163 06164 if (p->cid_signalling == CID_SIG_V23_JP) { 06165 #ifdef ZT_EVENT_RINGBEGIN 06166 if (res == ZT_EVENT_RINGBEGIN) { 06167 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06168 usleep(1); 06169 } 06170 #endif 06171 } else { 06172 res = 0; 06173 break; 06174 } 06175 } else if (i & ZT_IOMUX_READ) { 06176 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06177 if (res < 0) { 06178 if (errno != ELAST) { 06179 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06180 callerid_free(cs); 06181 ast_hangup(chan); 06182 return NULL; 06183 } 06184 break; 06185 } 06186 samples += res; 06187 06188 if (p->cid_signalling == CID_SIG_V23_JP) { 06189 res = callerid_feed_jp(cs, buf, res, AST_LAW(p)); 06190 } else { 06191 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06192 } 06193 06194 if (res < 0) { 06195 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06196 break; 06197 } else if (res) 06198 break; 06199 else if (samples > (8000 * 10)) 06200 break; 06201 } 06202 } 06203 if (res == 1) { 06204 callerid_get(cs, &name, &number, &flags); 06205 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06206 } 06207 if (res < 0) { 06208 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06209 } 06210 06211 if (p->cid_signalling == CID_SIG_V23_JP) { 06212 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 06213 usleep(1); 06214 res = 4000; 06215 } else { 06216 06217 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 06218 res = 2000; 06219 } 06220 06221 for (;;) { 06222 struct ast_frame *f; 06223 res = ast_waitfor(chan, res); 06224 if (res <= 0) { 06225 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 06226 "Exiting simple switch\n"); 06227 ast_hangup(chan); 06228 return NULL; 06229 } 06230 f = ast_read(chan); 06231 ast_frfree(f); 06232 if (chan->_state == AST_STATE_RING || 06233 chan->_state == AST_STATE_RINGING) 06234 break; /* Got ring */ 06235 } 06236 06237 /* We must have a ring by now, so, if configured, lets try to listen for 06238 * distinctive ringing */ 06239 if (p->usedistinctiveringdetection == 1) { 06240 len = 0; 06241 distMatches = 0; 06242 /* Clear the current ring data array so we dont have old data in it. */ 06243 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06244 curRingData[receivedRingT] = 0; 06245 receivedRingT = 0; 06246 counter = 0; 06247 counter1 = 0; 06248 /* Check to see if context is what it should be, if not set to be. */ 06249 if (strcmp(p->context,p->defcontext) != 0) { 06250 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06251 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06252 } 06253 06254 for (;;) { 06255 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06256 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06257 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06258 callerid_free(cs); 06259 ast_hangup(chan); 06260 return NULL; 06261 } 06262 if (i & ZT_IOMUX_SIGEVENT) { 06263 res = zt_get_event(p->subs[index].zfd); 06264 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06265 res = 0; 06266 /* Let us detect distinctive ring */ 06267 06268 curRingData[receivedRingT] = p->ringt; 06269 06270 if (p->ringt < p->ringt_base/2) 06271 break; 06272 /* Increment the ringT counter so we can match it against 06273 values in zapata.conf for distinctive ring */ 06274 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06275 break; 06276 } else if (i & ZT_IOMUX_READ) { 06277 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06278 if (res < 0) { 06279 if (errno != ELAST) { 06280 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06281 callerid_free(cs); 06282 ast_hangup(chan); 06283 return NULL; 06284 } 06285 break; 06286 } 06287 if (p->ringt) 06288 p->ringt--; 06289 if (p->ringt == 1) { 06290 res = -1; 06291 break; 06292 } 06293 } 06294 } 06295 if (option_verbose > 2) 06296 /* this only shows up if you have n of the dring patterns filled in */ 06297 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06298 06299 for (counter = 0; counter < 3; counter++) { 06300 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06301 channel */ 06302 distMatches = 0; 06303 for (counter1 = 0; counter1 < 3; counter1++) { 06304 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06305 (p->drings.ringnum[counter].ring[counter1]-10)) { 06306 distMatches++; 06307 } 06308 } 06309 if (distMatches == 3) { 06310 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06311 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06312 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06313 if (option_verbose > 2) 06314 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06315 break; 06316 } 06317 } 06318 } 06319 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06320 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06321 #if 1 06322 restore_gains(p); 06323 #endif 06324 } else 06325 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06326 } else { 06327 ast_log(LOG_WARNING, "Channel %s in prering " 06328 "state, but I have nothing to do. " 06329 "Terminating simple switch, should be " 06330 "restarted by the actual ring.\n", 06331 chan->name); 06332 ast_hangup(chan); 06333 return NULL; 06334 } 06335 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 06336 /* FSK Bell202 callerID */ 06337 cs = callerid_new(p->cid_signalling); 06338 if (cs) { 06339 #if 1 06340 bump_gains(p); 06341 #endif 06342 samples = 0; 06343 len = 0; 06344 distMatches = 0; 06345 /* Clear the current ring data array so we dont have old data in it. */ 06346 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06347 curRingData[receivedRingT] = 0; 06348 receivedRingT = 0; 06349 counter = 0; 06350 counter1 = 0; 06351 /* Check to see if context is what it should be, if not set to be. */ 06352 if (strcmp(p->context,p->defcontext) != 0) { 06353 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06354 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06355 } 06356 06357 /* Take out of linear mode for Caller*ID processing */ 06358 zt_setlinear(p->subs[index].zfd, 0); 06359 for (;;) { 06360 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06361 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06362 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06363 callerid_free(cs); 06364 ast_hangup(chan); 06365 return NULL; 06366 } 06367 if (i & ZT_IOMUX_SIGEVENT) { 06368 res = zt_get_event(p->subs[index].zfd); 06369 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06370 res = 0; 06371 /* Let us detect callerid when the telco uses distinctive ring */ 06372 06373 curRingData[receivedRingT] = p->ringt; 06374 06375 if (p->ringt < p->ringt_base/2) 06376 break; 06377 /* Increment the ringT counter so we can match it against 06378 values in zapata.conf for distinctive ring */ 06379 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06380 break; 06381 } else if (i & ZT_IOMUX_READ) { 06382 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06383 if (res < 0) { 06384 if (errno != ELAST) { 06385 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06386 callerid_free(cs); 06387 ast_hangup(chan); 06388 return NULL; 06389 } 06390 break; 06391 } 06392 if (p->ringt) 06393 p->ringt--; 06394 if (p->ringt == 1) { 06395 res = -1; 06396 break; 06397 } 06398 samples += res; 06399 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06400 if (res < 0) { 06401 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06402 break; 06403 } else if (res) 06404 break; 06405 else if (samples > (8000 * 10)) 06406 break; 06407 } 06408 } 06409 if (res == 1) { 06410 callerid_get(cs, &name, &number, &flags); 06411 if (option_debug) 06412 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06413 } 06414 if (distinctiveringaftercid == 1) { 06415 /* Clear the current ring data array so we dont have old data in it. */ 06416 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) { 06417 curRingData[receivedRingT] = 0; 06418 } 06419 receivedRingT = 0; 06420 if (option_verbose > 2) 06421 ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n"); 06422 for (;;) { 06423 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06424 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06425 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06426 callerid_free(cs); 06427 ast_hangup(chan); 06428 return NULL; 06429 } 06430 if (i & ZT_IOMUX_SIGEVENT) { 06431 res = zt_get_event(p->subs[index].zfd); 06432 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06433 res = 0; 06434 /* Let us detect callerid when the telco uses distinctive ring */ 06435 06436 curRingData[receivedRingT] = p->ringt; 06437 06438 if (p->ringt < p->ringt_base/2) 06439 break; 06440 /* Increment the ringT counter so we can match it against 06441 values in zapata.conf for distinctive ring */ 06442 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06443 break; 06444 } else if (i & ZT_IOMUX_READ) { 06445 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06446 if (res < 0) { 06447 if (errno != ELAST) { 06448 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06449 callerid_free(cs); 06450 ast_hangup(chan); 06451 return NULL; 06452 } 06453 break; 06454 } 06455 if (p->ringt) 06456 p->ringt--; 06457 if (p->ringt == 1) { 06458 res = -1; 06459 break; 06460 } 06461 } 06462 } 06463 } 06464 if (p->usedistinctiveringdetection == 1) { 06465 if (option_verbose > 2) 06466 /* this only shows up if you have n of the dring patterns filled in */ 06467 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06468 06469 for (counter = 0; counter < 3; counter++) { 06470 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06471 channel */ 06472 if (option_verbose > 2) 06473 /* this only shows up if you have n of the dring patterns filled in */ 06474 ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n", 06475 p->drings.ringnum[counter].ring[0], 06476 p->drings.ringnum[counter].ring[1], 06477 p->drings.ringnum[counter].ring[2]); 06478 distMatches = 0; 06479 for (counter1 = 0; counter1 < 3; counter1++) { 06480 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06481 (p->drings.ringnum[counter].ring[counter1]-10)) { 06482 distMatches++; 06483 } 06484 } 06485 if (distMatches == 3) { 06486 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06487 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06488 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06489 if (option_verbose > 2) 06490 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06491 break; 06492 } 06493 } 06494 } 06495 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06496 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06497 #if 1 06498 restore_gains(p); 06499 #endif 06500 if (res < 0) { 06501 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06502 } 06503 } else 06504 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06505 } 06506 else 06507 cs = NULL; 06508 06509 if (number) 06510 ast_shrink_phone_number(number); 06511 ast_set_callerid(chan, number, name, number); 06512 06513 if (smdi_msg) 06514 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 06515 06516 if (cs) 06517 callerid_free(cs); 06518 06519 ast_setstate(chan, AST_STATE_RING); 06520 chan->rings = 1; 06521 p->ringt = p->ringt_base; 06522 res = ast_pbx_run(chan); 06523 if (res) { 06524 ast_hangup(chan); 06525 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06526 } 06527 return NULL; 06528 default: 06529 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 06530 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06531 if (res < 0) 06532 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06533 } 06534 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06535 if (res < 0) 06536 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06537 ast_hangup(chan); 06538 return NULL; 06539 }
static void swap_subs | ( | struct zt_pvt * | p, | |
int | a, | |||
int | b | |||
) | [static] |
Definition at line 843 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().
00844 { 00845 int tchan; 00846 int tinthreeway; 00847 struct ast_channel *towner; 00848 00849 ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b); 00850 00851 tchan = p->subs[a].chan; 00852 towner = p->subs[a].owner; 00853 tinthreeway = p->subs[a].inthreeway; 00854 00855 p->subs[a].chan = p->subs[b].chan; 00856 p->subs[a].owner = p->subs[b].owner; 00857 p->subs[a].inthreeway = p->subs[b].inthreeway; 00858 00859 p->subs[b].chan = tchan; 00860 p->subs[b].owner = towner; 00861 p->subs[b].inthreeway = tinthreeway; 00862 00863 if (p->subs[a].owner) 00864 p->subs[a].owner->fds[0] = p->subs[a].zfd; 00865 if (p->subs[b].owner) 00866 p->subs[b].owner->fds[0] = p->subs[b].zfd; 00867 wakeup_sub(p, a, NULL); 00868 wakeup_sub(p, b, NULL); 00869 }
static int unalloc_sub | ( | struct zt_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 963 of file chan_zap.c.
References ast_log(), zt_subchannel::chan, zt_pvt::channel, 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().
00964 { 00965 if (!x) { 00966 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel); 00967 return -1; 00968 } 00969 ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel); 00970 if (p->subs[x].zfd > -1) { 00971 zt_close(p->subs[x].zfd); 00972 } 00973 p->subs[x].zfd = -1; 00974 p->subs[x].linear = 0; 00975 p->subs[x].chan = 0; 00976 p->subs[x].owner = NULL; 00977 p->subs[x].inthreeway = 0; 00978 p->polarity = POLARITY_IDLE; 00979 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf)); 00980 return 0; 00981 }
static int unload_module | ( | void | ) | [static] |
Definition at line 10378 of file chan_zap.c.
References __unload_module(), ast_mutex_destroy(), and lock.
10379 { 10380 #ifdef HAVE_PRI 10381 int y; 10382 for (y = 0; y < NUM_SPANS; y++) 10383 ast_mutex_destroy(&pris[y].lock); 10384 #endif 10385 return __unload_module(); 10386 }
static int update_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1349 of file chan_zap.c.
References ast_log(), zt_pvt::channel, conf_add(), conf_del(), zt_pvt::confno, GET_CHANNEL, zt_pvt::inconference, zt_subchannel::inthreeway, isslavenative(), LOG_DEBUG, zt_pvt::master, MAX_SLAVES, option_debug, zt_pvt::slaves, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), mkintf(), zt_bridge(), zt_fixup(), zt_handle_event(), zt_hangup(), and zt_unlink().
01350 { 01351 int needconf = 0; 01352 int x; 01353 int useslavenative; 01354 struct zt_pvt *slave = NULL; 01355 01356 useslavenative = isslavenative(p, &slave); 01357 /* Start with the obvious, general stuff */ 01358 for (x = 0; x < 3; x++) { 01359 /* Look for three way calls */ 01360 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) { 01361 conf_add(p, &p->subs[x], x, 0); 01362 needconf++; 01363 } else { 01364 conf_del(p, &p->subs[x], x); 01365 } 01366 } 01367 /* If we have a slave, add him to our conference now. or DAX 01368 if this is slave native */ 01369 for (x = 0; x < MAX_SLAVES; x++) { 01370 if (p->slaves[x]) { 01371 if (useslavenative) 01372 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 01373 else { 01374 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 01375 needconf++; 01376 } 01377 } 01378 } 01379 /* If we're supposed to be in there, do so now */ 01380 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 01381 if (useslavenative) 01382 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 01383 else { 01384 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 01385 needconf++; 01386 } 01387 } 01388 /* If we have a master, add ourselves to his conference */ 01389 if (p->master) { 01390 if (isslavenative(p->master, NULL)) { 01391 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 01392 } else { 01393 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 01394 } 01395 } 01396 if (!needconf) { 01397 /* Nobody is left (or should be left) in our conference. 01398 Kill it. */ 01399 p->confno = -1; 01400 } 01401 if (option_debug) 01402 ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 01403 return 0; 01404 }
static void wakeup_sub | ( | struct zt_pvt * | p, | |
int | a, | |||
void * | pri | |||
) | [static] |
Definition at line 783 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_null_frame, ast_queue_frame(), zt_pvt::lock, ast_channel::lock, zt_subchannel::owner, and zt_pvt::subs.
Referenced by swap_subs().
00785 { 00786 #ifdef HAVE_PRI 00787 if (pri) 00788 ast_mutex_unlock(&pri->lock); 00789 #endif 00790 for (;;) { 00791 if (p->subs[a].owner) { 00792 if (ast_mutex_trylock(&p->subs[a].owner->lock)) { 00793 ast_mutex_unlock(&p->lock); 00794 usleep(1); 00795 ast_mutex_lock(&p->lock); 00796 } else { 00797 ast_queue_frame(p->subs[a].owner, &ast_null_frame); 00798 ast_mutex_unlock(&p->subs[a].owner->lock); 00799 break; 00800 } 00801 } else 00802 break; 00803 } 00804 #ifdef HAVE_PRI 00805 if (pri) 00806 ast_mutex_lock(&pri->lock); 00807 #endif 00808 }
static int zap_destroy_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9740 of file chan_zap.c.
References RESULT_SHOWUSAGE, and zap_destroy_channel_bynum().
09741 { 09742 int channel; 09743 09744 if (argc != 4) 09745 return RESULT_SHOWUSAGE; 09746 09747 channel = atoi(argv[3]); 09748 09749 return zap_destroy_channel_bynum(channel); 09750 }
static int zap_destroy_channel_bynum | ( | int | channel | ) | [static] |
Definition at line 6542 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().
06543 { 06544 struct zt_pvt *tmp = NULL; 06545 struct zt_pvt *prev = NULL; 06546 06547 tmp = iflist; 06548 while (tmp) { 06549 if (tmp->channel == channel) { 06550 destroy_channel(prev, tmp, 1); 06551 return RESULT_SUCCESS; 06552 } 06553 prev = tmp; 06554 tmp = tmp->next; 06555 } 06556 return RESULT_FAILURE; 06557 }
static int zap_fake_event | ( | struct zt_pvt * | p, | |
int | mode | |||
) | [static] |
Definition at line 10128 of file chan_zap.c.
References ast_log(), zt_pvt::fake_event, HANGUP, LOG_WARNING, zt_pvt::owner, and TRANSFER.
Referenced by action_transfer(), and action_transferhangup().
10129 { 10130 if (p) { 10131 switch (mode) { 10132 case TRANSFER: 10133 p->fake_event = ZT_EVENT_WINKFLASH; 10134 break; 10135 case HANGUP: 10136 p->fake_event = ZT_EVENT_ONHOOK; 10137 break; 10138 default: 10139 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name); 10140 } 10141 } 10142 return 0; 10143 }
Definition at line 813 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), zt_pvt::lock, ast_channel::lock, and zt_pvt::owner.
Referenced by action_zapdialoffhook().
00815 { 00816 /* We must unlock the PRI to avoid the possibility of a deadlock */ 00817 #ifdef HAVE_PRI 00818 if (pri) 00819 ast_mutex_unlock(&pri->lock); 00820 #endif 00821 for (;;) { 00822 if (p->owner) { 00823 if (ast_mutex_trylock(&p->owner->lock)) { 00824 ast_mutex_unlock(&p->lock); 00825 usleep(1); 00826 ast_mutex_lock(&p->lock); 00827 } else { 00828 ast_queue_frame(p->owner, f); 00829 ast_mutex_unlock(&p->owner->lock); 00830 break; 00831 } 00832 } else 00833 break; 00834 } 00835 #ifdef HAVE_PRI 00836 if (pri) 00837 ast_mutex_lock(&pri->lock); 00838 #endif 00839 }
static int zap_restart | ( | void | ) | [static] |
Definition at line 9753 of file chan_zap.c.
References ast_log(), ast_verbose(), destroy_channel(), iflist, LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, setup_zap(), and VERBOSE_PREFIX_1.
Referenced by action_zaprestart(), and zap_restart_cmd().
09754 { 09755 if (option_verbose > 0) 09756 ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n"); 09757 while (iflist) { 09758 if (option_debug) 09759 ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel); 09760 /* Also updates iflist: */ 09761 destroy_channel(NULL, iflist, 1); 09762 } 09763 if (option_debug) 09764 ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n"); 09765 if (setup_zap(0) != 0) { 09766 ast_log(LOG_WARNING, "Reload channels from zap config failed!\n"); 09767 return 1; 09768 } 09769 return 0; 09770 }
static int zap_restart_cmd | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9772 of file chan_zap.c.
References RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and zap_restart().
09773 { 09774 if (argc != 2) { 09775 return RESULT_SHOWUSAGE; 09776 } 09777 09778 if (zap_restart() != 0) 09779 return RESULT_FAILURE; 09780 return RESULT_SUCCESS; 09781 }
static int zap_show_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9854 of file chan_zap.c.
References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::callwaitcas, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, zt_pvt::destroy, zt_pvt::dialing, zt_pvt::dsp, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echocanon, zt_pvt::exten, zt_pvt::faxhandled, iflist, zt_pvt::inalarm, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::law, zt_subchannel::linear, lock, LOG_WARNING, zt_pvt::master, MAX_SLAVES, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::propconfno, zt_pvt::pulsedial, zt_pvt::radio, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, zt_pvt::sig, sig2str, zt_pvt::slaves, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.
09855 { 09856 int channel; 09857 struct zt_pvt *tmp = NULL; 09858 ZT_CONFINFO ci; 09859 ZT_PARAMS ps; 09860 int x; 09861 ast_mutex_t *lock; 09862 struct zt_pvt *start; 09863 #ifdef HAVE_PRI 09864 char *c; 09865 int trunkgroup; 09866 struct zt_pri *pri=NULL; 09867 #endif 09868 09869 lock = &iflock; 09870 start = iflist; 09871 09872 if (argc != 4) 09873 return RESULT_SHOWUSAGE; 09874 #ifdef HAVE_PRI 09875 if ((c = strchr(argv[3], ':'))) { 09876 if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2) 09877 return RESULT_SHOWUSAGE; 09878 if ((trunkgroup < 1) || (channel < 1)) 09879 return RESULT_SHOWUSAGE; 09880 for (x = 0; x < NUM_SPANS; x++) { 09881 if (pris[x].trunkgroup == trunkgroup) { 09882 pri = pris + x; 09883 break; 09884 } 09885 } 09886 if (pri) { 09887 start = pri->crvs; 09888 lock = &pri->lock; 09889 } else { 09890 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 09891 return RESULT_FAILURE; 09892 } 09893 } else 09894 #endif 09895 channel = atoi(argv[3]); 09896 09897 ast_mutex_lock(lock); 09898 tmp = start; 09899 while (tmp) { 09900 if (tmp->channel == channel) { 09901 #ifdef HAVE_PRI 09902 if (pri) 09903 ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel); 09904 else 09905 #endif 09906 ast_cli(fd, "Channel: %d\n", tmp->channel); 09907 ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd); 09908 ast_cli(fd, "Span: %d\n", tmp->span); 09909 ast_cli(fd, "Extension: %s\n", tmp->exten); 09910 ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 09911 ast_cli(fd, "Context: %s\n", tmp->context); 09912 ast_cli(fd, "Caller ID: %s\n", tmp->cid_num); 09913 ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton); 09914 ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name); 09915 ast_cli(fd, "Destroy: %d\n", tmp->destroy); 09916 ast_cli(fd, "InAlarm: %d\n", tmp->inalarm); 09917 ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 09918 ast_cli(fd, "Radio: %d\n", tmp->radio); 09919 ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>"); 09920 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)" : ""); 09921 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)" : ""); 09922 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)" : ""); 09923 ast_cli(fd, "Confno: %d\n", tmp->confno); 09924 ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno); 09925 ast_cli(fd, "Real in conference: %d\n", tmp->inconference); 09926 ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 09927 ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 09928 ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 09929 ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown"); 09930 ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 09931 ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 09932 ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF"); 09933 if (tmp->master) 09934 ast_cli(fd, "Master Channel: %d\n", tmp->master->channel); 09935 for (x = 0; x < MAX_SLAVES; x++) { 09936 if (tmp->slaves[x]) 09937 ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 09938 } 09939 #ifdef HAVE_PRI 09940 if (tmp->pri) { 09941 ast_cli(fd, "PRI Flags: "); 09942 if (tmp->resetting) 09943 ast_cli(fd, "Resetting "); 09944 if (tmp->call) 09945 ast_cli(fd, "Call "); 09946 if (tmp->bearer) 09947 ast_cli(fd, "Bearer "); 09948 ast_cli(fd, "\n"); 09949 if (tmp->logicalspan) 09950 ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan); 09951 else 09952 ast_cli(fd, "PRI Logical Span: Implicit\n"); 09953 } 09954 09955 #endif 09956 memset(&ci, 0, sizeof(ci)); 09957 ps.channo = tmp->channel; 09958 if (tmp->subs[SUB_REAL].zfd > -1) { 09959 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 09960 ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 09961 } 09962 #ifdef ZT_GETCONFMUTE 09963 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) { 09964 ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 09965 } 09966 #endif 09967 if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 09968 ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel); 09969 } else { 09970 ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 09971 } 09972 } 09973 ast_mutex_unlock(lock); 09974 return RESULT_SUCCESS; 09975 } 09976 tmp = tmp->next; 09977 } 09978 09979 ast_cli(fd, "Unable to find given channel %d\n", channel); 09980 ast_mutex_unlock(lock); 09981 return RESULT_FAILURE; 09982 }
static int zap_show_channels | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 9793 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.
09794 { 09795 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 09796 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 09797 struct zt_pvt *tmp = NULL; 09798 char tmps[20] = ""; 09799 ast_mutex_t *lock; 09800 struct zt_pvt *start; 09801 #ifdef HAVE_PRI 09802 int trunkgroup; 09803 struct zt_pri *pri = NULL; 09804 int x; 09805 #endif 09806 09807 lock = &iflock; 09808 start = iflist; 09809 09810 #ifdef HAVE_PRI 09811 if (argc == 4) { 09812 if ((trunkgroup = atoi(argv[3])) < 1) 09813 return RESULT_SHOWUSAGE; 09814 for (x = 0; x < NUM_SPANS; x++) { 09815 if (pris[x].trunkgroup == trunkgroup) { 09816 pri = pris + x; 09817 break; 09818 } 09819 } 09820 if (pri) { 09821 start = pri->crvs; 09822 lock = &pri->lock; 09823 } else { 09824 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 09825 return RESULT_FAILURE; 09826 } 09827 } else 09828 #endif 09829 if (argc != 3) 09830 return RESULT_SHOWUSAGE; 09831 09832 ast_mutex_lock(lock); 09833 #ifdef HAVE_PRI 09834 ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret"); 09835 #else 09836 ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret"); 09837 #endif 09838 09839 tmp = start; 09840 while (tmp) { 09841 if (tmp->channel > 0) { 09842 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 09843 } else 09844 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 09845 ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret); 09846 tmp = tmp->next; 09847 } 09848 ast_mutex_unlock(lock); 09849 return RESULT_SUCCESS; 09850 #undef FORMAT 09851 #undef FORMAT2 09852 }
static int zap_show_status | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10015 of file chan_zap.c.
References alarms, ast_cli(), ast_log(), FORMAT, FORMAT2, LOG_WARNING, RESULT_FAILURE, and RESULT_SUCCESS.
10015 { 10016 #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" 10017 #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" 10018 10019 int span; 10020 int res; 10021 char alarms[50]; 10022 10023 int ctl; 10024 ZT_SPANINFO s; 10025 10026 ctl = open("/dev/zap/ctl", O_RDWR); 10027 if (ctl < 0) { 10028 ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno)); 10029 ast_cli(fd, "No Zaptel interface found.\n"); 10030 return RESULT_FAILURE; 10031 } 10032 ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4"); 10033 10034 for (span = 1; span < ZT_MAX_SPANS; ++span) { 10035 s.spanno = span; 10036 res = ioctl(ctl, ZT_SPANSTAT, &s); 10037 if (res) { 10038 continue; 10039 } 10040 alarms[0] = '\0'; 10041 if (s.alarms > 0) { 10042 if (s.alarms & ZT_ALARM_BLUE) 10043 strcat(alarms, "BLU/"); 10044 if (s.alarms & ZT_ALARM_YELLOW) 10045 strcat(alarms, "YEL/"); 10046 if (s.alarms & ZT_ALARM_RED) 10047 strcat(alarms, "RED/"); 10048 if (s.alarms & ZT_ALARM_LOOPBACK) 10049 strcat(alarms, "LB/"); 10050 if (s.alarms & ZT_ALARM_RECOVER) 10051 strcat(alarms, "REC/"); 10052 if (s.alarms & ZT_ALARM_NOTOPEN) 10053 strcat(alarms, "NOP/"); 10054 if (!strlen(alarms)) 10055 strcat(alarms, "UUU/"); 10056 if (strlen(alarms)) { 10057 /* Strip trailing / */ 10058 alarms[strlen(alarms) - 1] = '\0'; 10059 } 10060 } else { 10061 if (s.numchans) 10062 strcpy(alarms, "OK"); 10063 else 10064 strcpy(alarms, "UNCONFIGURED"); 10065 } 10066 10067 ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count); 10068 } 10069 close(ctl); 10070 10071 return RESULT_SUCCESS; 10072 #undef FORMAT 10073 #undef FORMAT2 10074 }
static char* zap_sig2str | ( | int | sig | ) | [static] |
Definition at line 1159 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.
01160 { 01161 static char buf[256]; 01162 switch (sig) { 01163 case SIG_EM: 01164 return "E & M Immediate"; 01165 case SIG_EMWINK: 01166 return "E & M Wink"; 01167 case SIG_EM_E1: 01168 return "E & M E1"; 01169 case SIG_FEATD: 01170 return "Feature Group D (DTMF)"; 01171 case SIG_FEATDMF: 01172 return "Feature Group D (MF)"; 01173 case SIG_FEATDMF_TA: 01174 return "Feature Groud D (MF) Tandem Access"; 01175 case SIG_FEATB: 01176 return "Feature Group B (MF)"; 01177 case SIG_E911: 01178 return "E911 (MF)"; 01179 case SIG_FGC_CAMA: 01180 return "FGC/CAMA (Dialpulse)"; 01181 case SIG_FGC_CAMAMF: 01182 return "FGC/CAMA (MF)"; 01183 case SIG_FXSLS: 01184 return "FXS Loopstart"; 01185 case SIG_FXSGS: 01186 return "FXS Groundstart"; 01187 case SIG_FXSKS: 01188 return "FXS Kewlstart"; 01189 case SIG_FXOLS: 01190 return "FXO Loopstart"; 01191 case SIG_FXOGS: 01192 return "FXO Groundstart"; 01193 case SIG_FXOKS: 01194 return "FXO Kewlstart"; 01195 case SIG_PRI: 01196 return "PRI Signalling"; 01197 case SIG_SF: 01198 return "SF (Tone) Signalling Immediate"; 01199 case SIG_SFWINK: 01200 return "SF (Tone) Signalling Wink"; 01201 case SIG_SF_FEATD: 01202 return "SF (Tone) Signalling with Feature Group D (DTMF)"; 01203 case SIG_SF_FEATDMF: 01204 return "SF (Tone) Signalling with Feature Group D (MF)"; 01205 case SIG_SF_FEATB: 01206 return "SF (Tone) Signalling with Feature Group B (MF)"; 01207 case SIG_GR303FXOKS: 01208 return "GR-303 Signalling with FXOKS"; 01209 case SIG_GR303FXSKS: 01210 return "GR-303 Signalling with FXSKS"; 01211 case 0: 01212 return "Pseudo Signalling"; 01213 default: 01214 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig); 01215 return buf; 01216 } 01217 }
static int zt_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2732 of file chan_zap.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::channel, zt_pvt::dialing, zt_pvt::digital, zt_pvt::hanguponpolarityswitch, zt_subchannel::inthreeway, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::oprmode, zt_subchannel::owner, zt_pvt::owner, zt_pvt::polaritydelaytv, zt_pvt::radio, zt_pvt::ringt, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::span, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_subchannel::zfd, zt_enable_ec(), zt_get_index(), zt_set_hook(), and zt_train_ec().
02733 { 02734 struct zt_pvt *p = ast->tech_pvt; 02735 int res = 0; 02736 int index; 02737 int oldstate = ast->_state; 02738 ast_setstate(ast, AST_STATE_UP); 02739 ast_mutex_lock(&p->lock); 02740 index = zt_get_index(ast, p, 0); 02741 if (index < 0) 02742 index = SUB_REAL; 02743 /* nothing to do if a radio channel */ 02744 if ((p->radio || (p->oprmode < 0))) { 02745 ast_mutex_unlock(&p->lock); 02746 return 0; 02747 } 02748 switch (p->sig) { 02749 case SIG_FXSLS: 02750 case SIG_FXSGS: 02751 case SIG_FXSKS: 02752 p->ringt = 0; 02753 /* Fall through */ 02754 case SIG_EM: 02755 case SIG_EM_E1: 02756 case SIG_EMWINK: 02757 case SIG_FEATD: 02758 case SIG_FEATDMF: 02759 case SIG_FEATDMF_TA: 02760 case SIG_E911: 02761 case SIG_FGC_CAMA: 02762 case SIG_FGC_CAMAMF: 02763 case SIG_FEATB: 02764 case SIG_SF: 02765 case SIG_SFWINK: 02766 case SIG_SF_FEATD: 02767 case SIG_SF_FEATDMF: 02768 case SIG_SF_FEATB: 02769 case SIG_FXOLS: 02770 case SIG_FXOGS: 02771 case SIG_FXOKS: 02772 /* Pick up the line */ 02773 ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name); 02774 if (p->hanguponpolarityswitch) { 02775 gettimeofday(&p->polaritydelaytv, NULL); 02776 } 02777 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 02778 tone_zone_play_tone(p->subs[index].zfd, -1); 02779 p->dialing = 0; 02780 if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) { 02781 if (oldstate == AST_STATE_RINGING) { 02782 ast_log(LOG_DEBUG, "Finally swapping real and threeway\n"); 02783 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1); 02784 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02785 p->owner = p->subs[SUB_REAL].owner; 02786 } 02787 } 02788 if (p->sig & __ZT_SIG_FXS) { 02789 zt_enable_ec(p); 02790 zt_train_ec(p); 02791 } 02792 break; 02793 #ifdef HAVE_PRI 02794 case SIG_PRI: 02795 /* Send a pri acknowledge */ 02796 if (!pri_grab(p, p->pri)) { 02797 p->proceeding = 1; 02798 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 02799 pri_rel(p->pri); 02800 } else { 02801 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02802 res = -1; 02803 } 02804 break; 02805 #endif 02806 case 0: 02807 ast_mutex_unlock(&p->lock); 02808 return 0; 02809 default: 02810 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 02811 res = -1; 02812 } 02813 ast_mutex_unlock(&p->lock); 02814 return res; 02815 }
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 3141 of file chan_zap.c.
References ast_channel::_state, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_read(), AST_STATE_RINGING, ast_verbose(), ast_waitfor_n(), ast_write(), zt_pvt::channel, disable_dtmf_detect(), zt_pvt::echocanbridged, enable_dtmf_detect(), ast_channel::fds, ast_frame::frametype, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, master, option_verbose, zt_subchannel::owner, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::sig, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, ast_channel::tech_pvt, zt_pvt::transfer, update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_index(), zt_link(), and zt_unlink().
03142 { 03143 struct ast_channel *who; 03144 struct zt_pvt *p0, *p1, *op0, *op1; 03145 struct zt_pvt *master = NULL, *slave = NULL; 03146 struct ast_frame *f; 03147 int inconf = 0; 03148 int nothingok = 1; 03149 int ofd0, ofd1; 03150 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 03151 int os0 = -1, os1 = -1; 03152 int priority = 0; 03153 struct ast_channel *oc0, *oc1; 03154 enum ast_bridge_result res; 03155 03156 #ifdef PRI_2BCT 03157 int triedtopribridge = 0; 03158 q931_call *q931c0 = NULL, *q931c1 = NULL; 03159 #endif 03160 03161 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 03162 There is code below to handle it properly until DTMF is actually seen, 03163 but due to currently unresolved issues it's ignored... 03164 */ 03165 03166 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 03167 return AST_BRIDGE_FAILED_NOWARN; 03168 03169 ast_mutex_lock(&c0->lock); 03170 ast_mutex_lock(&c1->lock); 03171 03172 p0 = c0->tech_pvt; 03173 p1 = c1->tech_pvt; 03174 /* cant do pseudo-channels here */ 03175 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 03176 ast_mutex_unlock(&c0->lock); 03177 ast_mutex_unlock(&c1->lock); 03178 return AST_BRIDGE_FAILED_NOWARN; 03179 } 03180 03181 oi0 = zt_get_index(c0, p0, 0); 03182 oi1 = zt_get_index(c1, p1, 0); 03183 if ((oi0 < 0) || (oi1 < 0)) { 03184 ast_mutex_unlock(&c0->lock); 03185 ast_mutex_unlock(&c1->lock); 03186 return AST_BRIDGE_FAILED; 03187 } 03188 03189 op0 = p0 = c0->tech_pvt; 03190 op1 = p1 = c1->tech_pvt; 03191 ofd0 = c0->fds[0]; 03192 ofd1 = c1->fds[0]; 03193 oc0 = p0->owner; 03194 oc1 = p1->owner; 03195 03196 if (ast_mutex_trylock(&p0->lock)) { 03197 /* Don't block, due to potential for deadlock */ 03198 ast_mutex_unlock(&c0->lock); 03199 ast_mutex_unlock(&c1->lock); 03200 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03201 return AST_BRIDGE_RETRY; 03202 } 03203 if (ast_mutex_trylock(&p1->lock)) { 03204 /* Don't block, due to potential for deadlock */ 03205 ast_mutex_unlock(&p0->lock); 03206 ast_mutex_unlock(&c0->lock); 03207 ast_mutex_unlock(&c1->lock); 03208 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03209 return AST_BRIDGE_RETRY; 03210 } 03211 03212 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03213 if (p0->owner && p1->owner) { 03214 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 03215 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 03216 master = p0; 03217 slave = p1; 03218 inconf = 1; 03219 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 03220 master = p1; 03221 slave = p0; 03222 inconf = 1; 03223 } else { 03224 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 03225 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 03226 p0->channel, 03227 oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03228 p0->subs[SUB_REAL].inthreeway, p0->channel, 03229 oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03230 p1->subs[SUB_REAL].inthreeway); 03231 } 03232 nothingok = 0; 03233 } 03234 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 03235 if (p1->subs[SUB_THREEWAY].inthreeway) { 03236 master = p1; 03237 slave = p0; 03238 nothingok = 0; 03239 } 03240 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 03241 if (p0->subs[SUB_THREEWAY].inthreeway) { 03242 master = p0; 03243 slave = p1; 03244 nothingok = 0; 03245 } 03246 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 03247 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 03248 don't put us in anything */ 03249 if (p1->subs[SUB_CALLWAIT].inthreeway) { 03250 master = p1; 03251 slave = p0; 03252 nothingok = 0; 03253 } 03254 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 03255 /* Same as previous */ 03256 if (p0->subs[SUB_CALLWAIT].inthreeway) { 03257 master = p0; 03258 slave = p1; 03259 nothingok = 0; 03260 } 03261 } 03262 ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n", 03263 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 03264 if (master && slave) { 03265 /* Stop any tones, or play ringtone as appropriate. If they're bridged 03266 in an active threeway call with a channel that is ringing, we should 03267 indicate ringing. */ 03268 if ((oi1 == SUB_THREEWAY) && 03269 p1->subs[SUB_THREEWAY].inthreeway && 03270 p1->subs[SUB_REAL].owner && 03271 p1->subs[SUB_REAL].inthreeway && 03272 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03273 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name); 03274 tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE); 03275 os1 = p1->subs[SUB_REAL].owner->_state; 03276 } else { 03277 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1); 03278 tone_zone_play_tone(p0->subs[oi0].zfd, -1); 03279 } 03280 if ((oi0 == SUB_THREEWAY) && 03281 p0->subs[SUB_THREEWAY].inthreeway && 03282 p0->subs[SUB_REAL].owner && 03283 p0->subs[SUB_REAL].inthreeway && 03284 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03285 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name); 03286 tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE); 03287 os0 = p0->subs[SUB_REAL].owner->_state; 03288 } else { 03289 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0); 03290 tone_zone_play_tone(p1->subs[oi0].zfd, -1); 03291 } 03292 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03293 if (!p0->echocanbridged || !p1->echocanbridged) { 03294 /* Disable echo cancellation if appropriate */ 03295 zt_disable_ec(p0); 03296 zt_disable_ec(p1); 03297 } 03298 } 03299 zt_link(slave, master); 03300 master->inconference = inconf; 03301 } else if (!nothingok) 03302 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 03303 03304 update_conf(p0); 03305 update_conf(p1); 03306 t0 = p0->subs[SUB_REAL].inthreeway; 03307 t1 = p1->subs[SUB_REAL].inthreeway; 03308 03309 ast_mutex_unlock(&p0->lock); 03310 ast_mutex_unlock(&p1->lock); 03311 03312 ast_mutex_unlock(&c0->lock); 03313 ast_mutex_unlock(&c1->lock); 03314 03315 /* Native bridge failed */ 03316 if ((!master || !slave) && !nothingok) { 03317 zt_enable_ec(p0); 03318 zt_enable_ec(p1); 03319 return AST_BRIDGE_FAILED; 03320 } 03321 03322 if (option_verbose > 2) 03323 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 03324 03325 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03326 disable_dtmf_detect(op0); 03327 03328 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03329 disable_dtmf_detect(op1); 03330 03331 for (;;) { 03332 struct ast_channel *c0_priority[2] = {c0, c1}; 03333 struct ast_channel *c1_priority[2] = {c1, c0}; 03334 03335 /* Here's our main loop... Start by locking things, looking for private parts, 03336 and then balking if anything is wrong */ 03337 ast_mutex_lock(&c0->lock); 03338 ast_mutex_lock(&c1->lock); 03339 p0 = c0->tech_pvt; 03340 p1 = c1->tech_pvt; 03341 03342 if (op0 == p0) 03343 i0 = zt_get_index(c0, p0, 1); 03344 if (op1 == p1) 03345 i1 = zt_get_index(c1, p1, 1); 03346 ast_mutex_unlock(&c0->lock); 03347 ast_mutex_unlock(&c1->lock); 03348 03349 if (!timeoutms || 03350 (op0 != p0) || 03351 (op1 != p1) || 03352 (ofd0 != c0->fds[0]) || 03353 (ofd1 != c1->fds[0]) || 03354 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 03355 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 03356 (oc0 != p0->owner) || 03357 (oc1 != p1->owner) || 03358 (t0 != p0->subs[SUB_REAL].inthreeway) || 03359 (t1 != p1->subs[SUB_REAL].inthreeway) || 03360 (oi0 != i0) || 03361 (oi1 != i1)) { 03362 ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 03363 op0->channel, oi0, op1->channel, oi1); 03364 res = AST_BRIDGE_RETRY; 03365 goto return_from_bridge; 03366 } 03367 03368 #ifdef PRI_2BCT 03369 q931c0 = p0->call; 03370 q931c1 = p1->call; 03371 if (p0->transfer && p1->transfer 03372 && q931c0 && q931c1 03373 && !triedtopribridge) { 03374 pri_channel_bridge(q931c0, q931c1); 03375 triedtopribridge = 1; 03376 } 03377 #endif 03378 03379 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms); 03380 if (!who) { 03381 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 03382 continue; 03383 } 03384 f = ast_read(who); 03385 if (!f || (f->frametype == AST_FRAME_CONTROL)) { 03386 *fo = f; 03387 *rc = who; 03388 res = AST_BRIDGE_COMPLETE; 03389 goto return_from_bridge; 03390 } 03391 if (f->frametype == AST_FRAME_DTMF) { 03392 if ((who == c0) && p0->pulsedial) { 03393 ast_write(c1, f); 03394 } else if ((who == c1) && p1->pulsedial) { 03395 ast_write(c0, f); 03396 } else { 03397 *fo = f; 03398 *rc = who; 03399 res = AST_BRIDGE_COMPLETE; 03400 goto return_from_bridge; 03401 } 03402 } 03403 ast_frfree(f); 03404 03405 /* Swap who gets priority */ 03406 priority = !priority; 03407 } 03408 03409 return_from_bridge: 03410 if (op0 == p0) 03411 zt_enable_ec(p0); 03412 03413 if (op1 == p1) 03414 zt_enable_ec(p1); 03415 03416 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03417 enable_dtmf_detect(op0); 03418 03419 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03420 enable_dtmf_detect(op1); 03421 03422 zt_unlink(slave, master, 1); 03423 03424 return res; 03425 }
static int zt_call | ( | struct ast_channel * | ast, | |
char * | rdest, | |||
int | timeout | |||
) | [static] |
Definition at line 1769 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, 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().
01770 { 01771 struct zt_pvt *p = ast->tech_pvt; 01772 int x, res, index,mysig; 01773 char *c, *n, *l; 01774 #ifdef HAVE_PRI 01775 char *s = NULL; 01776 #endif 01777 char dest[256]; /* must be same length as p->dialdest */ 01778 ast_mutex_lock(&p->lock); 01779 ast_copy_string(dest, rdest, sizeof(dest)); 01780 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 01781 if ((ast->_state == AST_STATE_BUSY)) { 01782 p->subs[SUB_REAL].needbusy = 1; 01783 ast_mutex_unlock(&p->lock); 01784 return 0; 01785 } 01786 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 01787 ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name); 01788 ast_mutex_unlock(&p->lock); 01789 return -1; 01790 } 01791 p->dialednone = 0; 01792 if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */ 01793 { 01794 /* Special pseudo -- automatically up */ 01795 ast_setstate(ast, AST_STATE_UP); 01796 ast_mutex_unlock(&p->lock); 01797 return 0; 01798 } 01799 x = ZT_FLUSH_READ | ZT_FLUSH_WRITE; 01800 res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 01801 if (res) 01802 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel); 01803 p->outgoing = 1; 01804 01805 set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01806 01807 mysig = p->sig; 01808 if (p->outsigmod > -1) 01809 mysig = p->outsigmod; 01810 01811 switch (mysig) { 01812 case SIG_FXOLS: 01813 case SIG_FXOGS: 01814 case SIG_FXOKS: 01815 if (p->owner == ast) { 01816 /* Normal ring, on hook */ 01817 01818 /* Don't send audio while on hook, until the call is answered */ 01819 p->dialing = 1; 01820 if (p->use_callerid) { 01821 /* Generate the Caller-ID spill if desired */ 01822 if (p->cidspill) { 01823 ast_log(LOG_WARNING, "cidspill already exists??\n"); 01824 free(p->cidspill); 01825 } 01826 p->callwaitcas = 0; 01827 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) { 01828 p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p)); 01829 p->cidpos = 0; 01830 send_callerid(p); 01831 } 01832 } 01833 /* Choose proper cadence */ 01834 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) { 01835 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1])) 01836 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name); 01837 p->cidrings = cidrings[p->distinctivering - 1]; 01838 } else { 01839 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL)) 01840 ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name); 01841 p->cidrings = p->sendcalleridafter; 01842 } 01843 01844 /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */ 01845 c = strchr(dest, '/'); 01846 if (c) 01847 c++; 01848 if (c && (strlen(c) < p->stripmsd)) { 01849 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01850 c = NULL; 01851 } 01852 if (c) { 01853 p->dop.op = ZT_DIAL_OP_REPLACE; 01854 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c); 01855 ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c); 01856 } else { 01857 p->dop.dialstr[0] = '\0'; 01858 } 01859 x = ZT_RING; 01860 if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) { 01861 ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno)); 01862 ast_mutex_unlock(&p->lock); 01863 return -1; 01864 } 01865 p->dialing = 1; 01866 } else { 01867 /* Call waiting call */ 01868 p->callwaitrings = 0; 01869 if (ast->cid.cid_num) 01870 ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num)); 01871 else 01872 p->callwait_num[0] = '\0'; 01873 if (ast->cid.cid_name) 01874 ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name)); 01875 else 01876 p->callwait_name[0] = '\0'; 01877 /* Call waiting tone instead */ 01878 if (zt_callwait(ast)) { 01879 ast_mutex_unlock(&p->lock); 01880 return -1; 01881 } 01882 /* Make ring-back */ 01883 if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE)) 01884 ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name); 01885 01886 } 01887 n = ast->cid.cid_name; 01888 l = ast->cid.cid_num; 01889 if (l) 01890 ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num)); 01891 else 01892 p->lastcid_num[0] = '\0'; 01893 if (n) 01894 ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name)); 01895 else 01896 p->lastcid_name[0] = '\0'; 01897 ast_setstate(ast, AST_STATE_RINGING); 01898 index = zt_get_index(ast, p, 0); 01899 if (index > -1) { 01900 p->subs[index].needringing = 1; 01901 } 01902 break; 01903 case SIG_FXSLS: 01904 case SIG_FXSGS: 01905 case SIG_FXSKS: 01906 case SIG_EMWINK: 01907 case SIG_EM: 01908 case SIG_EM_E1: 01909 case SIG_FEATD: 01910 case SIG_FEATDMF: 01911 case SIG_E911: 01912 case SIG_FGC_CAMA: 01913 case SIG_FGC_CAMAMF: 01914 case SIG_FEATB: 01915 case SIG_SFWINK: 01916 case SIG_SF: 01917 case SIG_SF_FEATD: 01918 case SIG_SF_FEATDMF: 01919 case SIG_FEATDMF_TA: 01920 case SIG_SF_FEATB: 01921 c = strchr(dest, '/'); 01922 if (c) 01923 c++; 01924 else 01925 c = ""; 01926 if (strlen(c) < p->stripmsd) { 01927 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01928 ast_mutex_unlock(&p->lock); 01929 return -1; 01930 } 01931 #ifdef HAVE_PRI 01932 /* Start the trunk, if not GR-303 */ 01933 if (!p->pri) { 01934 #endif 01935 x = ZT_START; 01936 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 01937 if (res < 0) { 01938 if (errno != EINPROGRESS) { 01939 ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno)); 01940 ast_mutex_unlock(&p->lock); 01941 return -1; 01942 } 01943 } 01944 #ifdef HAVE_PRI 01945 } 01946 #endif 01947 ast_log(LOG_DEBUG, "Dialing '%s'\n", c); 01948 p->dop.op = ZT_DIAL_OP_REPLACE; 01949 01950 c += p->stripmsd; 01951 01952 switch (mysig) { 01953 case SIG_FEATD: 01954 l = ast->cid.cid_num; 01955 if (l) 01956 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c); 01957 else 01958 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c); 01959 break; 01960 case SIG_FEATDMF: 01961 l = ast->cid.cid_num; 01962 if (l) 01963 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c); 01964 else 01965 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c); 01966 break; 01967 case SIG_FEATDMF_TA: 01968 { 01969 const char *cic, *ozz; 01970 01971 /* If you have to go through a Tandem Access point you need to use this */ 01972 ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ"); 01973 if (!ozz) 01974 ozz = defaultozz; 01975 cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC"); 01976 if (!cic) 01977 cic = defaultcic; 01978 if (!ozz || !cic) { 01979 ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n"); 01980 ast_mutex_unlock(&p->lock); 01981 return -1; 01982 } 01983 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic); 01984 snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c); 01985 p->whichwink = 0; 01986 } 01987 break; 01988 case SIG_E911: 01989 ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr)); 01990 break; 01991 case SIG_FGC_CAMA: 01992 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c); 01993 break; 01994 case SIG_FGC_CAMAMF: 01995 case SIG_FEATB: 01996 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c); 01997 break; 01998 default: 01999 if (p->pulse) 02000 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c); 02001 else 02002 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c); 02003 break; 02004 } 02005 02006 if (p->echotraining && (strlen(p->dop.dialstr) > 4)) { 02007 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 02008 strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 02009 p->echorest[sizeof(p->echorest) - 1] = '\0'; 02010 p->echobreak = 1; 02011 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 02012 } else 02013 p->echobreak = 0; 02014 if (!res) { 02015 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 02016 x = ZT_ONHOOK; 02017 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 02018 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 02019 ast_mutex_unlock(&p->lock); 02020 return -1; 02021 } 02022 } else 02023 ast_log(LOG_DEBUG, "Deferring dialing...\n"); 02024 p->dialing = 1; 02025 if (ast_strlen_zero(c)) 02026 p->dialednone = 1; 02027 ast_setstate(ast, AST_STATE_DIALING); 02028 break; 02029 case 0: 02030 /* Special pseudo -- automatically up*/ 02031 ast_setstate(ast, AST_STATE_UP); 02032 break; 02033 case SIG_PRI: 02034 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ 02035 p->dialdest[0] = '\0'; 02036 break; 02037 default: 02038 ast_log(LOG_DEBUG, "not yet implemented\n"); 02039 ast_mutex_unlock(&p->lock); 02040 return -1; 02041 } 02042 #ifdef HAVE_PRI 02043 if (p->pri) { 02044 struct pri_sr *sr; 02045 #ifdef SUPPORT_USERUSER 02046 const char *useruser; 02047 #endif 02048 int pridialplan; 02049 int dp_strip; 02050 int prilocaldialplan; 02051 int ldp_strip; 02052 int exclusive; 02053 const char *rr_str; 02054 int redirect_reason; 02055 02056 c = strchr(dest, '/'); 02057 if (c) 02058 c++; 02059 else 02060 c = dest; 02061 if (!p->hidecalleridname) 02062 n = ast->cid.cid_name; 02063 else 02064 n = NULL; 02065 if (!p->hidecallerid) { 02066 l = ast->cid.cid_num; 02067 n = ast->cid.cid_name; 02068 } else { 02069 l = NULL; 02070 n = NULL; 02071 } 02072 if (strlen(c) < p->stripmsd) { 02073 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 02074 ast_mutex_unlock(&p->lock); 02075 return -1; 02076 } 02077 if (mysig != SIG_FXSKS) { 02078 p->dop.op = ZT_DIAL_OP_REPLACE; 02079 s = strchr(c + p->stripmsd, 'w'); 02080 if (s) { 02081 if (strlen(s) > 1) 02082 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s); 02083 else 02084 p->dop.dialstr[0] = '\0'; 02085 *s = '\0'; 02086 } else { 02087 p->dop.dialstr[0] = '\0'; 02088 } 02089 } 02090 if (pri_grab(p, p->pri)) { 02091 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 02092 ast_mutex_unlock(&p->lock); 02093 return -1; 02094 } 02095 if (!(p->call = pri_new_call(p->pri->pri))) { 02096 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 02097 pri_rel(p->pri); 02098 ast_mutex_unlock(&p->lock); 02099 return -1; 02100 } 02101 if (!(sr = pri_sr_new())) { 02102 ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); 02103 pri_rel(p->pri); 02104 ast_mutex_unlock(&p->lock); 02105 } 02106 if (p->bearer || (mysig == SIG_FXSKS)) { 02107 if (p->bearer) { 02108 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); 02109 p->bearer->call = p->call; 02110 } else 02111 ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n"); 02112 pri_set_crv(p->pri->pri, p->call, p->channel, 0); 02113 } 02114 p->digital = IS_DIGITAL(ast->transfercapability); 02115 /* Add support for exclusive override */ 02116 if (p->priexclusive) 02117 exclusive = 1; 02118 else { 02119 /* otherwise, traditional behavior */ 02120 if (p->pri->nodetype == PRI_NETWORK) 02121 exclusive = 0; 02122 else 02123 exclusive = 1; 02124 } 02125 02126 pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1); 02127 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 02128 (p->digital ? -1 : 02129 ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW))); 02130 if (p->pri->facilityenable) 02131 pri_facility_enable(p->pri->pri); 02132 02133 if (option_verbose > 2) 02134 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 02135 dp_strip = 0; 02136 pridialplan = p->pri->dialplan - 1; 02137 if (pridialplan == -2) { /* compute dynamically */ 02138 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02139 dp_strip = strlen(p->pri->internationalprefix); 02140 pridialplan = PRI_INTERNATIONAL_ISDN; 02141 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02142 dp_strip = strlen(p->pri->nationalprefix); 02143 pridialplan = PRI_NATIONAL_ISDN; 02144 } else { 02145 pridialplan = PRI_LOCAL_ISDN; 02146 } 02147 } 02148 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 02149 02150 ldp_strip = 0; 02151 prilocaldialplan = p->pri->localdialplan - 1; 02152 if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */ 02153 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02154 ldp_strip = strlen(p->pri->internationalprefix); 02155 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 02156 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02157 ldp_strip = strlen(p->pri->nationalprefix); 02158 prilocaldialplan = PRI_NATIONAL_ISDN; 02159 } else { 02160 prilocaldialplan = PRI_LOCAL_ISDN; 02161 } 02162 } 02163 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 02164 p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 02165 if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) { 02166 if (!strcasecmp(rr_str, "UNKNOWN")) 02167 redirect_reason = 0; 02168 else if (!strcasecmp(rr_str, "BUSY")) 02169 redirect_reason = 1; 02170 else if (!strcasecmp(rr_str, "NO_REPLY")) 02171 redirect_reason = 2; 02172 else if (!strcasecmp(rr_str, "UNCONDITIONAL")) 02173 redirect_reason = 15; 02174 else 02175 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02176 } else 02177 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02178 pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason); 02179 02180 #ifdef SUPPORT_USERUSER 02181 /* User-user info */ 02182 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 02183 02184 if (useruser) 02185 pri_sr_set_useruser(sr, useruser); 02186 #endif 02187 02188 if (pri_setup(p->pri->pri, p->call, sr)) { 02189 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 02190 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 02191 pri_rel(p->pri); 02192 ast_mutex_unlock(&p->lock); 02193 pri_sr_free(sr); 02194 return -1; 02195 } 02196 pri_sr_free(sr); 02197 ast_setstate(ast, AST_STATE_DIALING); 02198 pri_rel(p->pri); 02199 } 02200 #endif 02201 ast_mutex_unlock(&p->lock); 02202 return 0; 02203 }
static int zt_callwait | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 1741 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().
01742 { 01743 struct zt_pvt *p = ast->tech_pvt; 01744 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 01745 if (p->cidspill) { 01746 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 01747 free(p->cidspill); 01748 } 01749 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 01750 return -1; 01751 save_conference(p); 01752 /* Silence */ 01753 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 01754 if (!p->callwaitrings && p->callwaitingcallerid) { 01755 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 01756 p->callwaitcas = 1; 01757 p->cidlen = 2400 + 680 + READ_SIZE * 4; 01758 } else { 01759 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 01760 p->callwaitcas = 0; 01761 p->cidlen = 2400 + READ_SIZE * 4; 01762 } 01763 p->cidpos = 0; 01764 send_callerid(p); 01765 01766 return 0; 01767 }
static struct zt_chan_conf zt_chan_conf_default | ( | void | ) | [static, read] |
returns a new zt_chan_conf with default values (by-value)
Definition at line 599 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().
00599 { 00600 /* recall that if a field is not included here it is initialized 00601 * to 0 or equivalent 00602 */ 00603 struct zt_chan_conf conf = { 00604 #ifdef HAVE_PRI 00605 .pri = { 00606 .nsf = PRI_NSF_NONE, 00607 .switchtype = PRI_SWITCH_NI2, 00608 .dialplan = PRI_NATIONAL_ISDN + 1, 00609 .localdialplan = PRI_NATIONAL_ISDN + 1, 00610 .nodetype = PRI_CPE, 00611 00612 .minunused = 2, 00613 .idleext = "", 00614 .idledial = "", 00615 .internationalprefix = "", 00616 .nationalprefix = "", 00617 .localprefix = "", 00618 .privateprefix = "", 00619 .unknownprefix = "", 00620 00621 .resetinterval = 3600 00622 }, 00623 #endif 00624 .chan = { 00625 .context = "default", 00626 .cid_num = "", 00627 .cid_name = "", 00628 .mohinterpret = "default", 00629 .mohsuggest = "", 00630 .transfertobusy = 1, 00631 00632 .cid_signalling = CID_SIG_BELL, 00633 .cid_start = CID_START_RING, 00634 .zaptrcallerid = 0, 00635 .use_callerid = 1, 00636 .sig = -1, 00637 .outsigmod = -1, 00638 00639 .tonezone = -1, 00640 00641 .echocancel = 1, 00642 00643 .busycount = 3, 00644 00645 .accountcode = "", 00646 00647 .mailbox = "", 00648 00649 00650 .polarityonanswerdelay = 600, 00651 00652 .sendcalleridafter = DEFAULT_CIDRINGS 00653 }, 00654 .timing = { 00655 .prewinktime = -1, 00656 .preflashtime = -1, 00657 .winktime = -1, 00658 .flashtime = -1, 00659 .starttime = -1, 00660 .rxwinktime = -1, 00661 .rxflashtime = -1, 00662 .debouncetime = -1 00663 }, 00664 .smdi_port = "/dev/ttyS0", 00665 }; 00666 00667 return conf; 00668 }
static void zt_close | ( | int | fd | ) | [static] |
Definition at line 912 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 1624 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_WARNING, zt_pvt::sig, SIG_PRI, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_handle_dtmfup(), zt_handle_event(), zt_hangup(), and zt_new().
01625 { 01626 int x, y, res; 01627 x = muted; 01628 if (p->sig == SIG_PRI) { 01629 y = 1; 01630 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y); 01631 if (res) 01632 ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel); 01633 } 01634 res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x); 01635 if (res < 0) 01636 ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno)); 01637 return res; 01638 }
static int zt_digit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 999 of file chan_zap.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DIALING, zt_pvt::begindigit, zt_pvt::dialdest, zt_pvt::dialing, digit_to_dtmfindex(), zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::owner, zt_pvt::pulse, zt_pvt::sig, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, and zt_get_index().
01000 { 01001 struct zt_pvt *pvt; 01002 int index; 01003 int dtmf = -1; 01004 01005 pvt = chan->tech_pvt; 01006 01007 ast_mutex_lock(&pvt->lock); 01008 01009 index = zt_get_index(chan, pvt, 0); 01010 01011 if ((index != SUB_REAL) || !pvt->owner) 01012 goto out; 01013 01014 #ifdef HAVE_PRI 01015 if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) { 01016 if (pvt->setup_ack) { 01017 if (!pri_grab(pvt, pvt->pri)) { 01018 pri_information(pvt->pri->pri, pvt->call, digit); 01019 pri_rel(pvt->pri); 01020 } else 01021 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span); 01022 } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) { 01023 int res; 01024 ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit); 01025 res = strlen(pvt->dialdest); 01026 pvt->dialdest[res++] = digit; 01027 pvt->dialdest[res] = '\0'; 01028 } 01029 goto out; 01030 } 01031 #endif 01032 if ((dtmf = digit_to_dtmfindex(digit)) == -1) 01033 goto out; 01034 01035 if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) { 01036 int res; 01037 ZT_DIAL_OPERATION zo = { 01038 .op = ZT_DIAL_OP_APPEND, 01039 .dialstr[0] = 'T', 01040 .dialstr[1] = digit, 01041 .dialstr[2] = 0, 01042 }; 01043 if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo))) 01044 ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit); 01045 else 01046 pvt->dialing = 1; 01047 } else { 01048 ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit); 01049 pvt->dialing = 1; 01050 pvt->begindigit = digit; 01051 } 01052 01053 out: 01054 ast_mutex_unlock(&pvt->lock); 01055 01056 return 0; 01057 }
static int zt_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 1059 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::begindigit, zt_pvt::dialing, zt_pvt::lock, LOG_DEBUG, zt_pvt::owner, zt_pvt::pulse, zt_pvt::sig, SIG_PRI, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, and zt_get_index().
01060 { 01061 struct zt_pvt *pvt; 01062 int res = 0; 01063 int index; 01064 int x; 01065 01066 pvt = chan->tech_pvt; 01067 01068 ast_mutex_lock(&pvt->lock); 01069 01070 index = zt_get_index(chan, pvt, 0); 01071 01072 if ((index != SUB_REAL) || !pvt->owner || pvt->pulse) 01073 goto out; 01074 01075 #ifdef HAVE_PRI 01076 /* This means that the digit was already sent via PRI signalling */ 01077 if (pvt->sig == SIG_PRI && !pvt->begindigit) 01078 goto out; 01079 #endif 01080 01081 if (pvt->begindigit) { 01082 x = -1; 01083 ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit); 01084 res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x); 01085 pvt->dialing = 0; 01086 pvt->begindigit = 0; 01087 } 01088 01089 out: 01090 ast_mutex_unlock(&pvt->lock); 01091 01092 return res; 01093 }
static void zt_disable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1456 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echocanon, LOG_DEBUG, LOG_WARNING, option_debug, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), handle_init_event(), zt_bridge(), zt_handle_event(), zt_hangup(), and zt_setoption().
01457 { 01458 int x; 01459 int res; 01460 if (p->echocancel) { 01461 x = 0; 01462 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01463 if (res) 01464 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel); 01465 else if (option_debug) 01466 ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel); 01467 } 01468 p->echocanon = 0; 01469 }
static void zt_enable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1406 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::digital, zt_pvt::echocancel, zt_pvt::echocanon, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::sig, SIG_PRI, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by handle_init_event(), ss_thread(), zt_answer(), zt_bridge(), zt_handle_event(), and zt_setoption().
01407 { 01408 int x; 01409 int res; 01410 if (!p) 01411 return; 01412 if (p->echocanon) { 01413 ast_log(LOG_DEBUG, "Echo cancellation already on\n"); 01414 return; 01415 } 01416 if (p->digital) { 01417 ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n"); 01418 return; 01419 } 01420 if (p->echocancel) { 01421 if (p->sig == SIG_PRI) { 01422 x = 1; 01423 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x); 01424 if (res) 01425 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel); 01426 } 01427 x = p->echocancel; 01428 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01429 if (res) 01430 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel); 01431 else { 01432 p->echocanon = 1; 01433 if (option_debug) 01434 ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel); 01435 } 01436 } else if (option_debug) 01437 ast_log(LOG_DEBUG, "No echo cancellation requested\n"); 01438 }
static struct ast_frame * zt_exception | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 4593 of file chan_zap.c.
References __zt_exception(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::lock, and ast_channel::tech_pvt.
04594 { 04595 struct zt_pvt *p = ast->tech_pvt; 04596 struct ast_frame *f; 04597 ast_mutex_lock(&p->lock); 04598 f = __zt_exception(ast); 04599 ast_mutex_unlock(&p->lock); 04600 return f; 04601 }
static int zt_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3427 of file chan_zap.c.
References ast_channel::_state, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RINGING, zt_pvt::channel, zt_pvt::lock, LOG_DEBUG, zt_subchannel::owner, zt_pvt::owner, zt_pvt::subs, ast_channel::tech_pvt, update_conf(), zt_indicate(), and zt_unlink().
03428 { 03429 struct zt_pvt *p = newchan->tech_pvt; 03430 int x; 03431 ast_mutex_lock(&p->lock); 03432 ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name); 03433 if (p->owner == oldchan) { 03434 p->owner = newchan; 03435 } 03436 for (x = 0; x < 3; x++) 03437 if (p->subs[x].owner == oldchan) { 03438 if (!x) 03439 zt_unlink(NULL, p, 0); 03440 p->subs[x].owner = newchan; 03441 } 03442 if (newchan->_state == AST_STATE_RINGING) 03443 zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0); 03444 update_conf(p); 03445 ast_mutex_unlock(&p->lock); 03446 return 0; 03447 }
static int zt_func_read | ( | struct ast_channel * | chan, | |
char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 3002 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.
03003 { 03004 struct zt_pvt *p = chan->tech_pvt; 03005 03006 if (!strcasecmp(data, "rxgain")) { 03007 ast_mutex_lock(&p->lock); 03008 snprintf(buf, len, "%f", p->rxgain); 03009 ast_mutex_unlock(&p->lock); 03010 } else if (!strcasecmp(data, "txgain")) { 03011 ast_mutex_lock(&p->lock); 03012 snprintf(buf, len, "%f", p->txgain); 03013 ast_mutex_unlock(&p->lock); 03014 } else { 03015 ast_copy_string(buf, "", len); 03016 } 03017 return 0; 03018 }
static int zt_get_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_getevent which ignores a bunch of events.
Definition at line 256 of file chan_zap.c.
Referenced by __zt_exception(), do_monitor(), ss_thread(), and zt_handle_event().
00257 { 00258 int j; 00259 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00260 return -1; 00261 return j; 00262 }
static int zt_get_index | ( | struct ast_channel * | ast, | |
struct zt_pvt * | p, | |||
int | nullok | |||
) | [static] |
Definition at line 763 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().
00764 { 00765 int res; 00766 if (p->subs[0].owner == ast) 00767 res = 0; 00768 else if (p->subs[1].owner == ast) 00769 res = 1; 00770 else if (p->subs[2].owner == ast) 00771 res = 2; 00772 else { 00773 res = -1; 00774 if (!nullok) 00775 ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n"); 00776 } 00777 return res; 00778 }
static void zt_handle_dtmfup | ( | struct ast_channel * | ast, | |
int | index, | |||
struct ast_frame ** | dest | |||
) | [static] |
Definition at line 3595 of file chan_zap.c.
References ast_async_goto(), AST_CONTROL_ANSWER, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_NULL, ast_log(), ast_verbose(), zt_pvt::callprogress, zt_pvt::callwaitcas, ast_channel::cid, ast_callerid::cid_num, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_channel::context, ast_channel::exten, zt_subchannel::f, zt_pvt::faxhandled, ast_frame::frametype, free, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, option_debug, option_verbose, pbx_builtin_setvar_helper(), S_OR, send_cwcidspill(), ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, VERBOSE_PREFIX_3, and zt_confmute().
Referenced by zt_handle_event(), and zt_read().
03596 { 03597 struct zt_pvt *p = ast->tech_pvt; 03598 struct ast_frame *f = *dest; 03599 03600 if (option_debug) 03601 ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name); 03602 03603 if (p->confirmanswer) { 03604 if (option_debug) 03605 ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name); 03606 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 03607 of a DTMF digit */ 03608 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03609 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03610 *dest = &p->subs[index].f; 03611 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 03612 p->confirmanswer = 0; 03613 } else if (p->callwaitcas) { 03614 if ((f->subclass == 'A') || (f->subclass == 'D')) { 03615 if (option_debug) 03616 ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n"); 03617 if (p->cidspill) 03618 free(p->cidspill); 03619 send_cwcidspill(p); 03620 } 03621 if ((f->subclass != 'm') && (f->subclass != 'u')) 03622 p->callwaitcas = 0; 03623 p->subs[index].f.frametype = AST_FRAME_NULL; 03624 p->subs[index].f.subclass = 0; 03625 *dest = &p->subs[index].f; 03626 } else if (f->subclass == 'f') { 03627 /* Fax tone -- Handle and return NULL */ 03628 if ((p->callprogress & 0x6) && !p->faxhandled) { 03629 p->faxhandled++; 03630 if (strcmp(ast->exten, "fax")) { 03631 const char *target_context = S_OR(ast->macrocontext, ast->context); 03632 03633 if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) { 03634 if (option_verbose > 2) 03635 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name); 03636 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 03637 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 03638 if (ast_async_goto(ast, target_context, "fax", 1)) 03639 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 03640 } else 03641 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 03642 } else if (option_debug) 03643 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 03644 } else if (option_debug) 03645 ast_log(LOG_DEBUG, "Fax already handled\n"); 03646 zt_confmute(p, 0); 03647 p->subs[index].f.frametype = AST_FRAME_NULL; 03648 p->subs[index].f.subclass = 0; 03649 *dest = &p->subs[index].f; 03650 } else if (f->subclass == 'm') { 03651 /* Confmute request */ 03652 zt_confmute(p, 1); 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 == 'u') { 03657 /* Unmute */ 03658 zt_confmute(p, 0); 03659 p->subs[index].f.frametype = AST_FRAME_NULL; 03660 p->subs[index].f.subclass = 0; 03661 *dest = &p->subs[index].f; 03662 } else 03663 zt_confmute(p, 0); 03664 }
static struct ast_frame* zt_handle_event | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 3666 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, alarm2str(), alloc_sub(), zt_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_pthread_create, ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdup, ast_strlen_zero(), ast_verbose(), attempt_transfer(), zt_pvt::callprogress, zt_pvt::callwaitcas, zt_pvt::callwaitingrepeat, CANPROGRESSDETECT, zt_pvt::channel, check_for_conference(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, zt_pvt::cid_name, ast_callerid::cid_name, cid_name, zt_pvt::cid_num, ast_callerid::cid_num, cid_num, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_frame::data, ast_frame::datalen, zt_pvt::dialdest, zt_pvt::dialednone, zt_pvt::dialing, zt_pvt::dop, zt_pvt::dsp, zt_pvt::echobreak, zt_pvt::echocanon, zt_pvt::echorest, zt_pvt::echotraining, event2str(), EVENT_FLAG_SYSTEM, zt_subchannel::f, zt_pvt::fake_event, zt_pvt::finaldial, zt_pvt::flashtime, ast_frame::frametype, free, get_alarms(), zt_pvt::hanguponpolarityswitch, has_voicemail(), zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_event(), MIN_MS_SINCE_FLASH, zt_pvt::mohsuggest, zt_pvt::msgstate, zt_subchannel::needanswer, zt_subchannel::needflash, zt_subchannel::needhold, zt_subchannel::needringing, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::onhooktime, zt_pvt::oprmode, zt_pvt::oprpeer, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::outsigmod, zt_pvt::overlapdial, zt_subchannel::owner, zt_pvt::owner, ast_channel::pbx, zt_pvt::polarity, POLARITY_IDLE, POLARITY_REV, zt_pvt::polaritydelaytv, zt_pvt::polarityonanswerdelay, zt_pvt::pulsedial, zt_pvt::radio, restore_conference(), ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, S_OR, ast_frame::samples, save_conference(), zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ast_frame::src, ss_thread(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::threewaycalling, zt_pvt::transfer, zt_pvt::transfertobusy, unalloc_sub(), 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().
03667 { 03668 int res, x; 03669 int index, mysig; 03670 char *c; 03671 struct zt_pvt *p = ast->tech_pvt; 03672 pthread_t threadid; 03673 pthread_attr_t attr; 03674 struct ast_channel *chan; 03675 struct ast_frame *f; 03676 03677 index = zt_get_index(ast, p, 0); 03678 mysig = p->sig; 03679 if (p->outsigmod > -1) 03680 mysig = p->outsigmod; 03681 p->subs[index].f.frametype = AST_FRAME_NULL; 03682 p->subs[index].f.subclass = 0; 03683 p->subs[index].f.datalen = 0; 03684 p->subs[index].f.samples = 0; 03685 p->subs[index].f.mallocd = 0; 03686 p->subs[index].f.offset = 0; 03687 p->subs[index].f.src = "zt_handle_event"; 03688 p->subs[index].f.data = NULL; 03689 f = &p->subs[index].f; 03690 03691 if (index < 0) 03692 return &p->subs[index].f; 03693 if (p->fake_event) { 03694 res = p->fake_event; 03695 p->fake_event = 0; 03696 } else 03697 res = zt_get_event(p->subs[index].zfd); 03698 03699 if (option_debug) 03700 ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index); 03701 03702 if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) { 03703 p->pulsedial = (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0; 03704 03705 ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 03706 #ifdef HAVE_PRI 03707 if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) { 03708 /* absorb event */ 03709 } else { 03710 #endif 03711 p->subs[index].f.frametype = AST_FRAME_DTMF_END; 03712 p->subs[index].f.subclass = res & 0xff; 03713 #ifdef HAVE_PRI 03714 } 03715 #endif 03716 zt_handle_dtmfup(ast, index, &f); 03717 return f; 03718 } 03719 03720 if (res & ZT_EVENT_DTMFDOWN) { 03721 if (option_debug) 03722 ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff); 03723 /* Mute conference */ 03724 zt_confmute(p, 1); 03725 p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN; 03726 p->subs[index].f.subclass = res & 0xff; 03727 return &p->subs[index].f; 03728 } 03729 03730 switch (res) { 03731 #ifdef ZT_EVENT_EC_DISABLED 03732 case ZT_EVENT_EC_DISABLED: 03733 if (option_verbose > 2) 03734 ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel); 03735 p->echocanon = 0; 03736 break; 03737 #endif 03738 case ZT_EVENT_BITSCHANGED: 03739 ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig)); 03740 case ZT_EVENT_PULSE_START: 03741 /* Stop tone if there's a pulse start and the PBX isn't started */ 03742 if (!ast->pbx) 03743 tone_zone_play_tone(p->subs[index].zfd, -1); 03744 break; 03745 case ZT_EVENT_DIALCOMPLETE: 03746 if (p->inalarm) break; 03747 if ((p->radio || (p->oprmode < 0))) break; 03748 if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) { 03749 ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name); 03750 return NULL; 03751 } 03752 if (!x) { /* if not still dialing in driver */ 03753 zt_enable_ec(p); 03754 if (p->echobreak) { 03755 zt_train_ec(p); 03756 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 03757 p->dop.op = ZT_DIAL_OP_REPLACE; 03758 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 03759 p->echobreak = 0; 03760 } else { 03761 p->dialing = 0; 03762 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) { 03763 /* if thru with dialing after offhook */ 03764 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 03765 ast_setstate(ast, AST_STATE_UP); 03766 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03767 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03768 break; 03769 } else { /* if to state wait for offhook to dial rest */ 03770 /* we now wait for off hook */ 03771 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 03772 } 03773 } 03774 if (ast->_state == AST_STATE_DIALING) { 03775 if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 03776 ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n"); 03777 } 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)))) { 03778 ast_setstate(ast, AST_STATE_RINGING); 03779 } else if (!p->answeronpolarityswitch) { 03780 ast_setstate(ast, AST_STATE_UP); 03781 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03782 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03783 } 03784 } 03785 } 03786 } 03787 break; 03788 case ZT_EVENT_ALARM: 03789 #ifdef HAVE_PRI 03790 if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) { 03791 /* T309 is not enabled : hangup calls when alarm occurs */ 03792 if (p->call) { 03793 if (p->pri && p->pri->pri) { 03794 if (!pri_grab(p, p->pri)) { 03795 pri_hangup(p->pri->pri, p->call, -1); 03796 pri_destroycall(p->pri->pri, p->call); 03797 p->call = NULL; 03798 pri_rel(p->pri); 03799 } else 03800 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 03801 } else 03802 ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n"); 03803 } 03804 if (p->owner) 03805 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03806 } 03807 if (p->bearer) 03808 p->bearer->inalarm = 1; 03809 else 03810 #endif 03811 p->inalarm = 1; 03812 res = get_alarms(p); 03813 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm2str(res)); 03814 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 03815 "Alarm: %s\r\n" 03816 "Channel: %d\r\n", 03817 alarm2str(res), p->channel); 03818 #ifdef HAVE_LIBPRI 03819 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 03820 /* fall through intentionally */ 03821 } else { 03822 break; 03823 } 03824 #endif 03825 case ZT_EVENT_ONHOOK: 03826 if (p->radio) { 03827 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03828 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 03829 break; 03830 } 03831 if (p->oprmode < 0) 03832 { 03833 if (p->oprmode != -1) break; 03834 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 03835 { 03836 /* Make sure it starts ringing */ 03837 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 03838 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING); 03839 save_conference(p->oprpeer); 03840 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 03841 } 03842 break; 03843 } 03844 switch (p->sig) { 03845 case SIG_FXOLS: 03846 case SIG_FXOGS: 03847 case SIG_FXOKS: 03848 p->onhooktime = time(NULL); 03849 p->msgstate = -1; 03850 /* Check for some special conditions regarding call waiting */ 03851 if (index == SUB_REAL) { 03852 /* The normal line was hung up */ 03853 if (p->subs[SUB_CALLWAIT].owner) { 03854 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 03855 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 03856 if (option_verbose > 2) 03857 ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel); 03858 unalloc_sub(p, SUB_CALLWAIT); 03859 #if 0 03860 p->subs[index].needanswer = 0; 03861 p->subs[index].needringing = 0; 03862 #endif 03863 p->callwaitingrepeat = 0; 03864 p->cidcwexpire = 0; 03865 p->owner = NULL; 03866 /* Don't start streaming audio yet if the incoming call isn't up yet */ 03867 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 03868 p->dialing = 1; 03869 zt_ring_phone(p); 03870 } else if (p->subs[SUB_THREEWAY].owner) { 03871 unsigned int mssinceflash; 03872 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 03873 the private structure -- not especially easy or clean */ 03874 while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) { 03875 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 03876 ast_mutex_unlock(&p->lock); 03877 ast_mutex_unlock(&ast->lock); 03878 usleep(1); 03879 /* We can grab ast and p in that order, without worry. We should make sure 03880 nothing seriously bad has happened though like some sort of bizarre double 03881 masquerade! */ 03882 ast_mutex_lock(&ast->lock); 03883 ast_mutex_lock(&p->lock); 03884 if (p->owner != ast) { 03885 ast_log(LOG_WARNING, "This isn't good...\n"); 03886 return NULL; 03887 } 03888 } 03889 if (!p->subs[SUB_THREEWAY].owner) { 03890 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 03891 return NULL; 03892 } 03893 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 03894 ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash); 03895 if (mssinceflash < MIN_MS_SINCE_FLASH) { 03896 /* It hasn't been long enough since the last flashook. This is probably a bounce on 03897 hanging up. Hangup both channels now */ 03898 if (p->subs[SUB_THREEWAY].owner) 03899 ast_queue_hangup(p->subs[SUB_THREEWAY].owner); 03900 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03901 ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 03902 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03903 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 03904 if (p->transfer) { 03905 /* In any case this isn't a threeway call anymore */ 03906 p->subs[SUB_REAL].inthreeway = 0; 03907 p->subs[SUB_THREEWAY].inthreeway = 0; 03908 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 03909 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 03910 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03911 /* Swap subs and dis-own channel */ 03912 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03913 p->owner = NULL; 03914 /* Ring the phone */ 03915 zt_ring_phone(p); 03916 } else { 03917 if ((res = attempt_transfer(p)) < 0) { 03918 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03919 if (p->subs[SUB_THREEWAY].owner) 03920 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03921 } else if (res) { 03922 /* Don't actually hang up at this point */ 03923 if (p->subs[SUB_THREEWAY].owner) 03924 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03925 break; 03926 } 03927 } 03928 } else { 03929 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03930 if (p->subs[SUB_THREEWAY].owner) 03931 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03932 } 03933 } else { 03934 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03935 /* Swap subs and dis-own channel */ 03936 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03937 p->owner = NULL; 03938 /* Ring the phone */ 03939 zt_ring_phone(p); 03940 } 03941 } 03942 } else { 03943 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index); 03944 } 03945 /* Fall through */ 03946 default: 03947 zt_disable_ec(p); 03948 return NULL; 03949 } 03950 break; 03951 case ZT_EVENT_RINGOFFHOOK: 03952 if (p->inalarm) break; 03953 if (p->oprmode < 0) 03954 { 03955 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 03956 { 03957 /* Make sure it stops ringing */ 03958 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 03959 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1); 03960 restore_conference(p->oprpeer); 03961 } 03962 break; 03963 } 03964 if (p->radio) 03965 { 03966 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03967 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 03968 break; 03969 } 03970 /* for E911, its supposed to wait for offhook then dial 03971 the second half of the dial string */ 03972 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 03973 c = strchr(p->dialdest, '/'); 03974 if (c) 03975 c++; 03976 else 03977 c = p->dialdest; 03978 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 03979 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 03980 if (strlen(p->dop.dialstr) > 4) { 03981 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 03982 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 03983 p->echorest[sizeof(p->echorest) - 1] = '\0'; 03984 p->echobreak = 1; 03985 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 03986 } else 03987 p->echobreak = 0; 03988 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 03989 x = ZT_ONHOOK; 03990 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03991 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 03992 return NULL; 03993 } 03994 p->dialing = 1; 03995 return &p->subs[index].f; 03996 } 03997 switch (p->sig) { 03998 case SIG_FXOLS: 03999 case SIG_FXOGS: 04000 case SIG_FXOKS: 04001 switch (ast->_state) { 04002 case AST_STATE_RINGING: 04003 zt_enable_ec(p); 04004 zt_train_ec(p); 04005 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04006 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04007 /* Make sure it stops ringing */ 04008 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04009 ast_log(LOG_DEBUG, "channel %d answered\n", p->channel); 04010 if (p->cidspill) { 04011 /* Cancel any running CallerID spill */ 04012 free(p->cidspill); 04013 p->cidspill = NULL; 04014 } 04015 p->dialing = 0; 04016 p->callwaitcas = 0; 04017 if (p->confirmanswer) { 04018 /* Ignore answer if "confirm answer" is enabled */ 04019 p->subs[index].f.frametype = AST_FRAME_NULL; 04020 p->subs[index].f.subclass = 0; 04021 } else if (!ast_strlen_zero(p->dop.dialstr)) { 04022 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 04023 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04024 if (res < 0) { 04025 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04026 p->dop.dialstr[0] = '\0'; 04027 return NULL; 04028 } else { 04029 ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 04030 p->subs[index].f.frametype = AST_FRAME_NULL; 04031 p->subs[index].f.subclass = 0; 04032 p->dialing = 1; 04033 } 04034 p->dop.dialstr[0] = '\0'; 04035 ast_setstate(ast, AST_STATE_DIALING); 04036 } else 04037 ast_setstate(ast, AST_STATE_UP); 04038 return &p->subs[index].f; 04039 case AST_STATE_DOWN: 04040 ast_setstate(ast, AST_STATE_RING); 04041 ast->rings = 1; 04042 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04043 p->subs[index].f.subclass = AST_CONTROL_OFFHOOK; 04044 ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel); 04045 return &p->subs[index].f; 04046 case AST_STATE_UP: 04047 /* Make sure it stops ringing */ 04048 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04049 /* Okay -- probably call waiting*/ 04050 if (ast_bridged_channel(p->owner)) 04051 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04052 p->subs[index].needunhold = 1; 04053 break; 04054 case AST_STATE_RESERVED: 04055 /* Start up dialtone */ 04056 if (has_voicemail(p)) 04057 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 04058 else 04059 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 04060 break; 04061 default: 04062 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 04063 } 04064 break; 04065 case SIG_FXSLS: 04066 case SIG_FXSGS: 04067 case SIG_FXSKS: 04068 if (ast->_state == AST_STATE_RING) { 04069 p->ringt = p->ringt_base; 04070 } 04071 04072 /* If we get a ring then we cannot be in 04073 * reversed polarity. So we reset to idle */ 04074 if (option_debug) 04075 ast_log(LOG_DEBUG, "Setting IDLE polarity due " 04076 "to ring. Old polarity was %d\n", 04077 p->polarity); 04078 p->polarity = POLARITY_IDLE; 04079 04080 /* Fall through */ 04081 case SIG_EM: 04082 case SIG_EM_E1: 04083 case SIG_EMWINK: 04084 case SIG_FEATD: 04085 case SIG_FEATDMF: 04086 case SIG_FEATDMF_TA: 04087 case SIG_E911: 04088 case SIG_FGC_CAMA: 04089 case SIG_FGC_CAMAMF: 04090 case SIG_FEATB: 04091 case SIG_SF: 04092 case SIG_SFWINK: 04093 case SIG_SF_FEATD: 04094 case SIG_SF_FEATDMF: 04095 case SIG_SF_FEATB: 04096 if (ast->_state == AST_STATE_PRERING) 04097 ast_setstate(ast, AST_STATE_RING); 04098 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 04099 if (option_debug) 04100 ast_log(LOG_DEBUG, "Ring detected\n"); 04101 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04102 p->subs[index].f.subclass = AST_CONTROL_RING; 04103 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 04104 if (option_debug) 04105 ast_log(LOG_DEBUG, "Line answered\n"); 04106 if (p->confirmanswer) { 04107 p->subs[index].f.frametype = AST_FRAME_NULL; 04108 p->subs[index].f.subclass = 0; 04109 } else { 04110 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04111 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04112 ast_setstate(ast, AST_STATE_UP); 04113 } 04114 } else if (ast->_state != AST_STATE_RING) 04115 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 04116 break; 04117 default: 04118 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 04119 } 04120 break; 04121 #ifdef ZT_EVENT_RINGBEGIN 04122 case ZT_EVENT_RINGBEGIN: 04123 switch (p->sig) { 04124 case SIG_FXSLS: 04125 case SIG_FXSGS: 04126 case SIG_FXSKS: 04127 if (ast->_state == AST_STATE_RING) { 04128 p->ringt = p->ringt_base; 04129 } 04130 break; 04131 } 04132 break; 04133 #endif 04134 case ZT_EVENT_RINGEROFF: 04135 if (p->inalarm) break; 04136 if ((p->radio || (p->oprmode < 0))) break; 04137 ast->rings++; 04138 if ((ast->rings > p->cidrings) && (p->cidspill)) { 04139 ast_log(LOG_WARNING, "Didn't finish Caller-ID spill. Cancelling.\n"); 04140 free(p->cidspill); 04141 p->cidspill = NULL; 04142 p->callwaitcas = 0; 04143 } 04144 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04145 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04146 break; 04147 case ZT_EVENT_RINGERON: 04148 break; 04149 case ZT_EVENT_NOALARM: 04150 p->inalarm = 0; 04151 #ifdef HAVE_PRI 04152 /* Extremely unlikely but just in case */ 04153 if (p->bearer) 04154 p->bearer->inalarm = 0; 04155 #endif 04156 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 04157 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 04158 "Channel: %d\r\n", p->channel); 04159 break; 04160 case ZT_EVENT_WINKFLASH: 04161 if (p->inalarm) break; 04162 if (p->radio) break; 04163 if (p->oprmode < 0) break; 04164 if (p->oprmode > 1) 04165 { 04166 struct zt_params par; 04167 04168 if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1) 04169 { 04170 if (!par.rxisoffhook) 04171 { 04172 /* Make sure it stops ringing */ 04173 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF); 04174 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING); 04175 save_conference(p); 04176 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04177 } 04178 } 04179 break; 04180 } 04181 /* Remember last time we got a flash-hook */ 04182 gettimeofday(&p->flashtime, NULL); 04183 switch (mysig) { 04184 case SIG_FXOLS: 04185 case SIG_FXOGS: 04186 case SIG_FXOKS: 04187 ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 04188 index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 04189 p->callwaitcas = 0; 04190 04191 if (index != SUB_REAL) { 04192 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel); 04193 goto winkflashdone; 04194 } 04195 04196 if (p->subs[SUB_CALLWAIT].owner) { 04197 /* Swap to call-wait */ 04198 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 04199 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 04200 p->owner = p->subs[SUB_REAL].owner; 04201 ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name); 04202 if (p->owner->_state == AST_STATE_RINGING) { 04203 ast_setstate(p->owner, AST_STATE_UP); 04204 p->subs[SUB_REAL].needanswer = 1; 04205 } 04206 p->callwaitingrepeat = 0; 04207 p->cidcwexpire = 0; 04208 /* Start music on hold if appropriate */ 04209 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 04210 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 04211 S_OR(p->mohsuggest, NULL), 04212 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04213 } 04214 p->subs[SUB_CALLWAIT].needhold = 1; 04215 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 04216 ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD, 04217 S_OR(p->mohsuggest, NULL), 04218 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04219 } 04220 p->subs[SUB_REAL].needunhold = 1; 04221 } else if (!p->subs[SUB_THREEWAY].owner) { 04222 char cid_num[256]; 04223 char cid_name[256]; 04224 04225 if (!p->threewaycalling) { 04226 /* Just send a flash if no 3-way calling */ 04227 p->subs[SUB_REAL].needflash = 1; 04228 goto winkflashdone; 04229 } else if (!check_for_conference(p)) { 04230 if (p->zaptrcallerid && p->owner) { 04231 if (p->owner->cid.cid_num) 04232 ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num)); 04233 if (p->owner->cid.cid_name) 04234 ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name)); 04235 } 04236 /* XXX This section needs much more error checking!!! XXX */ 04237 /* Start a 3-way call if feasible */ 04238 if (!((ast->pbx) || 04239 (ast->_state == AST_STATE_UP) || 04240 (ast->_state == AST_STATE_RING))) { 04241 ast_log(LOG_DEBUG, "Flash when call not up or ringing\n"); 04242 goto winkflashdone; 04243 } 04244 if (alloc_sub(p, SUB_THREEWAY)) { 04245 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 04246 goto winkflashdone; 04247 } 04248 /* Make new channel */ 04249 chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0); 04250 if (p->zaptrcallerid) { 04251 if (!p->origcid_num) 04252 p->origcid_num = ast_strdup(p->cid_num); 04253 if (!p->origcid_name) 04254 p->origcid_name = ast_strdup(p->cid_name); 04255 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 04256 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 04257 } 04258 /* Swap things around between the three-way and real call */ 04259 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04260 /* Disable echo canceller for better dialing */ 04261 zt_disable_ec(p); 04262 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL); 04263 if (res) 04264 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 04265 p->owner = chan; 04266 pthread_attr_init(&attr); 04267 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04268 if (!chan) { 04269 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 04270 } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 04271 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 04272 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 04273 zt_enable_ec(p); 04274 ast_hangup(chan); 04275 } else { 04276 if (option_verbose > 2) 04277 ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel); 04278 /* Start music on hold if appropriate */ 04279 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 04280 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 04281 S_OR(p->mohsuggest, NULL), 04282 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04283 } 04284 p->subs[SUB_THREEWAY].needhold = 1; 04285 } 04286 pthread_attr_destroy(&attr); 04287 } 04288 } else { 04289 /* Already have a 3 way call */ 04290 if (p->subs[SUB_THREEWAY].inthreeway) { 04291 /* Call is already up, drop the last person */ 04292 if (option_debug) 04293 ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel); 04294 /* If the primary call isn't answered yet, use it */ 04295 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 04296 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 04297 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04298 p->owner = p->subs[SUB_REAL].owner; 04299 } 04300 /* Drop the last call and stop the conference */ 04301 if (option_verbose > 2) 04302 ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name); 04303 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04304 p->subs[SUB_REAL].inthreeway = 0; 04305 p->subs[SUB_THREEWAY].inthreeway = 0; 04306 } else { 04307 /* Lets see what we're up to */ 04308 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 04309 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 04310 int otherindex = SUB_THREEWAY; 04311 04312 if (option_verbose > 2) 04313 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); 04314 /* Put them in the threeway, and flip */ 04315 p->subs[SUB_THREEWAY].inthreeway = 1; 04316 p->subs[SUB_REAL].inthreeway = 1; 04317 if (ast->_state == AST_STATE_UP) { 04318 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04319 otherindex = SUB_REAL; 04320 } 04321 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 04322 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 04323 p->subs[otherindex].needunhold = 1; 04324 p->owner = p->subs[SUB_REAL].owner; 04325 if (ast->_state == AST_STATE_RINGING) { 04326 ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n"); 04327 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04328 res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 04329 } 04330 } else { 04331 if (option_verbose > 2) 04332 ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name); 04333 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04334 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04335 p->owner = p->subs[SUB_REAL].owner; 04336 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 04337 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 04338 p->subs[SUB_REAL].needunhold = 1; 04339 zt_enable_ec(p); 04340 } 04341 04342 } 04343 } 04344 winkflashdone: 04345 update_conf(p); 04346 break; 04347 case SIG_EM: 04348 case SIG_EM_E1: 04349 case SIG_EMWINK: 04350 case SIG_FEATD: 04351 case SIG_SF: 04352 case SIG_SFWINK: 04353 case SIG_SF_FEATD: 04354 case SIG_FXSLS: 04355 case SIG_FXSGS: 04356 if (p->dialing) 04357 ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel); 04358 else 04359 ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 04360 break; 04361 case SIG_FEATDMF_TA: 04362 switch (p->whichwink) { 04363 case 0: 04364 ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04365 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04366 break; 04367 case 1: 04368 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 04369 break; 04370 case 2: 04371 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 04372 return NULL; 04373 } 04374 p->whichwink++; 04375 /* Fall through */ 04376 case SIG_FEATDMF: 04377 case SIG_E911: 04378 case SIG_FGC_CAMAMF: 04379 case SIG_FGC_CAMA: 04380 case SIG_FEATB: 04381 case SIG_SF_FEATDMF: 04382 case SIG_SF_FEATB: 04383 /* FGD MF *Must* wait for wink */ 04384 if (!ast_strlen_zero(p->dop.dialstr)) 04385 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04386 else if (res < 0) { 04387 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04388 p->dop.dialstr[0] = '\0'; 04389 return NULL; 04390 } else 04391 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04392 p->dop.dialstr[0] = '\0'; 04393 break; 04394 default: 04395 ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig); 04396 } 04397 break; 04398 case ZT_EVENT_HOOKCOMPLETE: 04399 if (p->inalarm) break; 04400 if ((p->radio || (p->oprmode < 0))) break; 04401 switch (mysig) { 04402 case SIG_FXSLS: /* only interesting for FXS */ 04403 case SIG_FXSGS: 04404 case SIG_FXSKS: 04405 case SIG_EM: 04406 case SIG_EM_E1: 04407 case SIG_EMWINK: 04408 case SIG_FEATD: 04409 case SIG_SF: 04410 case SIG_SFWINK: 04411 case SIG_SF_FEATD: 04412 if (!ast_strlen_zero(p->dop.dialstr)) 04413 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04414 else if (res < 0) { 04415 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04416 p->dop.dialstr[0] = '\0'; 04417 return NULL; 04418 } else 04419 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04420 p->dop.dialstr[0] = '\0'; 04421 p->dop.op = ZT_DIAL_OP_REPLACE; 04422 break; 04423 case SIG_FEATDMF: 04424 case SIG_FEATDMF_TA: 04425 case SIG_E911: 04426 case SIG_FGC_CAMA: 04427 case SIG_FGC_CAMAMF: 04428 case SIG_FEATB: 04429 case SIG_SF_FEATDMF: 04430 case SIG_SF_FEATB: 04431 ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 04432 break; 04433 default: 04434 break; 04435 } 04436 break; 04437 case ZT_EVENT_POLARITY: 04438 /* 04439 * If we get a Polarity Switch event, check to see 04440 * if we should change the polarity state and 04441 * mark the channel as UP or if this is an indication 04442 * of remote end disconnect. 04443 */ 04444 if (p->polarity == POLARITY_IDLE) { 04445 p->polarity = POLARITY_REV; 04446 if (p->answeronpolarityswitch && 04447 ((ast->_state == AST_STATE_DIALING) || 04448 (ast->_state == AST_STATE_RINGING))) { 04449 ast_log(LOG_DEBUG, "Answering on polarity switch!\n"); 04450 ast_setstate(p->owner, AST_STATE_UP); 04451 if (p->hanguponpolarityswitch) { 04452 gettimeofday(&p->polaritydelaytv, NULL); 04453 } 04454 } else 04455 ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 04456 } 04457 /* Removed else statement from here as it was preventing hangups from ever happening*/ 04458 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 04459 if (p->hanguponpolarityswitch && 04460 (p->polarityonanswerdelay > 0) && 04461 (p->polarity == POLARITY_REV) && 04462 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 04463 /* Added log_debug information below to provide a better indication of what is going on */ 04464 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) ); 04465 04466 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 04467 ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 04468 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 04469 p->polarity = POLARITY_IDLE; 04470 } else { 04471 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); 04472 } 04473 } else { 04474 p->polarity = POLARITY_IDLE; 04475 ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 04476 } 04477 /* Added more log_debug information below to provide a better indication of what is going on */ 04478 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) ); 04479 break; 04480 default: 04481 ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel); 04482 } 04483 return &p->subs[index].f; 04484 }
static int zt_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2404 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().
02405 { 02406 int res; 02407 int index,x, law; 02408 /*static int restore_gains(struct zt_pvt *p);*/ 02409 struct zt_pvt *p = ast->tech_pvt; 02410 struct zt_pvt *tmp = NULL; 02411 struct zt_pvt *prev = NULL; 02412 ZT_PARAMS par; 02413 02414 if (option_debug) 02415 ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name); 02416 if (!ast->tech_pvt) { 02417 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 02418 return 0; 02419 } 02420 02421 ast_mutex_lock(&p->lock); 02422 02423 index = zt_get_index(ast, p, 1); 02424 02425 if (p->sig == SIG_PRI) { 02426 x = 1; 02427 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02428 } 02429 02430 x = 0; 02431 zt_confmute(p, 0); 02432 restore_gains(p); 02433 if (p->origcid_num) { 02434 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 02435 free(p->origcid_num); 02436 p->origcid_num = NULL; 02437 } 02438 if (p->origcid_name) { 02439 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 02440 free(p->origcid_name); 02441 p->origcid_name = NULL; 02442 } 02443 if (p->dsp) 02444 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 02445 if (p->exten) 02446 p->exten[0] = '\0'; 02447 02448 if (option_debug) 02449 ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 02450 p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 02451 p->ignoredtmf = 0; 02452 02453 if (index > -1) { 02454 /* Real channel, do some fixup */ 02455 p->subs[index].owner = NULL; 02456 p->subs[index].needanswer = 0; 02457 p->subs[index].needflash = 0; 02458 p->subs[index].needringing = 0; 02459 p->subs[index].needbusy = 0; 02460 p->subs[index].needcongestion = 0; 02461 p->subs[index].linear = 0; 02462 p->subs[index].needcallerid = 0; 02463 p->polarity = POLARITY_IDLE; 02464 zt_setlinear(p->subs[index].zfd, 0); 02465 if (index == SUB_REAL) { 02466 if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) { 02467 ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n"); 02468 if (p->subs[SUB_CALLWAIT].inthreeway) { 02469 /* We had flipped over to answer a callwait and now it's gone */ 02470 ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n"); 02471 /* Move to the call-wait, but un-own us until they flip back. */ 02472 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02473 unalloc_sub(p, SUB_CALLWAIT); 02474 p->owner = NULL; 02475 } else { 02476 /* The three way hung up, but we still have a call wait */ 02477 ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 02478 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02479 unalloc_sub(p, SUB_THREEWAY); 02480 if (p->subs[SUB_REAL].inthreeway) { 02481 /* This was part of a three way call. Immediately make way for 02482 another call */ 02483 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02484 p->owner = p->subs[SUB_REAL].owner; 02485 } else { 02486 /* This call hasn't been completed yet... Set owner to NULL */ 02487 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02488 p->owner = NULL; 02489 } 02490 p->subs[SUB_REAL].inthreeway = 0; 02491 } 02492 } else if (p->subs[SUB_CALLWAIT].zfd > -1) { 02493 /* Move to the call-wait and switch back to them. */ 02494 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02495 unalloc_sub(p, SUB_CALLWAIT); 02496 p->owner = p->subs[SUB_REAL].owner; 02497 if (p->owner->_state != AST_STATE_UP) 02498 p->subs[SUB_REAL].needanswer = 1; 02499 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 02500 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 02501 } else if (p->subs[SUB_THREEWAY].zfd > -1) { 02502 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02503 unalloc_sub(p, SUB_THREEWAY); 02504 if (p->subs[SUB_REAL].inthreeway) { 02505 /* This was part of a three way call. Immediately make way for 02506 another call */ 02507 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02508 p->owner = p->subs[SUB_REAL].owner; 02509 } else { 02510 /* This call hasn't been completed yet... Set owner to NULL */ 02511 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02512 p->owner = NULL; 02513 } 02514 p->subs[SUB_REAL].inthreeway = 0; 02515 } 02516 } else if (index == SUB_CALLWAIT) { 02517 /* Ditch the holding callwait call, and immediately make it availabe */ 02518 if (p->subs[SUB_CALLWAIT].inthreeway) { 02519 /* This is actually part of a three way, placed on hold. Place the third part 02520 on music on hold now */ 02521 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 02522 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 02523 S_OR(p->mohsuggest, NULL), 02524 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02525 } 02526 p->subs[SUB_THREEWAY].inthreeway = 0; 02527 /* Make it the call wait now */ 02528 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 02529 unalloc_sub(p, SUB_THREEWAY); 02530 } else 02531 unalloc_sub(p, SUB_CALLWAIT); 02532 } else if (index == SUB_THREEWAY) { 02533 if (p->subs[SUB_CALLWAIT].inthreeway) { 02534 /* The other party of the three way call is currently in a call-wait state. 02535 Start music on hold for them, and take the main guy out of the third call */ 02536 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 02537 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 02538 S_OR(p->mohsuggest, NULL), 02539 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02540 } 02541 p->subs[SUB_CALLWAIT].inthreeway = 0; 02542 } 02543 p->subs[SUB_REAL].inthreeway = 0; 02544 /* If this was part of a three way call index, let us make 02545 another three way call */ 02546 unalloc_sub(p, SUB_THREEWAY); 02547 } else { 02548 /* This wasn't any sort of call, but how are we an index? */ 02549 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 02550 } 02551 } 02552 02553 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 02554 p->owner = NULL; 02555 p->ringt = 0; 02556 p->distinctivering = 0; 02557 p->confirmanswer = 0; 02558 p->cidrings = 1; 02559 p->outgoing = 0; 02560 p->digital = 0; 02561 p->faxhandled = 0; 02562 p->pulsedial = 0; 02563 p->onhooktime = time(NULL); 02564 #ifdef HAVE_PRI 02565 p->proceeding = 0; 02566 p->progress = 0; 02567 p->alerting = 0; 02568 p->setup_ack = 0; 02569 #endif 02570 if (p->dsp) { 02571 ast_dsp_free(p->dsp); 02572 p->dsp = NULL; 02573 } 02574 02575 law = ZT_LAW_DEFAULT; 02576 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law); 02577 if (res < 0) 02578 ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel); 02579 /* Perform low level hangup if no owner left */ 02580 #ifdef HAVE_PRI 02581 if (p->pri) { 02582 #ifdef SUPPORT_USERUSER 02583 const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO"); 02584 #endif 02585 02586 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */ 02587 if (p->call && (!p->bearer || (p->bearer->call == p->call))) { 02588 if (!pri_grab(p, p->pri)) { 02589 if (p->alreadyhungup) { 02590 ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); 02591 02592 #ifdef SUPPORT_USERUSER 02593 pri_call_set_useruser(p->call, useruser); 02594 #endif 02595 02596 pri_hangup(p->pri->pri, p->call, -1); 02597 p->call = NULL; 02598 if (p->bearer) 02599 p->bearer->call = NULL; 02600 } else { 02601 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 02602 int icause = ast->hangupcause ? ast->hangupcause : -1; 02603 ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); 02604 02605 #ifdef SUPPORT_USERUSER 02606 pri_call_set_useruser(p->call, useruser); 02607 #endif 02608 02609 p->alreadyhungup = 1; 02610 if (p->bearer) 02611 p->bearer->alreadyhungup = 1; 02612 if (cause) { 02613 if (atoi(cause)) 02614 icause = atoi(cause); 02615 } 02616 pri_hangup(p->pri->pri, p->call, icause); 02617 } 02618 if (res < 0) 02619 ast_log(LOG_WARNING, "pri_disconnect failed\n"); 02620 pri_rel(p->pri); 02621 } else { 02622 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02623 res = -1; 02624 } 02625 } else { 02626 if (p->bearer) 02627 ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call); 02628 p->call = NULL; 02629 res = 0; 02630 } 02631 } 02632 #endif 02633 if (p->sig && (p->sig != SIG_PRI)) 02634 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 02635 if (res < 0) { 02636 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 02637 } 02638 switch (p->sig) { 02639 case SIG_FXOGS: 02640 case SIG_FXOLS: 02641 case SIG_FXOKS: 02642 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 02643 if (!res) { 02644 #if 0 02645 ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 02646 #endif 02647 /* If they're off hook, try playing congestion */ 02648 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0)))) 02649 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 02650 else 02651 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02652 } 02653 break; 02654 case SIG_FXSGS: 02655 case SIG_FXSLS: 02656 case SIG_FXSKS: 02657 /* Make sure we're not made available for at least two seconds assuming 02658 we were actually used for an inbound or outbound call. */ 02659 if (ast->_state != AST_STATE_RESERVED) { 02660 time(&p->guardtime); 02661 p->guardtime += 2; 02662 } 02663 break; 02664 default: 02665 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02666 } 02667 if (p->cidspill) 02668 free(p->cidspill); 02669 if (p->sig) 02670 zt_disable_ec(p); 02671 x = 0; 02672 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 02673 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 02674 p->didtdd = 0; 02675 p->cidspill = NULL; 02676 p->callwaitcas = 0; 02677 p->callwaiting = p->permcallwaiting; 02678 p->hidecallerid = p->permhidecallerid; 02679 p->dialing = 0; 02680 p->rdnis[0] = '\0'; 02681 update_conf(p); 02682 reset_conf(p); 02683 /* Restore data mode */ 02684 if (p->sig == SIG_PRI) { 02685 x = 0; 02686 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02687 } 02688 #ifdef HAVE_PRI 02689 if (p->bearer) { 02690 ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel); 02691 /* Free up the bearer channel as well, and 02692 don't use its file descriptor anymore */ 02693 update_conf(p->bearer); 02694 reset_conf(p->bearer); 02695 p->bearer->owner = NULL; 02696 p->bearer->realcall = NULL; 02697 p->bearer = NULL; 02698 p->subs[SUB_REAL].zfd = -1; 02699 p->pri = NULL; 02700 } 02701 #endif 02702 restart_monitor(); 02703 } 02704 02705 p->callwaitingrepeat = 0; 02706 p->cidcwexpire = 0; 02707 p->oprmode = 0; 02708 ast->tech_pvt = NULL; 02709 ast_mutex_unlock(&p->lock); 02710 ast_module_unref(ast_module_info->self); 02711 if (option_verbose > 2) 02712 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name); 02713 02714 ast_mutex_lock(&iflock); 02715 tmp = iflist; 02716 prev = NULL; 02717 if (p->destroy) { 02718 while (tmp) { 02719 if (tmp == p) { 02720 destroy_channel(prev, tmp, 0); 02721 break; 02722 } else { 02723 prev = tmp; 02724 tmp = tmp->next; 02725 } 02726 } 02727 } 02728 ast_mutex_unlock(&iflock); 02729 return 0; 02730 }
static int zt_indicate | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5001 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, AST_CAUSE_CONGESTION, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_log(), ast_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, func, ast_channel::hangupcause, ISTRUNK, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::mohinterpret, option_debug, zt_pvt::outgoing, zt_pvt::priindication_oob, zt_pvt::radio, zt_pvt::sig, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_set_hook().
Referenced by zt_fixup().
05002 { 05003 struct zt_pvt *p = chan->tech_pvt; 05004 int res=-1; 05005 int index; 05006 int func = ZT_FLASH; 05007 ast_mutex_lock(&p->lock); 05008 index = zt_get_index(chan, p, 0); 05009 if (option_debug) 05010 ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name); 05011 if (index == SUB_REAL) { 05012 switch (condition) { 05013 case AST_CONTROL_BUSY: 05014 #ifdef HAVE_PRI 05015 if (p->priindication_oob && p->sig == SIG_PRI) { 05016 chan->hangupcause = AST_CAUSE_USER_BUSY; 05017 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05018 res = 0; 05019 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05020 if (p->pri->pri) { 05021 if (!pri_grab(p, p->pri)) { 05022 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05023 pri_rel(p->pri); 05024 } 05025 else 05026 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05027 } 05028 p->progress = 1; 05029 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05030 } else 05031 #endif 05032 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05033 break; 05034 case AST_CONTROL_RINGING: 05035 #ifdef HAVE_PRI 05036 if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) { 05037 if (p->pri->pri) { 05038 if (!pri_grab(p, p->pri)) { 05039 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05040 pri_rel(p->pri); 05041 } 05042 else 05043 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05044 } 05045 p->alerting = 1; 05046 } 05047 #endif 05048 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE); 05049 if (chan->_state != AST_STATE_UP) { 05050 if ((chan->_state != AST_STATE_RING) || 05051 ((p->sig != SIG_FXSKS) && 05052 (p->sig != SIG_FXSLS) && 05053 (p->sig != SIG_FXSGS))) 05054 ast_setstate(chan, AST_STATE_RINGING); 05055 } 05056 break; 05057 case AST_CONTROL_PROCEEDING: 05058 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 05059 #ifdef HAVE_PRI 05060 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05061 if (p->pri->pri) { 05062 if (!pri_grab(p, p->pri)) { 05063 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05064 pri_rel(p->pri); 05065 } 05066 else 05067 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05068 } 05069 p->proceeding = 1; 05070 } 05071 #endif 05072 /* don't continue in ast_indicate */ 05073 res = 0; 05074 break; 05075 case AST_CONTROL_PROGRESS: 05076 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 05077 #ifdef HAVE_PRI 05078 p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */ 05079 if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05080 if (p->pri->pri) { 05081 if (!pri_grab(p, p->pri)) { 05082 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05083 pri_rel(p->pri); 05084 } 05085 else 05086 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05087 } 05088 p->progress = 1; 05089 } 05090 #endif 05091 /* don't continue in ast_indicate */ 05092 res = 0; 05093 break; 05094 case AST_CONTROL_CONGESTION: 05095 chan->hangupcause = AST_CAUSE_CONGESTION; 05096 #ifdef HAVE_PRI 05097 if (p->priindication_oob && p->sig == SIG_PRI) { 05098 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 05099 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05100 res = 0; 05101 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05102 if (p->pri) { 05103 if (!pri_grab(p, p->pri)) { 05104 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05105 pri_rel(p->pri); 05106 } else 05107 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05108 } 05109 p->progress = 1; 05110 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05111 } else 05112 #endif 05113 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05114 break; 05115 case AST_CONTROL_HOLD: 05116 #ifdef HAVE_PRI 05117 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05118 if (!pri_grab(p, p->pri)) { 05119 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 05120 pri_rel(p->pri); 05121 } else 05122 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05123 } else 05124 #endif 05125 ast_moh_start(chan, data, p->mohinterpret); 05126 break; 05127 case AST_CONTROL_UNHOLD: 05128 #ifdef HAVE_PRI 05129 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05130 if (!pri_grab(p, p->pri)) { 05131 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 05132 pri_rel(p->pri); 05133 } else 05134 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05135 } else 05136 #endif 05137 ast_moh_stop(chan); 05138 break; 05139 case AST_CONTROL_RADIO_KEY: 05140 if (p->radio) 05141 res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 05142 res = 0; 05143 break; 05144 case AST_CONTROL_RADIO_UNKEY: 05145 if (p->radio) 05146 res = zt_set_hook(p->subs[index].zfd, ZT_RINGOFF); 05147 res = 0; 05148 break; 05149 case AST_CONTROL_FLASH: 05150 /* flash hookswitch */ 05151 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 05152 /* Clear out the dial buffer */ 05153 p->dop.dialstr[0] = '\0'; 05154 if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 05155 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 05156 chan->name, strerror(errno)); 05157 } else 05158 res = 0; 05159 } else 05160 res = 0; 05161 break; 05162 case -1: 05163 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05164 break; 05165 } 05166 } else 05167 res = 0; 05168 ast_mutex_unlock(&p->lock); 05169 return res; 05170 }
Definition at line 3079 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_DEBUG, LOG_WARNING, zt_pvt::master, MAX_SLAVES, and zt_pvt::slaves.
Referenced by zt_bridge().
03079 { 03080 int x; 03081 if (!slave || !master) { 03082 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 03083 return; 03084 } 03085 for (x = 0; x < MAX_SLAVES; x++) { 03086 if (!master->slaves[x]) { 03087 master->slaves[x] = slave; 03088 break; 03089 } 03090 } 03091 if (x >= MAX_SLAVES) { 03092 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 03093 master->slaves[MAX_SLAVES - 1] = slave; 03094 } 03095 if (slave->master) 03096 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 03097 slave->master = master; 03098 03099 ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 03100 }
static struct ast_channel * zt_new | ( | struct zt_pvt * | i, | |
int | state, | |||
int | startpbx, | |||
int | index, | |||
int | law, | |||
int | transfercapability | |||
) | [static, read] |
> b2 can be freed now, it's been copied into the channel structure
Definition at line 5172 of file chan_zap.c.
References accountcode, zt_pvt::accountcode, zt_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, zt_pvt::amaflags, AST_ADSI_UNAVAILABLE, ast_channel_alloc(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_busy_count(), ast_dsp_set_busy_pattern(), ast_dsp_set_call_progress_zone(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), ast_random(), ast_safe_string_alloc(), AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_transfercapability2str(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::call_forward, zt_pvt::callgroup, ast_channel::callgroup, zt_pvt::callingpres, zt_pvt::callprogress, CANBUSYDETECT, CANPROGRESSDETECT, CHAN_PSEUDO, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cid_ton, ast_callerid::cid_ton, ast_channel::context, zt_pvt::context, zt_pvt::digital, zt_pvt::dnid, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, zt_pvt::dsp_features, DSP_PROGRESS_TALK, zt_pvt::dtmfrelax, ast_channel::exten, zt_pvt::exten, zt_pvt::fake_event, ast_channel::fds, free, global_jbconf, zt_pvt::hardwaredtmf, language, zt_pvt::language, zt_subchannel::linear, LOG_DEBUG, LOG_WARNING, ast_channel::nativeformats, NEED_MFDETECT, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), zt_pvt::pickupgroup, ast_channel::pickupgroup, PRI_TRANS_CAP_DIGITAL, ast_channel::rawreadformat, ast_channel::rawwriteformat, zt_pvt::rdnis, ast_channel::readformat, ast_channel::rings, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_PRI, SUB_REAL, zt_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, ast_channel::writeformat, zt_subchannel::zfd, zt_confmute(), and zt_setlinear().
Referenced by handle_init_event(), zt_handle_event(), and zt_request().
05173 { 05174 struct ast_channel *tmp; 05175 int deflaw; 05176 int res; 05177 int x,y; 05178 int features; 05179 char *b2 = NULL; 05180 ZT_PARAMS ps; 05181 if (i->subs[index].owner) { 05182 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]); 05183 return NULL; 05184 } 05185 y = 1; 05186 do { 05187 if (b2) 05188 free(b2); 05189 #ifdef HAVE_PRI 05190 if (i->bearer || (i->pri && (i->sig == SIG_FXSKS))) 05191 b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y); 05192 else 05193 #endif 05194 if (i->channel == CHAN_PSEUDO) 05195 b2 = ast_safe_string_alloc("pseudo-%ld", ast_random()); 05196 else 05197 b2 = ast_safe_string_alloc("%d-%d", i->channel, y); 05198 for (x = 0; x < 3; x++) { 05199 if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name)) 05200 break; 05201 } 05202 y++; 05203 } while (x < 3); 05204 tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2); 05205 if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */ 05206 free(b2); 05207 if (!tmp) 05208 return NULL; 05209 tmp->tech = &zap_tech; 05210 ps.channo = i->channel; 05211 res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps); 05212 if (res) { 05213 ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n"); 05214 ps.curlaw = ZT_LAW_MULAW; 05215 } 05216 if (ps.curlaw == ZT_LAW_ALAW) 05217 deflaw = AST_FORMAT_ALAW; 05218 else 05219 deflaw = AST_FORMAT_ULAW; 05220 if (law) { 05221 if (law == ZT_LAW_ALAW) 05222 deflaw = AST_FORMAT_ALAW; 05223 else 05224 deflaw = AST_FORMAT_ULAW; 05225 } 05226 tmp->fds[0] = i->subs[index].zfd; 05227 tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw; 05228 /* Start out assuming ulaw since it's smaller :) */ 05229 tmp->rawreadformat = deflaw; 05230 tmp->readformat = deflaw; 05231 tmp->rawwriteformat = deflaw; 05232 tmp->writeformat = deflaw; 05233 i->subs[index].linear = 0; 05234 zt_setlinear(i->subs[index].zfd, i->subs[index].linear); 05235 features = 0; 05236 if (index == SUB_REAL) { 05237 if (i->busydetect && CANBUSYDETECT(i)) 05238 features |= DSP_FEATURE_BUSY_DETECT; 05239 if ((i->callprogress & 1) && CANPROGRESSDETECT(i)) 05240 features |= DSP_FEATURE_CALL_PROGRESS; 05241 if ((!i->outgoing && (i->callprogress & 4)) || 05242 (i->outgoing && (i->callprogress & 2))) { 05243 features |= DSP_FEATURE_FAX_DETECT; 05244 } 05245 #ifdef ZT_TONEDETECT 05246 x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 05247 if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) { 05248 #endif 05249 i->hardwaredtmf = 0; 05250 features |= DSP_FEATURE_DTMF_DETECT; 05251 #ifdef ZT_TONEDETECT 05252 } else if (NEED_MFDETECT(i)) { 05253 i->hardwaredtmf = 1; 05254 features |= DSP_FEATURE_DTMF_DETECT; 05255 } 05256 #endif 05257 } 05258 if (features) { 05259 if (i->dsp) { 05260 ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name); 05261 } else { 05262 if (i->channel != CHAN_PSEUDO) 05263 i->dsp = ast_dsp_new(); 05264 else 05265 i->dsp = NULL; 05266 if (i->dsp) { 05267 i->dsp_features = features & ~DSP_PROGRESS_TALK; 05268 #ifdef HAVE_PRI 05269 /* We cannot do progress detection until receives PROGRESS message */ 05270 if (i->outgoing && (i->sig == SIG_PRI)) { 05271 /* Remember requested DSP features, don't treat 05272 talking as ANSWER */ 05273 features = 0; 05274 } 05275 #endif 05276 ast_dsp_set_features(i->dsp, features); 05277 ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 05278 if (!ast_strlen_zero(progzone)) 05279 ast_dsp_set_call_progress_zone(i->dsp, progzone); 05280 if (i->busydetect && CANBUSYDETECT(i)) { 05281 ast_dsp_set_busy_count(i->dsp, i->busycount); 05282 ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength); 05283 } 05284 } 05285 } 05286 } 05287 05288 if (state == AST_STATE_RING) 05289 tmp->rings = 1; 05290 tmp->tech_pvt = i; 05291 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 05292 /* Only FXO signalled stuff can be picked up */ 05293 tmp->callgroup = i->callgroup; 05294 tmp->pickupgroup = i->pickupgroup; 05295 } 05296 if (!ast_strlen_zero(i->language)) 05297 ast_string_field_set(tmp, language, i->language); 05298 if (!i->owner) 05299 i->owner = tmp; 05300 if (!ast_strlen_zero(i->accountcode)) 05301 ast_string_field_set(tmp, accountcode, i->accountcode); 05302 if (i->amaflags) 05303 tmp->amaflags = i->amaflags; 05304 i->subs[index].owner = tmp; 05305 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05306 ast_string_field_set(tmp, call_forward, i->call_forward); 05307 /* If we've been told "no ADSI" then enforce it */ 05308 if (!i->adsi) 05309 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05310 if (!ast_strlen_zero(i->exten)) 05311 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05312 if (!ast_strlen_zero(i->rdnis)) 05313 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05314 if (!ast_strlen_zero(i->dnid)) 05315 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05316 05317 /* Don't use ast_set_callerid() here because it will 05318 * generate a needless NewCallerID event */ 05319 #ifdef PRI_ANI 05320 tmp->cid.cid_num = ast_strdup(i->cid_num); 05321 tmp->cid.cid_name = ast_strdup(i->cid_name); 05322 if (!ast_strlen_zero(i->cid_ani)) 05323 tmp->cid.cid_ani = ast_strdup(i->cid_ani); 05324 else 05325 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05326 #else 05327 tmp->cid.cid_num = ast_strdup(i->cid_num); 05328 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05329 tmp->cid.cid_name = ast_strdup(i->cid_name); 05330 #endif 05331 tmp->cid.cid_pres = i->callingpres; 05332 tmp->cid.cid_ton = i->cid_ton; 05333 #ifdef HAVE_PRI 05334 tmp->transfercapability = transfercapability; 05335 pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability)); 05336 if (transfercapability & PRI_TRANS_CAP_DIGITAL) 05337 i->digital = 1; 05338 /* Assume calls are not idle calls unless we're told differently */ 05339 i->isidlecall = 0; 05340 i->alreadyhungup = 0; 05341 #endif 05342 /* clear the fake event in case we posted one before we had ast_channel */ 05343 i->fake_event = 0; 05344 /* Assure there is no confmute on this channel */ 05345 zt_confmute(i, 0); 05346 /* Configure the new channel jb */ 05347 ast_jb_configure(tmp, &global_jbconf); 05348 if (startpbx) { 05349 if (ast_pbx_start(tmp)) { 05350 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05351 ast_hangup(tmp); 05352 i->owner = NULL; 05353 return NULL; 05354 } 05355 } 05356 05357 ast_module_ref(ast_module_info->self); 05358 05359 return tmp; 05360 }
static int zt_open | ( | char * | fn | ) | [static] |
Definition at line 871 of file chan_zap.c.
References ast_log(), LOG_WARNING, and READ_SIZE.
Referenced by alloc_sub(), chandup(), and mkintf().
00872 { 00873 int fd; 00874 int isnum; 00875 int chan = 0; 00876 int bs; 00877 int x; 00878 isnum = 1; 00879 for (x = 0; x < strlen(fn); x++) { 00880 if (!isdigit(fn[x])) { 00881 isnum = 0; 00882 break; 00883 } 00884 } 00885 if (isnum) { 00886 chan = atoi(fn); 00887 if (chan < 1) { 00888 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn); 00889 return -1; 00890 } 00891 fn = "/dev/zap/channel"; 00892 } 00893 fd = open(fn, O_RDWR | O_NONBLOCK); 00894 if (fd < 0) { 00895 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno)); 00896 return -1; 00897 } 00898 if (chan) { 00899 if (ioctl(fd, ZT_SPECIFY, &chan)) { 00900 x = errno; 00901 close(fd); 00902 errno = x; 00903 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno)); 00904 return -1; 00905 } 00906 } 00907 bs = READ_SIZE; 00908 if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) return -1; 00909 return fd; 00910 }
static struct ast_frame * zt_read | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 4603 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, zt_subchannel::f, zt_pvt::fake_event, zt_pvt::firstradio, ast_frame::frametype, zt_pvt::ignoredtmf, zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needhold, zt_subchannel::needringing, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::oprmode, option_verbose, zt_pvt::outgoing, zt_pvt::overlapdial, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::radio, ast_channel::rawreadformat, READ_SIZE, restore_conference(), ast_channel::rings, zt_pvt::ringt, S_OR, ast_frame::samples, send_callerid(), zt_pvt::sig, SIG_PRI, ast_frame::src, SUB_CALLWAIT, SUB_REAL, ast_frame::subclass, zt_pvt::subs, zt_pvt::tdd, tdd_feed(), ast_channel::tech_pvt, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_callwait(), zt_get_index(), zt_handle_dtmfup(), and zt_setlinear().
04604 { 04605 struct zt_pvt *p = ast->tech_pvt; 04606 int res; 04607 int index; 04608 void *readbuf; 04609 struct ast_frame *f; 04610 04611 04612 ast_mutex_lock(&p->lock); 04613 04614 index = zt_get_index(ast, p, 0); 04615 04616 /* Hang up if we don't really exist */ 04617 if (index < 0) { 04618 ast_log(LOG_WARNING, "We dont exist?\n"); 04619 ast_mutex_unlock(&p->lock); 04620 return NULL; 04621 } 04622 04623 if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL; 04624 04625 p->subs[index].f.frametype = AST_FRAME_NULL; 04626 p->subs[index].f.datalen = 0; 04627 p->subs[index].f.samples = 0; 04628 p->subs[index].f.mallocd = 0; 04629 p->subs[index].f.offset = 0; 04630 p->subs[index].f.subclass = 0; 04631 p->subs[index].f.delivery = ast_tv(0,0); 04632 p->subs[index].f.src = "zt_read"; 04633 p->subs[index].f.data = NULL; 04634 04635 /* make sure it sends initial key state as first frame */ 04636 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio)) 04637 { 04638 ZT_PARAMS ps; 04639 04640 ps.channo = p->channel; 04641 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 04642 ast_mutex_unlock(&p->lock); 04643 return NULL; 04644 } 04645 p->firstradio = 1; 04646 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04647 if (ps.rxisoffhook) 04648 { 04649 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04650 } 04651 else 04652 { 04653 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 04654 } 04655 ast_mutex_unlock(&p->lock); 04656 return &p->subs[index].f; 04657 } 04658 if (p->ringt == 1) { 04659 ast_mutex_unlock(&p->lock); 04660 return NULL; 04661 } 04662 else if (p->ringt > 0) 04663 p->ringt--; 04664 04665 if (p->subs[index].needringing) { 04666 /* Send ringing frame if requested */ 04667 p->subs[index].needringing = 0; 04668 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04669 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04670 ast_setstate(ast, AST_STATE_RINGING); 04671 ast_mutex_unlock(&p->lock); 04672 return &p->subs[index].f; 04673 } 04674 04675 if (p->subs[index].needbusy) { 04676 /* Send busy frame if requested */ 04677 p->subs[index].needbusy = 0; 04678 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04679 p->subs[index].f.subclass = AST_CONTROL_BUSY; 04680 ast_mutex_unlock(&p->lock); 04681 return &p->subs[index].f; 04682 } 04683 04684 if (p->subs[index].needcongestion) { 04685 /* Send congestion frame if requested */ 04686 p->subs[index].needcongestion = 0; 04687 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04688 p->subs[index].f.subclass = AST_CONTROL_CONGESTION; 04689 ast_mutex_unlock(&p->lock); 04690 return &p->subs[index].f; 04691 } 04692 04693 if (p->subs[index].needcallerid) { 04694 ast_set_callerid(ast, S_OR(p->lastcid_num, NULL), 04695 S_OR(p->lastcid_name, NULL), 04696 S_OR(p->lastcid_num, NULL) 04697 ); 04698 p->subs[index].needcallerid = 0; 04699 } 04700 04701 if (p->subs[index].needanswer) { 04702 /* Send answer frame if requested */ 04703 p->subs[index].needanswer = 0; 04704 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04705 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04706 ast_mutex_unlock(&p->lock); 04707 return &p->subs[index].f; 04708 } 04709 04710 if (p->subs[index].needflash) { 04711 /* Send answer frame if requested */ 04712 p->subs[index].needflash = 0; 04713 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04714 p->subs[index].f.subclass = AST_CONTROL_FLASH; 04715 ast_mutex_unlock(&p->lock); 04716 return &p->subs[index].f; 04717 } 04718 04719 if (p->subs[index].needhold) { 04720 /* Send answer frame if requested */ 04721 p->subs[index].needhold = 0; 04722 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04723 p->subs[index].f.subclass = AST_CONTROL_HOLD; 04724 ast_mutex_unlock(&p->lock); 04725 ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name); 04726 return &p->subs[index].f; 04727 } 04728 04729 if (p->subs[index].needunhold) { 04730 /* Send answer frame if requested */ 04731 p->subs[index].needunhold = 0; 04732 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04733 p->subs[index].f.subclass = AST_CONTROL_UNHOLD; 04734 ast_mutex_unlock(&p->lock); 04735 ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name); 04736 return &p->subs[index].f; 04737 } 04738 04739 if (ast->rawreadformat == AST_FORMAT_SLINEAR) { 04740 if (!p->subs[index].linear) { 04741 p->subs[index].linear = 1; 04742 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04743 if (res) 04744 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index); 04745 } 04746 } else if ((ast->rawreadformat == AST_FORMAT_ULAW) || 04747 (ast->rawreadformat == AST_FORMAT_ALAW)) { 04748 if (p->subs[index].linear) { 04749 p->subs[index].linear = 0; 04750 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04751 if (res) 04752 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index); 04753 } 04754 } else { 04755 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat)); 04756 ast_mutex_unlock(&p->lock); 04757 return NULL; 04758 } 04759 readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET; 04760 CHECK_BLOCKING(ast); 04761 res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04762 ast_clear_flag(ast, AST_FLAG_BLOCKING); 04763 /* Check for hangup */ 04764 if (res < 0) { 04765 f = NULL; 04766 if (res == -1) { 04767 if (errno == EAGAIN) { 04768 /* Return "NULL" frame if there is nobody there */ 04769 ast_mutex_unlock(&p->lock); 04770 return &p->subs[index].f; 04771 } else if (errno == ELAST) { 04772 f = __zt_exception(ast); 04773 } else 04774 ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno)); 04775 } 04776 ast_mutex_unlock(&p->lock); 04777 return f; 04778 } 04779 if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) { 04780 ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04781 f = __zt_exception(ast); 04782 ast_mutex_unlock(&p->lock); 04783 return f; 04784 } 04785 if (p->tdd) { /* if in TDD mode, see if we receive that */ 04786 int c; 04787 04788 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 04789 if (c < 0) { 04790 ast_log(LOG_DEBUG,"tdd_feed failed\n"); 04791 ast_mutex_unlock(&p->lock); 04792 return NULL; 04793 } 04794 if (c) { /* if a char to return */ 04795 p->subs[index].f.subclass = 0; 04796 p->subs[index].f.frametype = AST_FRAME_TEXT; 04797 p->subs[index].f.mallocd = 0; 04798 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04799 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET; 04800 p->subs[index].f.datalen = 1; 04801 *((char *) p->subs[index].f.data) = c; 04802 ast_mutex_unlock(&p->lock); 04803 return &p->subs[index].f; 04804 } 04805 } 04806 if (p->callwaitingrepeat) 04807 p->callwaitingrepeat--; 04808 if (p->cidcwexpire) 04809 p->cidcwexpire--; 04810 /* Repeat callwaiting */ 04811 if (p->callwaitingrepeat == 1) { 04812 p->callwaitrings++; 04813 zt_callwait(ast); 04814 } 04815 /* Expire CID/CW */ 04816 if (p->cidcwexpire == 1) { 04817 if (option_verbose > 2) 04818 ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n"); 04819 restore_conference(p); 04820 } 04821 if (p->subs[index].linear) { 04822 p->subs[index].f.datalen = READ_SIZE * 2; 04823 } else 04824 p->subs[index].f.datalen = READ_SIZE; 04825 04826 /* Handle CallerID Transmission */ 04827 if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) { 04828 send_callerid(p); 04829 } 04830 04831 p->subs[index].f.frametype = AST_FRAME_VOICE; 04832 p->subs[index].f.subclass = ast->rawreadformat; 04833 p->subs[index].f.samples = READ_SIZE; 04834 p->subs[index].f.mallocd = 0; 04835 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04836 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]); 04837 #if 0 04838 ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name); 04839 #endif 04840 if (p->dialing || /* Transmitting something */ 04841 (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 04842 ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 04843 ) { 04844 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 04845 don't send anything */ 04846 p->subs[index].f.frametype = AST_FRAME_NULL; 04847 p->subs[index].f.subclass = 0; 04848 p->subs[index].f.samples = 0; 04849 p->subs[index].f.mallocd = 0; 04850 p->subs[index].f.offset = 0; 04851 p->subs[index].f.data = NULL; 04852 p->subs[index].f.datalen= 0; 04853 } 04854 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) { 04855 /* Perform busy detection. etc on the zap line */ 04856 f = ast_dsp_process(ast, p->dsp, &p->subs[index].f); 04857 if (f) { 04858 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) { 04859 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 04860 /* Treat this as a "hangup" instead of a "busy" on the assumption that 04861 a busy */ 04862 f = NULL; 04863 } 04864 } else if (f->frametype == AST_FRAME_DTMF) { 04865 #ifdef HAVE_PRI 04866 if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) { 04867 /* Don't accept in-band DTMF when in overlap dial mode */ 04868 f->frametype = AST_FRAME_NULL; 04869 f->subclass = 0; 04870 } 04871 #endif 04872 /* DSP clears us of being pulse */ 04873 p->pulsedial = 0; 04874 } 04875 } 04876 } else 04877 f = &p->subs[index].f; 04878 04879 if (f && (f->frametype == AST_FRAME_DTMF)) 04880 zt_handle_dtmfup(ast, index, &f); 04881 04882 /* If we have a fake_event, trigger exception to handle it */ 04883 if (p->fake_event) 04884 ast_set_flag(ast, AST_FLAG_EXCEPTION); 04885 04886 ast_mutex_unlock(&p->lock); 04887 return f; 04888 }
static struct ast_channel * zt_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
Definition at line 7717 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, LOG_WARNING, zt_pvt::next, option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::prev, restart_monitor(), s, zt_pvt::sig, SIG_FXSKS, strsep(), SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::transfercapability, zt_subchannel::zfd, and zt_new().
07718 { 07719 int groupmatch = 0; 07720 int channelmatch = -1; 07721 int roundrobin = 0; 07722 int callwait = 0; 07723 int busy = 0; 07724 struct zt_pvt *p; 07725 struct ast_channel *tmp = NULL; 07726 char *dest=NULL; 07727 int x; 07728 char *s; 07729 char opt=0; 07730 int res=0, y=0; 07731 int backwards = 0; 07732 #ifdef HAVE_PRI 07733 int crv; 07734 int bearer = -1; 07735 int trunkgroup; 07736 struct zt_pri *pri=NULL; 07737 #endif 07738 struct zt_pvt *exit, *start, *end; 07739 ast_mutex_t *lock; 07740 int channelmatched = 0; 07741 int groupmatched = 0; 07742 07743 /* Assume we're locking the iflock */ 07744 lock = &iflock; 07745 start = iflist; 07746 end = ifend; 07747 if (data) { 07748 dest = ast_strdupa((char *)data); 07749 } else { 07750 ast_log(LOG_WARNING, "Channel requested with no data\n"); 07751 return NULL; 07752 } 07753 if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') { 07754 /* Retrieve the group number */ 07755 char *stringp=NULL; 07756 stringp=dest + 1; 07757 s = strsep(&stringp, "/"); 07758 if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 07759 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data); 07760 return NULL; 07761 } 07762 groupmatch = 1 << x; 07763 if (toupper(dest[0]) == 'G') { 07764 if (dest[0] == 'G') { 07765 backwards = 1; 07766 p = ifend; 07767 } else 07768 p = iflist; 07769 } else { 07770 if (dest[0] == 'R') { 07771 backwards = 1; 07772 p = round_robin[x]?round_robin[x]->prev:ifend; 07773 if (!p) 07774 p = ifend; 07775 } else { 07776 p = round_robin[x]?round_robin[x]->next:iflist; 07777 if (!p) 07778 p = iflist; 07779 } 07780 roundrobin = 1; 07781 } 07782 } else { 07783 char *stringp=NULL; 07784 stringp=dest; 07785 s = strsep(&stringp, "/"); 07786 p = iflist; 07787 if (!strcasecmp(s, "pseudo")) { 07788 /* Special case for pseudo */ 07789 x = CHAN_PSEUDO; 07790 channelmatch = x; 07791 } 07792 #ifdef HAVE_PRI 07793 else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) { 07794 if ((trunkgroup < 1) || (crv < 1)) { 07795 ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data); 07796 return NULL; 07797 } 07798 res--; 07799 for (x = 0; x < NUM_SPANS; x++) { 07800 if (pris[x].trunkgroup == trunkgroup) { 07801 pri = pris + x; 07802 lock = &pri->lock; 07803 start = pri->crvs; 07804 end = pri->crvend; 07805 break; 07806 } 07807 } 07808 if (!pri) { 07809 ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup); 07810 return NULL; 07811 } 07812 channelmatch = crv; 07813 p = pris[x].crvs; 07814 } 07815 #endif 07816 else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 07817 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data); 07818 return NULL; 07819 } else { 07820 channelmatch = x; 07821 } 07822 } 07823 /* Search for an unowned channel */ 07824 ast_mutex_lock(lock); 07825 exit = p; 07826 while (p && !tmp) { 07827 if (roundrobin) 07828 round_robin[x] = p; 07829 #if 0 07830 ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch); 07831 #endif 07832 07833 if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) { 07834 if (option_debug) 07835 ast_log(LOG_DEBUG, "Using channel %d\n", p->channel); 07836 if (p->inalarm) 07837 goto next; 07838 07839 callwait = (p->owner != NULL); 07840 #ifdef HAVE_PRI 07841 if (pri && (p->subs[SUB_REAL].zfd < 0)) { 07842 if (p->sig != SIG_FXSKS) { 07843 /* Gotta find an actual channel to use for this 07844 CRV if this isn't a callwait */ 07845 bearer = pri_find_empty_chan(pri, 0); 07846 if (bearer < 0) { 07847 ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv); 07848 p = NULL; 07849 break; 07850 } 07851 pri_assign_bearer(p, pri, pri->pvts[bearer]); 07852 } else { 07853 if (alloc_sub(p, 0)) { 07854 ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n"); 07855 p = NULL; 07856 break; 07857 } else 07858 ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n"); 07859 p->pri = pri; 07860 } 07861 } 07862 #endif 07863 if (p->channel == CHAN_PSEUDO) { 07864 p = chandup(p); 07865 if (!p) { 07866 break; 07867 } 07868 } 07869 if (p->owner) { 07870 if (alloc_sub(p, SUB_CALLWAIT)) { 07871 p = NULL; 07872 break; 07873 } 07874 } 07875 p->outgoing = 1; 07876 tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0); 07877 #ifdef HAVE_PRI 07878 if (p->bearer) { 07879 /* Log owner to bearer channel, too */ 07880 p->bearer->owner = tmp; 07881 } 07882 #endif 07883 /* Make special notes */ 07884 if (res > 1) { 07885 if (opt == 'c') { 07886 /* Confirm answer */ 07887 p->confirmanswer = 1; 07888 } else if (opt == 'r') { 07889 /* Distinctive ring */ 07890 if (res < 3) 07891 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data); 07892 else 07893 p->distinctivering = y; 07894 } else if (opt == 'd') { 07895 /* If this is an ISDN call, make it digital */ 07896 p->digital = 1; 07897 if (tmp) 07898 tmp->transfercapability = AST_TRANS_CAP_DIGITAL; 07899 } else { 07900 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data); 07901 } 07902 } 07903 /* Note if the call is a call waiting call */ 07904 if (tmp && callwait) 07905 tmp->cdrflags |= AST_CDR_CALLWAIT; 07906 break; 07907 } 07908 next: 07909 if (backwards) { 07910 p = p->prev; 07911 if (!p) 07912 p = end; 07913 } else { 07914 p = p->next; 07915 if (!p) 07916 p = start; 07917 } 07918 /* stop when you roll to the one that we started from */ 07919 if (p == exit) 07920 break; 07921 } 07922 ast_mutex_unlock(lock); 07923 restart_monitor(); 07924 if (callwait) 07925 *cause = AST_CAUSE_BUSY; 07926 else if (!tmp) { 07927 if (channelmatched) { 07928 if (busy) 07929 *cause = AST_CAUSE_BUSY; 07930 } else if (groupmatched) { 07931 *cause = AST_CAUSE_CONGESTION; 07932 } 07933 } 07934 07935 return tmp; 07936 }
static int zt_ring_phone | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3449 of file chan_zap.c.
References ast_log(), LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), and zt_handle_event().
03450 { 03451 int x; 03452 int res; 03453 /* Make sure our transmit state is on hook */ 03454 x = 0; 03455 x = ZT_ONHOOK; 03456 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03457 do { 03458 x = ZT_RING; 03459 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03460 if (res) { 03461 switch (errno) { 03462 case EBUSY: 03463 case EINTR: 03464 /* Wait just in case */ 03465 usleep(10000); 03466 continue; 03467 case EINPROGRESS: 03468 res = 0; 03469 break; 03470 default: 03471 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 03472 res = 0; 03473 } 03474 } 03475 } while (res); 03476 return res; 03477 }
static int zt_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 11328 of file chan_zap.c.
References ASCII_BYTES_PER_CHAR, ast_check_hangup(), AST_LAW, ast_log(), ast_malloc, zt_pvt::channel, END_SILENCE_LEN, pollfd::events, pollfd::fd, free, HEADER_LEN, HEADER_MS, LOG_DEBUG, LOG_ERROR, LOG_WARNING, zt_pvt::mate, option_debug, poll(), POLLOUT, PUT_CLID, PUT_CLID_MARKMS, READ_SIZE, pollfd::revents, zt_pvt::subs, zt_pvt::tdd, TDD_BYTES_PER_CHAR, tdd_generate(), ast_channel::tech_pvt, TRAILER_MS, zt_subchannel::zfd, and zt_get_index().
11329 { 11330 #define END_SILENCE_LEN 400 11331 #define HEADER_MS 50 11332 #define TRAILER_MS 5 11333 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 11334 #define ASCII_BYTES_PER_CHAR 80 11335 11336 unsigned char *buf,*mybuf; 11337 struct zt_pvt *p = c->tech_pvt; 11338 struct pollfd fds[1]; 11339 int size,res,fd,len,x; 11340 int bytes=0; 11341 /* Initial carrier (imaginary) */ 11342 float cr = 1.0; 11343 float ci = 0.0; 11344 float scont = 0.0; 11345 int index; 11346 11347 index = zt_get_index(c, p, 0); 11348 if (index < 0) { 11349 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 11350 return -1; 11351 } 11352 if (!text[0]) return(0); /* if nothing to send, dont */ 11353 if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ 11354 if (p->mate) 11355 buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 11356 else 11357 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 11358 if (!buf) 11359 return -1; 11360 mybuf = buf; 11361 if (p->mate) { 11362 int codec = AST_LAW(p); 11363 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */ 11364 PUT_CLID_MARKMS; 11365 } 11366 /* Put actual message */ 11367 for (x = 0; text[x]; x++) { 11368 PUT_CLID(text[x]); 11369 } 11370 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */ 11371 PUT_CLID_MARKMS; 11372 } 11373 len = bytes; 11374 buf = mybuf; 11375 } else { 11376 len = tdd_generate(p->tdd, buf, text); 11377 if (len < 1) { 11378 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text)); 11379 free(mybuf); 11380 return -1; 11381 } 11382 } 11383 memset(buf + len, 0x7f, END_SILENCE_LEN); 11384 len += END_SILENCE_LEN; 11385 fd = p->subs[index].zfd; 11386 while (len) { 11387 if (ast_check_hangup(c)) { 11388 free(mybuf); 11389 return -1; 11390 } 11391 size = len; 11392 if (size > READ_SIZE) 11393 size = READ_SIZE; 11394 fds[0].fd = fd; 11395 fds[0].events = POLLOUT | POLLPRI; 11396 fds[0].revents = 0; 11397 res = poll(fds, 1, -1); 11398 if (!res) { 11399 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 11400 continue; 11401 } 11402 /* if got exception */ 11403 if (fds[0].revents & POLLPRI) 11404 return -1; 11405 if (!(fds[0].revents & POLLOUT)) { 11406 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 11407 continue; 11408 } 11409 res = write(fd, buf, size); 11410 if (res != size) { 11411 if (res == -1) { 11412 free(mybuf); 11413 return -1; 11414 } 11415 if (option_debug) 11416 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 11417 break; 11418 } 11419 len -= size; 11420 buf += size; 11421 } 11422 free(mybuf); 11423 return(0); 11424 }
static int zt_set_hook | ( | int | fd, | |
int | hs | |||
) | [inline, static] |
Definition at line 1608 of file chan_zap.c.
References ast_log(), and LOG_WARNING.
Referenced by __zt_exception(), handle_init_event(), mkintf(), ss_thread(), zt_answer(), zt_handle_event(), zt_hangup(), zt_indicate(), and zt_wink().
01609 { 01610 int x, res; 01611 01612 x = hs; 01613 res = ioctl(fd, ZT_HOOK, &x); 01614 01615 if (res < 0) { 01616 if (errno == EINPROGRESS) 01617 return 0; 01618 ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno)); 01619 } 01620 01621 return res; 01622 }
static int zt_setlinear | ( | int | zfd, | |
int | linear | |||
) | [static] |
Definition at line 918 of file chan_zap.c.
Referenced by send_callerid(), ss_thread(), zt_hangup(), zt_new(), zt_read(), and zt_write().
00919 { 00920 int res; 00921 res = ioctl(zfd, ZT_SETLINEAR, &linear); 00922 if (res) 00923 return res; 00924 return 0; 00925 }
static int zt_setoption | ( | struct ast_channel * | chan, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2817 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, 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().
02818 { 02819 char *cp; 02820 signed char *scp; 02821 int x; 02822 int index; 02823 struct zt_pvt *p = chan->tech_pvt, *pp; 02824 struct oprmode *oprmode; 02825 02826 02827 /* all supported options require data */ 02828 if (!data || (datalen < 1)) { 02829 errno = EINVAL; 02830 return -1; 02831 } 02832 02833 switch (option) { 02834 case AST_OPTION_TXGAIN: 02835 scp = (signed char *) data; 02836 index = zt_get_index(chan, p, 0); 02837 if (index < 0) { 02838 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 02839 return -1; 02840 } 02841 if (option_debug) 02842 ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp); 02843 return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law); 02844 case AST_OPTION_RXGAIN: 02845 scp = (signed char *) data; 02846 index = zt_get_index(chan, p, 0); 02847 if (index < 0) { 02848 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 02849 return -1; 02850 } 02851 if (option_debug) 02852 ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp); 02853 return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law); 02854 case AST_OPTION_TONE_VERIFY: 02855 if (!p->dsp) 02856 break; 02857 cp = (char *) data; 02858 switch (*cp) { 02859 case 1: 02860 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name); 02861 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 02862 break; 02863 case 2: 02864 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name); 02865 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 02866 break; 02867 default: 02868 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name); 02869 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 02870 break; 02871 } 02872 break; 02873 case AST_OPTION_TDD: 02874 /* turn on or off TDD */ 02875 cp = (char *) data; 02876 p->mate = 0; 02877 if (!*cp) { /* turn it off */ 02878 if (option_debug) 02879 ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name); 02880 if (p->tdd) 02881 tdd_free(p->tdd); 02882 p->tdd = 0; 02883 break; 02884 } 02885 ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n", 02886 (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name); 02887 zt_disable_ec(p); 02888 /* otherwise, turn it on */ 02889 if (!p->didtdd) { /* if havent done it yet */ 02890 unsigned char mybuf[41000], *buf; 02891 int size, res, fd, len; 02892 struct pollfd fds[1]; 02893 02894 buf = mybuf; 02895 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 02896 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 02897 len = 40000; 02898 index = zt_get_index(chan, p, 0); 02899 if (index < 0) { 02900 ast_log(LOG_WARNING, "No index in TDD?\n"); 02901 return -1; 02902 } 02903 fd = p->subs[index].zfd; 02904 while (len) { 02905 if (ast_check_hangup(chan)) 02906 return -1; 02907 size = len; 02908 if (size > READ_SIZE) 02909 size = READ_SIZE; 02910 fds[0].fd = fd; 02911 fds[0].events = POLLPRI | POLLOUT; 02912 fds[0].revents = 0; 02913 res = poll(fds, 1, -1); 02914 if (!res) { 02915 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 02916 continue; 02917 } 02918 /* if got exception */ 02919 if (fds[0].revents & POLLPRI) 02920 return -1; 02921 if (!(fds[0].revents & POLLOUT)) { 02922 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 02923 continue; 02924 } 02925 res = write(fd, buf, size); 02926 if (res != size) { 02927 if (res == -1) return -1; 02928 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 02929 break; 02930 } 02931 len -= size; 02932 buf += size; 02933 } 02934 p->didtdd = 1; /* set to have done it now */ 02935 } 02936 if (*cp == 2) { /* Mate mode */ 02937 if (p->tdd) 02938 tdd_free(p->tdd); 02939 p->tdd = 0; 02940 p->mate = 1; 02941 break; 02942 } 02943 if (!p->tdd) { /* if we dont have one yet */ 02944 p->tdd = tdd_new(); /* allocate one */ 02945 } 02946 break; 02947 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 02948 if (!p->dsp) 02949 break; 02950 cp = (char *) data; 02951 ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n", 02952 *cp ? "ON" : "OFF", (int) *cp, chan->name); 02953 p->dtmfrelax = 0; 02954 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 02955 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 02956 break; 02957 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 02958 cp = (char *) data; 02959 if (!*cp) { 02960 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name); 02961 x = 0; 02962 zt_disable_ec(p); 02963 } else { 02964 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name); 02965 x = 1; 02966 } 02967 if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1) 02968 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x); 02969 break; 02970 case AST_OPTION_OPRMODE: /* Operator services mode */ 02971 oprmode = (struct oprmode *) data; 02972 pp = oprmode->peer->tech_pvt; 02973 p->oprmode = pp->oprmode = 0; 02974 /* setup peers */ 02975 p->oprpeer = pp; 02976 pp->oprpeer = p; 02977 /* setup modes, if any */ 02978 if (oprmode->mode) 02979 { 02980 pp->oprmode = oprmode->mode; 02981 p->oprmode = -oprmode->mode; 02982 } 02983 ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n", 02984 oprmode->mode, chan->name,oprmode->peer->name);; 02985 break; 02986 case AST_OPTION_ECHOCAN: 02987 cp = (char *) data; 02988 if (*cp) { 02989 ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name); 02990 zt_enable_ec(p); 02991 } else { 02992 ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name); 02993 zt_disable_ec(p); 02994 } 02995 break; 02996 } 02997 errno = 0; 02998 02999 return 0; 03000 }
static void zt_train_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1440 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echotraining, LOG_DEBUG, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_answer(), and zt_handle_event().
01441 { 01442 int x; 01443 int res; 01444 if (p && p->echocancel && p->echotraining) { 01445 x = p->echotraining; 01446 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x); 01447 if (res) 01448 ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel); 01449 else { 01450 ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel); 01451 } 01452 } else 01453 ast_log(LOG_DEBUG, "No echo training requested\n"); 01454 }
Definition at line 3021 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), zt_pvt::channel, conf_del(), zt_pvt::inconference, zt_pvt::lock, LOG_DEBUG, zt_pvt::master, MAX_SLAVES, zt_pvt::slaves, SUB_REAL, zt_pvt::subs, and update_conf().
Referenced by zt_bridge(), and zt_fixup().
03022 { 03023 /* Unlink a specific slave or all slaves/masters from a given master */ 03024 int x; 03025 int hasslaves; 03026 if (!master) 03027 return; 03028 if (needlock) { 03029 ast_mutex_lock(&master->lock); 03030 if (slave) { 03031 while (ast_mutex_trylock(&slave->lock)) { 03032 ast_mutex_unlock(&master->lock); 03033 usleep(1); 03034 ast_mutex_lock(&master->lock); 03035 } 03036 } 03037 } 03038 hasslaves = 0; 03039 for (x = 0; x < MAX_SLAVES; x++) { 03040 if (master->slaves[x]) { 03041 if (!slave || (master->slaves[x] == slave)) { 03042 /* Take slave out of the conference */ 03043 ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 03044 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 03045 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 03046 master->slaves[x]->master = NULL; 03047 master->slaves[x] = NULL; 03048 } else 03049 hasslaves = 1; 03050 } 03051 if (!hasslaves) 03052 master->inconference = 0; 03053 } 03054 if (!slave) { 03055 if (master->master) { 03056 /* Take master out of the conference */ 03057 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 03058 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 03059 hasslaves = 0; 03060 for (x = 0; x < MAX_SLAVES; x++) { 03061 if (master->master->slaves[x] == master) 03062 master->master->slaves[x] = NULL; 03063 else if (master->master->slaves[x]) 03064 hasslaves = 1; 03065 } 03066 if (!hasslaves) 03067 master->master->inconference = 0; 03068 } 03069 master->master = NULL; 03070 } 03071 update_conf(master); 03072 if (needlock) { 03073 if (slave) 03074 ast_mutex_unlock(&slave->lock); 03075 ast_mutex_unlock(&master->lock); 03076 } 03077 }
static int zt_wait_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_waitevent which ignores a bunch of events.
Definition at line 265 of file chan_zap.c.
Referenced by flash_exec(), and ss_thread().
00266 { 00267 int i, j = 0; 00268 i = ZT_IOMUX_SIGEVENT; 00269 if (ioctl(fd, ZT_IOMUX, &i) == -1) 00270 return -1; 00271 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00272 return -1; 00273 return j; 00274 }
static int zt_wink | ( | struct zt_pvt * | p, | |
int | index | |||
) | [static] |
Definition at line 5382 of file chan_zap.c.
References zt_pvt::subs, zt_subchannel::zfd, and zt_set_hook().
Referenced by ss_thread().
05383 { 05384 int j; 05385 zt_set_hook(p->subs[index].zfd, ZT_WINK); 05386 for (;;) 05387 { 05388 /* set bits of interest */ 05389 j = ZT_IOMUX_SIGEVENT; 05390 /* wait for some happening */ 05391 if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1); 05392 /* exit loop if we have it */ 05393 if (j & ZT_IOMUX_SIGEVENT) break; 05394 } 05395 /* get the event info */ 05396 if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1); 05397 return 0; 05398 }
static int zt_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 4913 of file chan_zap.c.
References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::channel, zt_pvt::cidspill, ast_frame::data, ast_frame::datalen, zt_pvt::dialing, zt_pvt::digital, ast_frame::frametype, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, my_zt_write(), option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::sig, SIG_PRI, zt_pvt::span, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_setlinear().
04914 { 04915 struct zt_pvt *p = ast->tech_pvt; 04916 int res; 04917 unsigned char outbuf[4096]; 04918 int index; 04919 index = zt_get_index(ast, p, 0); 04920 if (index < 0) { 04921 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name); 04922 return -1; 04923 } 04924 04925 #if 0 04926 #ifdef HAVE_PRI 04927 ast_mutex_lock(&p->lock); 04928 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 04929 if (p->pri->pri) { 04930 if (!pri_grab(p, p->pri)) { 04931 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 04932 pri_rel(p->pri); 04933 } else 04934 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04935 } 04936 p->proceeding=1; 04937 } 04938 ast_mutex_unlock(&p->lock); 04939 #endif 04940 #endif 04941 /* Write a frame of (presumably voice) data */ 04942 if (frame->frametype != AST_FRAME_VOICE) { 04943 if (frame->frametype != AST_FRAME_IMAGE) 04944 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 04945 return 0; 04946 } 04947 if ((frame->subclass != AST_FORMAT_SLINEAR) && 04948 (frame->subclass != AST_FORMAT_ULAW) && 04949 (frame->subclass != AST_FORMAT_ALAW)) { 04950 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass); 04951 return -1; 04952 } 04953 if (p->dialing) { 04954 if (option_debug) 04955 ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name); 04956 return 0; 04957 } 04958 if (!p->owner) { 04959 if (option_debug) 04960 ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name); 04961 return 0; 04962 } 04963 if (p->cidspill) { 04964 if (option_debug) 04965 ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n"); 04966 return 0; 04967 } 04968 /* Return if it's not valid data */ 04969 if (!frame->data || !frame->datalen) 04970 return 0; 04971 if (frame->datalen > sizeof(outbuf) * 2) { 04972 ast_log(LOG_WARNING, "Frame too large\n"); 04973 return 0; 04974 } 04975 04976 if (frame->subclass == AST_FORMAT_SLINEAR) { 04977 if (!p->subs[index].linear) { 04978 p->subs[index].linear = 1; 04979 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04980 if (res) 04981 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 04982 } 04983 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1); 04984 } else { 04985 /* x-law already */ 04986 if (p->subs[index].linear) { 04987 p->subs[index].linear = 0; 04988 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04989 if (res) 04990 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 04991 } 04992 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0); 04993 } 04994 if (res < 0) { 04995 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 04996 return -1; 04997 } 04998 return 0; 04999 }
int alarm |
struct { ... } alarms[] [static] |
Referenced by alarm2str(), and zap_show_status().
struct zt_ring_cadence cadences[NUM_CADENCE_MAX] [static] |
Definition at line 739 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 750 of file chan_zap.c.
const char config[] = "zapata.conf" [static] |
Definition at line 165 of file chan_zap.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 109 of file chan_zap.c.
char defaultcic[64] = "" [static] |
Definition at line 204 of file chan_zap.c.
char defaultozz[64] = "" [static] |
Definition at line 205 of file chan_zap.c.
char destroy_channel_usage[] [static] |
Initial value:
"Usage: zap destroy channel <chan num>\n" " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n"
Definition at line 10088 of file chan_zap.c.
int distinctiveringaftercid = 0 [static] |
Definition at line 209 of file chan_zap.c.
struct zt_distRings drings [static] |
char* events[] [static] |
int firstdigittimeout = 16000 [static] |
int gendigittimeout = 8000 [static] |
struct ast_jb_conf global_jbconf [static] |
Definition at line 116 of file chan_zap.c.
int ifcount = 0 [static] |
Definition at line 235 of file chan_zap.c.
int matchdigittimeout = 3000 [static] |
How long to wait for an extra digit, if there is an ambiguous match.
Definition at line 229 of file chan_zap.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 247 of file chan_zap.c.
char* name |
Definition at line 1119 of file chan_zap.c.
int num_cadence = 4 [static] |
Definition at line 736 of file chan_zap.c.
int numbufs = 4 [static] |
Definition at line 211 of file chan_zap.c.
char progzone[10] = "" [static] |
Definition at line 207 of file chan_zap.c.
int ringt_base = DEFAULT_RINGT [static] |
Definition at line 290 of file chan_zap.c.
struct zt_pvt* round_robin[32] |
Definition at line 713 of file chan_zap.c.
char show_channel_usage[] [static] |
Initial value:
"Usage: zap show channel <chan num>\n" " Detailed information about a given channel\n"
Definition at line 10080 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 10076 of file chan_zap.c.
char* subnames[] [static] |
const char tdesc[] = "Zapata Telephony Driver" [static] |
Definition at line 159 of file chan_zap.c.
int user_has_defined_cadences = 0 [static] |
Definition at line 737 of file chan_zap.c.
struct ast_cli_entry zap_cli[] [static] |
Definition at line 10099 of file chan_zap.c.
char zap_restart_usage[] [static] |
Definition at line 10092 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 9984 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 10084 of file chan_zap.c.
struct ast_channel_tech zap_tech [static] |
Definition at line 686 of file chan_zap.c.