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