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