#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 "asterisk/devicestate.h"
Go to the source code of this file.
Data Structures | |
struct | distRingData |
struct | ringContextData |
struct | zt_chan_conf |
Channel configuration from zapata.conf . This struct is used for parsing the [channels] section of zapata.conf. Generally there is a field here for every possible configuration item. More... | |
struct | zt_distRings |
struct | zt_pvt |
struct | zt_subchannel |
Defines | |
#define | ASCII_BYTES_PER_CHAR 80 |
#define | AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
#define | CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
#define | CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
#define | CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define | CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
#define | CHAN_PSEUDO -2 |
#define | CHANNEL_PSEUDO -12 |
#define | CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
#define | CONF_USER_REAL (1 << 0) |
#define | CONF_USER_THIRDCALL (1 << 1) |
#define | DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
#define | DCHAN_NOTINALARM (1 << 1) |
#define | DCHAN_PROVISIONED (1 << 0) |
#define | DCHAN_UP (1 << 2) |
#define | DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID. | |
#define | DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
#define | END_SILENCE_LEN 400 |
#define | FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" |
#define | FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define | FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" |
#define | FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define | GET_CHANNEL(p) ((p)->channel) |
#define | HANGUP 1 |
#define | HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
#define | HEADER_MS 50 |
#define | ISTRUNK(p) |
#define | MASK_AVAIL (1 << 0) |
#define | MASK_INUSE (1 << 1) |
#define | MAX_CHANLIST_LEN 80 |
#define | MAX_CHANNELS 672 |
#define | MAX_SLAVES 4 |
#define | MIN_MS_SINCE_FLASH ( (2000) ) |
#define | NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) |
Signaling types that need to use MF detection should be placed in this macro. | |
#define | NUM_CADENCE_MAX 25 |
#define | NUM_DCHANS 4 |
#define | NUM_SPANS 128 |
#define | POLARITY_IDLE 0 |
#define | POLARITY_REV 1 |
#define | READ_SIZE 160 |
#define | sig2str zap_sig2str |
#define | SIG_E911 (0x1000000 | ZT_SIG_EM) |
#define | SIG_EM ZT_SIG_EM |
#define | SIG_EM_E1 ZT_SIG_EM_E1 |
#define | SIG_EMWINK (0x0100000 | ZT_SIG_EM) |
#define | SIG_FEATB (0x0800000 | ZT_SIG_EM) |
#define | SIG_FEATD (0x0200000 | ZT_SIG_EM) |
#define | SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
#define | SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM) |
#define | SIG_FGC_CAMA (0x4000000 | ZT_SIG_EM) |
#define | SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM) |
#define | SIG_FXOGS ZT_SIG_FXOGS |
#define | SIG_FXOKS ZT_SIG_FXOKS |
#define | SIG_FXOLS ZT_SIG_FXOLS |
#define | SIG_FXSGS ZT_SIG_FXSGS |
#define | SIG_FXSKS ZT_SIG_FXSKS |
#define | SIG_FXSLS ZT_SIG_FXSLS |
#define | SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) |
#define | SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS) |
#define | SIG_GSM (0x100000 | ZT_SIG_CLEAR) |
#define | SIG_PRI ZT_SIG_CLEAR |
#define | SIG_SF ZT_SIG_SF |
#define | SIG_SF_FEATB (0x0800000 | ZT_SIG_SF) |
#define | SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) |
#define | SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF) |
#define | SIG_SFWINK (0x0100000 | ZT_SIG_SF) |
#define | SMDI_MD_WAIT_TIMEOUT 1500 |
#define | SUB_CALLWAIT 1 |
#define | SUB_REAL 0 |
#define | SUB_THREEWAY 2 |
#define | tdesc "Zapata Telephony" |
#define | TRAILER_MS 5 |
#define | TRANSFER 0 |
#define | ZT_EVENT_DTMFDOWN 0 |
#define | ZT_EVENT_DTMFUP 0 |
Functions | |
static int | __unload_module (void) |
static struct ast_frame * | __zt_exception (struct ast_channel *ast) |
static int | action_transfer (struct mansession *s, const struct message *m) |
static int | action_transferhangup (struct mansession *s, const struct message *m) |
static int | action_zapdialoffhook (struct mansession *s, const struct message *m) |
static int | action_zapdndoff (struct mansession *s, const struct message *m) |
static int | action_zapdndon (struct mansession *s, const struct message *m) |
static int | action_zaprestart (struct mansession *s, const struct message *m) |
static int | action_zapshowchannels (struct mansession *s, const struct message *m) |
static char * | alarm2str (int alarm) |
static int | alloc_sub (struct zt_pvt *p, int x) |
static int | app_zapEC (struct ast_channel *chan, void *data) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
Protect the interface list (of zt_pvt's). | |
static int | attempt_transfer (struct zt_pvt *p) |
static int | available (struct zt_pvt *p, int channelmatch, 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_devicestate (void *data) |
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 *dest, const char *text, int ispdu) |
static int | zt_set_hook (int fd, int hs) |
static int | zt_setlaw (int zfd, int law) |
static int | zt_setlinear (int zfd, int linear) |
static int | zt_setoption (struct ast_channel *chan, int option, void *data, int datalen) |
static int | zt_tdd_sendtext (struct ast_channel *c, const char *text) |
static void | zt_train_ec (struct zt_pvt *p) |
static void | zt_unlink (struct zt_pvt *slave, struct zt_pvt *master, int needlock) |
static int | zt_wait_event (int fd) |
Avoid the silly zt_waitevent which ignores a bunch of events. | |
static int | zt_wink (struct zt_pvt *p, int index) |
static int | zt_write (struct ast_channel *ast, struct ast_frame *frame) |
Variables | |
struct { | |
int alarm | |
char * name | |
} | alarms [] |
static struct zt_ring_cadence | cadences [NUM_CADENCE_MAX] |
static int | cidrings [NUM_CADENCE_MAX] |
cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on. | |
static const char | config [] = "zapata.conf" |
static struct ast_jb_conf | default_jbconf |
static char | defaultcic [64] = "" |
static char | defaultozz [64] = "" |
static char | destroy_channel_usage [] |
static int | distinctiveringaftercid = 0 |
static struct zt_distRings | drings |
static char * | events [] |
static int | firstdigittimeout = 16000 |
Wait up to 16 seconds for first digit (FXO logic). | |
static int | gendigittimeout = 8000 |
How long to wait for following digits (FXO logic). | |
static struct ast_jb_conf | global_jbconf |
static char | gsm_modem_exten [AST_MAX_EXTENSION] |
static char | gsm_modem_pin [20] |
static int | ifcount = 0 |
static struct zt_pvt * | ifend |
static struct zt_pvt * | iflist |
static int | matchdigittimeout = 3000 |
How long to wait for an extra digit, if there is an ambiguous match. | |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static int | num_cadence = 4 |
static int | numbufs = 4 |
static char | progzone [10] = "" |
static int | ringt_base = DEFAULT_RINGT |
struct zt_pvt * | round_robin [32] |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char * | subnames [] |
static const char | tdesc [] = "Zapata Telephony Driver" |
static int | user_has_defined_cadences = 0 |
static struct ast_cli_entry | zap_cli [] |
static char | zap_restart_usage [] |
static char | zap_show_cadences_help [] |
static char | zap_show_status_usage [] |
static struct ast_channel_tech | zap_tech |
static char * | zapEC_app = "zapEC" |
static char * | zapEC_synopsis = "Enable/Disable Echo Cancelation on a Zap channel" |
static char * | zapEC_tdesc = "Enable/disable Echo cancelation" |
Connects to the zaptel telephony library as well as libpri. Libpri is optional and needed only if you are going to use ISDN connections.
You need to install libraries before you attempt to compile and install the zaptel channel.
Definition in file chan_zap.c.
#define ASCII_BYTES_PER_CHAR 80 |
Referenced by zt_tdd_sendtext().
#define AST_LAW | ( | p | ) | (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
Definition at line 164 of file chan_zap.c.
Referenced by do_monitor(), send_cwcidspill(), ss_thread(), zt_call(), zt_callwait(), and zt_tdd_sendtext().
#define CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
#define CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
300 ms
Definition at line 290 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 207 of file chan_zap.c.
Referenced by build_channels(), enable_dtmf_detect(), mkintf(), process_zap(), zt_devicestate(), zt_new(), and zt_request().
#define CHANNEL_PSEUDO -12 |
Definition at line 162 of file chan_zap.c.
#define CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
#define CONF_USER_REAL (1 << 0) |
Definition at line 455 of file chan_zap.c.
#define CONF_USER_THIRDCALL (1 << 1) |
Definition at line 456 of file chan_zap.c.
#define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
#define DCHAN_NOTINALARM (1 << 1) |
Definition at line 210 of file chan_zap.c.
#define DCHAN_PROVISIONED (1 << 0) |
Definition at line 209 of file chan_zap.c.
#define DCHAN_UP (1 << 2) |
#define DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID.
Define if you want to check the hook state for an FXO (FXS signalled) interface before dialing on it. Certain FXO interfaces always think they're out of service with this method however.
Definition at line 160 of file chan_zap.c.
Referenced by zt_chan_conf_default().
#define DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
Definition at line 294 of file chan_zap.c.
#define END_SILENCE_LEN 400 |
Referenced by zt_tdd_sendtext().
#define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" |
#define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" |
#define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
#define GET_CHANNEL | ( | p | ) | ((p)->channel) |
#define HANGUP 1 |
Definition at line 11960 of file chan_zap.c.
Referenced by action_transferhangup(), and zap_fake_event().
#define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
Referenced by build_alerting(), build_connect(), build_connect_acknowledge(), build_disconnect(), build_facility(), build_hold(), build_hold_acknowledge(), build_hold_reject(), build_information(), build_notify(), build_proceeding(), build_progress(), build_release(), build_release_complete(), build_restart(), build_resume(), build_resume_acknowledge(), build_resume_reject(), build_retrieve(), build_retrieve_acknowledge(), build_retrieve_reject(), build_setup(), build_setup_acknowledge(), build_status(), build_status_enquiry(), build_suspend(), build_suspend_acknowledge(), build_suspend_reject(), build_timeout(), build_user_information(), parse_alerting(), parse_connect(), parse_disconnect(), parse_facility(), parse_information(), parse_proceeding(), parse_progress(), parse_release(), parse_release_complete(), parse_restart(), parse_setup(), parse_setup_acknowledge(), parse_status(), and zt_tdd_sendtext().
#define HEADER_MS 50 |
Referenced by zt_tdd_sendtext().
#define ISTRUNK | ( | p | ) |
#define MASK_AVAIL (1 << 0) |
Channel available for PRI use
Definition at line 287 of file chan_zap.c.
#define MASK_INUSE (1 << 1) |
Channel currently in use
Definition at line 288 of file chan_zap.c.
#define MAX_CHANLIST_LEN 80 |
The length of the parameters list of 'zapchan'.
Definition at line 12324 of file chan_zap.c.
Referenced by process_zap().
#define MAX_CHANNELS 672 |
No more than a DS3 per trunk group
Definition at line 205 of file chan_zap.c.
Referenced by mkintf().
#define MAX_SLAVES 4 |
Definition at line 458 of file chan_zap.c.
Referenced by isslavenative(), update_conf(), zap_show_channel(), zt_link(), and zt_unlink().
#define MIN_MS_SINCE_FLASH ( (2000) ) |
#define NEED_MFDETECT | ( | p | ) | (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) |
Signaling types that need to use MF detection should be placed in this macro.
Definition at line 167 of file chan_zap.c.
Referenced by ss_thread(), and zt_new().
#define NUM_CADENCE_MAX 25 |
#define NUM_DCHANS 4 |
No more than 4 d-channels
Definition at line 204 of file chan_zap.c.
Referenced by zt_devicestate().
#define NUM_SPANS 128 |
"32 spans", muahahaha, us alaws like to have some more...
Definition at line 203 of file chan_zap.c.
#define POLARITY_IDLE 0 |
Definition at line 412 of file chan_zap.c.
Referenced by ss_thread(), unalloc_sub(), zt_handle_event(), and zt_hangup().
#define POLARITY_REV 1 |
Definition at line 413 of file chan_zap.c.
Referenced by handle_init_event(), ss_thread(), and zt_handle_event().
#define READ_SIZE 160 |
Chunk size to read -- we use 20ms chunks to make things happy.
Definition at line 285 of file chan_zap.c.
Referenced by my_zt_write(), process_zap(), send_cwcidspill(), zt_callwait(), zt_open(), zt_read(), zt_setoption(), and zt_tdd_sendtext().
#define sig2str zap_sig2str |
Definition at line 1406 of file chan_zap.c.
Referenced by action_zapshowchannels(), build_channels(), handle_init_event(), mkintf(), ss_thread(), zap_show_channel(), and zt_handle_event().
#define SIG_E911 (0x1000000 | ZT_SIG_EM) |
Definition at line 182 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EM ZT_SIG_EM |
Definition at line 177 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EM_E1 ZT_SIG_EM_E1 |
Definition at line 199 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_EMWINK (0x0100000 | ZT_SIG_EM) |
Definition at line 178 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATB (0x0800000 | ZT_SIG_EM) |
Definition at line 181 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATD (0x0200000 | ZT_SIG_EM) |
Definition at line 179 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
Definition at line 180 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM) |
Definition at line 183 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FGC_CAMA (0x4000000 | ZT_SIG_EM) |
Definition at line 184 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM) |
Definition at line 185 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_FXOGS ZT_SIG_FXOGS |
Definition at line 190 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
#define SIG_FXOKS ZT_SIG_FXOKS |
Definition at line 191 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 189 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
#define SIG_FXSGS ZT_SIG_FXSGS |
Definition at line 187 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_indicate().
#define SIG_FXSKS ZT_SIG_FXSKS |
Definition at line 188 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 186 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_indicate().
#define SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) |
Definition at line 200 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 201 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), and zap_sig2str().
#define SIG_GSM (0x100000 | ZT_SIG_CLEAR) |
Definition at line 193 of file chan_zap.c.
Referenced by mkintf(), process_zap(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_hangup(), and zt_sendtext().
#define SIG_PRI ZT_SIG_CLEAR |
Definition at line 192 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_digit_begin(), zt_digit_end(), zt_enable_ec(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), zt_read(), zt_sendtext(), and zt_write().
#define SIG_SF ZT_SIG_SF |
Definition at line 194 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATB (0x0800000 | ZT_SIG_SF) |
Definition at line 198 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) |
Definition at line 196 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF) |
Definition at line 197 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SIG_SFWINK (0x0100000 | ZT_SIG_SF) |
Definition at line 195 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
#define SMDI_MD_WAIT_TIMEOUT 1500 |
#define SUB_CALLWAIT 1 |
Call-Waiting call on hold
Definition at line 408 of file chan_zap.c.
#define SUB_REAL 0 |
Active call
Definition at line 407 of file chan_zap.c.
#define SUB_THREEWAY 2 |
Three-way call
Definition at line 409 of file chan_zap.c.
#define tdesc "Zapata Telephony" |
Definition at line 13391 of file chan_zap.c.
#define TRAILER_MS 5 |
Referenced by zt_tdd_sendtext().
#define TRANSFER 0 |
#define ZT_EVENT_DTMFDOWN 0 |
#define ZT_EVENT_DTMFUP 0 |
static int __unload_module | ( | void | ) | [static] |
Definition at line 12141 of file chan_zap.c.
References ast_channel_unregister(), ast_cli_unregister(), ast_cli_unregister_multiple(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_unregister_application(), ast_verbose(), zt_pvt::channel, zt_pvt::cidspill, destroy_zt_pvt(), free, iflist, master, zt_pvt::next, zt_pvt::owner, zt_pvt::subs, VERBOSE_PREFIX_3, zt_subchannel::zfd, and zt_close().
12142 { 12143 int x; 12144 struct zt_pvt *p, *pl; 12145 12146 #ifdef HAVE_PRI 12147 int i; 12148 for (i = 0; i < NUM_SPANS; i++) { 12149 if (pris[i].master != AST_PTHREADT_NULL) 12150 pthread_cancel(pris[i].master); 12151 } 12152 ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 12153 ast_unregister_application(zap_send_keypad_facility_app); 12154 ast_unregister_application(zapCD_app); 12155 ast_unregister_application(zapInband_app); 12156 #endif 12157 #ifdef HAVE_GSMAT 12158 ast_cli_unregister_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0])); 12159 ast_cli_unregister(&gsm_send_sms); 12160 ast_cli_unregister(&gsm_send_pdu); 12161 ast_cli_unregister(&gsm_show_status); 12162 #endif 12163 ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 12164 ast_unregister_application(zapEC_app); 12165 ast_manager_unregister( "ZapDialOffhook" ); 12166 ast_manager_unregister( "ZapHangup" ); 12167 ast_manager_unregister( "ZapTransfer" ); 12168 ast_manager_unregister( "ZapDNDoff" ); 12169 ast_manager_unregister( "ZapDNDon" ); 12170 ast_manager_unregister("ZapShowChannels"); 12171 ast_manager_unregister("ZapRestart"); 12172 ast_channel_unregister(&zap_tech); 12173 ast_mutex_lock(&iflock); 12174 /* Hangup all interfaces if they have an owner */ 12175 p = iflist; 12176 while (p) { 12177 if (p->owner) 12178 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 12179 p = p->next; 12180 } 12181 ast_mutex_unlock(&iflock); 12182 ast_mutex_lock(&monlock); 12183 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 12184 pthread_cancel(monitor_thread); 12185 pthread_kill(monitor_thread, SIGURG); 12186 pthread_join(monitor_thread, NULL); 12187 } 12188 monitor_thread = AST_PTHREADT_STOP; 12189 ast_mutex_unlock(&monlock); 12190 12191 ast_mutex_lock(&iflock); 12192 /* Destroy all the interfaces and free their memory */ 12193 p = iflist; 12194 while (p) { 12195 /* Free any callerid */ 12196 if (p->cidspill) 12197 free(p->cidspill); 12198 /* Close the zapata thingy */ 12199 if (p->subs[SUB_REAL].zfd > -1) 12200 zt_close(p->subs[SUB_REAL].zfd); 12201 pl = p; 12202 p = p->next; 12203 x = pl->channel; 12204 /* Free associated memory */ 12205 if (pl) 12206 destroy_zt_pvt(&pl); 12207 ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x); 12208 } 12209 iflist = NULL; 12210 ifcount = 0; 12211 ast_mutex_unlock(&iflock); 12212 #ifdef HAVE_PRI 12213 for (i = 0; i < NUM_SPANS; i++) { 12214 if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) 12215 pthread_join(pris[i].master, NULL); 12216 zt_close(pris[i].fds[i]); 12217 } 12218 #endif 12219 return 0; 12220 }
static struct ast_frame* __zt_exception | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 4779 of file chan_zap.c.
References ast_channel::_state, ast_bridged_channel(), AST_CONTROL_UNHOLD, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_pvt::callwaitingrepeat, zt_pvt::channel, zt_pvt::cidcwexpire, ast_frame::data, ast_frame::datalen, ast_frame::delivery, zt_pvt::dialing, event2str(), zt_subchannel::f, zt_pvt::fake_event, ast_channel::fds, zt_pvt::flashtime, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, zt_subchannel::needanswer, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::oprmode, option_debug, option_verbose, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, ast_frame::samples, ast_frame::src, SUB_REAL, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_disable_ec(), zt_get_event(), zt_get_index(), zt_handle_event(), zt_ring_phone(), and zt_set_hook().
Referenced by zt_exception(), and zt_read().
04780 { 04781 struct zt_pvt *p = ast->tech_pvt; 04782 int res; 04783 int usedindex=-1; 04784 int index; 04785 struct ast_frame *f; 04786 04787 04788 index = zt_get_index(ast, p, 1); 04789 04790 p->subs[index].f.frametype = AST_FRAME_NULL; 04791 p->subs[index].f.datalen = 0; 04792 p->subs[index].f.samples = 0; 04793 p->subs[index].f.mallocd = 0; 04794 p->subs[index].f.offset = 0; 04795 p->subs[index].f.subclass = 0; 04796 p->subs[index].f.delivery = ast_tv(0,0); 04797 p->subs[index].f.src = "zt_exception"; 04798 p->subs[index].f.data = NULL; 04799 04800 04801 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) { 04802 /* If nobody owns us, absorb the event appropriately, otherwise 04803 we loop indefinitely. This occurs when, during call waiting, the 04804 other end hangs up our channel so that it no longer exists, but we 04805 have neither FLASH'd nor ONHOOK'd to signify our desire to 04806 change to the other channel. */ 04807 if (p->fake_event) { 04808 res = p->fake_event; 04809 p->fake_event = 0; 04810 } else 04811 res = zt_get_event(p->subs[SUB_REAL].zfd); 04812 /* Switch to real if there is one and this isn't something really silly... */ 04813 if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) && 04814 (res != ZT_EVENT_HOOKCOMPLETE)) { 04815 ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res); 04816 p->owner = p->subs[SUB_REAL].owner; 04817 if (p->owner && ast_bridged_channel(p->owner)) 04818 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04819 p->subs[SUB_REAL].needunhold = 1; 04820 } 04821 switch (res) { 04822 case ZT_EVENT_ONHOOK: 04823 zt_disable_ec(p); 04824 if (p->owner) { 04825 if (option_verbose > 2) 04826 ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name); 04827 zt_ring_phone(p); 04828 p->callwaitingrepeat = 0; 04829 p->cidcwexpire = 0; 04830 } else 04831 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04832 update_conf(p); 04833 break; 04834 case ZT_EVENT_RINGOFFHOOK: 04835 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 04836 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 04837 p->subs[SUB_REAL].needanswer = 1; 04838 p->dialing = 0; 04839 } 04840 break; 04841 case ZT_EVENT_HOOKCOMPLETE: 04842 case ZT_EVENT_RINGERON: 04843 case ZT_EVENT_RINGEROFF: 04844 /* Do nothing */ 04845 break; 04846 case ZT_EVENT_WINKFLASH: 04847 gettimeofday(&p->flashtime, NULL); 04848 if (p->owner) { 04849 if (option_verbose > 2) 04850 ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 04851 if (p->owner->_state != AST_STATE_UP) { 04852 /* Answer if necessary */ 04853 usedindex = zt_get_index(p->owner, p, 0); 04854 if (usedindex > -1) { 04855 p->subs[usedindex].needanswer = 1; 04856 } 04857 ast_setstate(p->owner, AST_STATE_UP); 04858 } 04859 p->callwaitingrepeat = 0; 04860 p->cidcwexpire = 0; 04861 if (ast_bridged_channel(p->owner)) 04862 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04863 p->subs[SUB_REAL].needunhold = 1; 04864 } else 04865 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04866 update_conf(p); 04867 break; 04868 default: 04869 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 04870 } 04871 f = &p->subs[index].f; 04872 return f; 04873 } 04874 if (!(p->radio || (p->oprmode < 0)) && option_debug) 04875 ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 04876 /* If it's not us, return NULL immediately */ 04877 if (ast != p->owner) { 04878 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 04879 f = &p->subs[index].f; 04880 return f; 04881 } 04882 f = zt_handle_event(ast); 04883 return f; 04884 }
static int action_transfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 12028 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), TRANSFER, and zap_fake_event().
Referenced by load_module().
12029 { 12030 struct zt_pvt *p = NULL; 12031 const char *channel = astman_get_header(m, "ZapChannel"); 12032 12033 if (ast_strlen_zero(channel)) { 12034 astman_send_error(s, m, "No channel specified"); 12035 return 0; 12036 } 12037 p = find_channel(atoi(channel)); 12038 if (!p) { 12039 astman_send_error(s, m, "No such channel"); 12040 return 0; 12041 } 12042 zap_fake_event(p,TRANSFER); 12043 astman_send_ack(s, m, "ZapTransfer"); 12044 return 0; 12045 }
static int action_transferhangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 12047 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), HANGUP, and zap_fake_event().
Referenced by load_module().
12048 { 12049 struct zt_pvt *p = NULL; 12050 const char *channel = astman_get_header(m, "ZapChannel"); 12051 12052 if (ast_strlen_zero(channel)) { 12053 astman_send_error(s, m, "No channel specified"); 12054 return 0; 12055 } 12056 p = find_channel(atoi(channel)); 12057 if (!p) { 12058 astman_send_error(s, m, "No such channel"); 12059 return 0; 12060 } 12061 zap_fake_event(p,HANGUP); 12062 astman_send_ack(s, m, "ZapHangup"); 12063 return 0; 12064 }
static int action_zapdialoffhook | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 12066 of file chan_zap.c.
References AST_FRAME_DTMF, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), zt_pvt::owner, and zap_queue_frame().
Referenced by load_module().
12067 { 12068 struct zt_pvt *p = NULL; 12069 const char *channel = astman_get_header(m, "ZapChannel"); 12070 const char *number = astman_get_header(m, "Number"); 12071 int i; 12072 12073 if (ast_strlen_zero(channel)) { 12074 astman_send_error(s, m, "No channel specified"); 12075 return 0; 12076 } 12077 if (ast_strlen_zero(number)) { 12078 astman_send_error(s, m, "No number specified"); 12079 return 0; 12080 } 12081 p = find_channel(atoi(channel)); 12082 if (!p) { 12083 astman_send_error(s, m, "No such channel"); 12084 return 0; 12085 } 12086 if (!p->owner) { 12087 astman_send_error(s, m, "Channel does not have it's owner"); 12088 return 0; 12089 } 12090 for (i = 0; i < strlen(number); i++) { 12091 struct ast_frame f = { AST_FRAME_DTMF, number[i] }; 12092 zap_queue_frame(p, &f, NULL); 12093 } 12094 astman_send_ack(s, m, "ZapDialOffhook"); 12095 return 0; 12096 }
static int action_zapdndoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 12009 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, and find_channel().
Referenced by load_module().
12010 { 12011 struct zt_pvt *p = NULL; 12012 const char *channel = astman_get_header(m, "ZapChannel"); 12013 12014 if (ast_strlen_zero(channel)) { 12015 astman_send_error(s, m, "No channel specified"); 12016 return 0; 12017 } 12018 p = find_channel(atoi(channel)); 12019 if (!p) { 12020 astman_send_error(s, m, "No such channel"); 12021 return 0; 12022 } 12023 p->dnd = 0; 12024 astman_send_ack(s, m, "DND Disabled"); 12025 return 0; 12026 }
static int action_zapdndon | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11990 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, and find_channel().
Referenced by load_module().
11991 { 11992 struct zt_pvt *p = NULL; 11993 const char *channel = astman_get_header(m, "ZapChannel"); 11994 11995 if (ast_strlen_zero(channel)) { 11996 astman_send_error(s, m, "No channel specified"); 11997 return 0; 11998 } 11999 p = find_channel(atoi(channel)); 12000 if (!p) { 12001 astman_send_error(s, m, "No such channel"); 12002 return 0; 12003 } 12004 p->dnd = 1; 12005 astman_send_ack(s, m, "DND Enabled"); 12006 return 0; 12007 }
static int action_zaprestart | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 11617 of file chan_zap.c.
References astman_send_ack(), astman_send_error(), and zap_restart().
Referenced by load_module().
11618 { 11619 if (zap_restart() != 0) { 11620 astman_send_error(s, m, "Failed rereading zaptel configuration"); 11621 return 1; 11622 } 11623 astman_send_ack(s, m, "ZapRestart: Success"); 11624 return 0; 11625 }
static int action_zapshowchannels | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 12098 of file chan_zap.c.
References alarm, alarm2str(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), zt_pvt::channel, zt_pvt::context, zt_pvt::dnd, get_alarms(), iflist, zt_pvt::next, zt_pvt::sig, and sig2str.
Referenced by load_module().
12099 { 12100 struct zt_pvt *tmp = NULL; 12101 const char *id = astman_get_header(m, "ActionID"); 12102 char idText[256] = ""; 12103 12104 astman_send_ack(s, m, "Zapata channel status will follow"); 12105 if (!ast_strlen_zero(id)) 12106 snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id); 12107 12108 ast_mutex_lock(&iflock); 12109 12110 tmp = iflist; 12111 while (tmp) { 12112 if (tmp->channel > 0) { 12113 int alarm = get_alarms(tmp); 12114 astman_append(s, 12115 "Event: ZapShowChannels\r\n" 12116 "Channel: %d\r\n" 12117 "Signalling: %s\r\n" 12118 "Context: %s\r\n" 12119 "DND: %s\r\n" 12120 "Alarm: %s\r\n" 12121 "%s" 12122 "\r\n", 12123 tmp->channel, sig2str(tmp->sig), tmp->context, 12124 tmp->dnd ? "Enabled" : "Disabled", 12125 alarm2str(alarm), idText); 12126 } 12127 12128 tmp = tmp->next; 12129 } 12130 12131 ast_mutex_unlock(&iflock); 12132 12133 astman_append(s, 12134 "Event: ZapShowChannelsComplete\r\n" 12135 "%s" 12136 "\r\n", 12137 idText); 12138 return 0; 12139 }
static char* alarm2str | ( | int | alarm | ) | [static] |
Definition at line 1315 of file chan_zap.c.
References alarms.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
01316 { 01317 int x; 01318 for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) { 01319 if (alarms[x].alarm & alarm) 01320 return alarms[x].name; 01321 } 01322 return alarm ? "Unknown Alarm" : "No Alarm"; 01323 }
static int alloc_sub | ( | struct zt_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 1113 of file chan_zap.c.
References ast_log(), zt_subchannel::chan, zt_pvt::channel, errno, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::subs, zt_subchannel::zfd, zt_close(), and zt_open().
Referenced by ss_thread(), zt_handle_event(), and zt_request().
01114 { 01115 ZT_BUFFERINFO bi; 01116 int res; 01117 if (p->subs[x].zfd < 0) { 01118 p->subs[x].zfd = zt_open("/dev/zap/pseudo"); 01119 if (p->subs[x].zfd > -1) { 01120 res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi); 01121 if (!res) { 01122 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 01123 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 01124 bi.numbufs = numbufs; 01125 res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi); 01126 if (res < 0) { 01127 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x); 01128 } 01129 } else 01130 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x); 01131 if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) { 01132 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd); 01133 zt_close(p->subs[x].zfd); 01134 p->subs[x].zfd = -1; 01135 return -1; 01136 } 01137 if (option_debug) 01138 ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan); 01139 return 0; 01140 } else 01141 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 01142 return -1; 01143 } 01144 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel); 01145 return -1; 01146 }
static int app_zapEC | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 11536 of file chan_zap.c.
References ast_log(), ast_verbose(), LOG_WARNING, option_verbose, ast_channel::tech, ast_channel::tech_pvt, ast_channel_tech::type, VERBOSE_PREFIX_3, zt_disable_ec(), and zt_enable_ec().
Referenced by load_module().
11537 { 11538 int res=-1; 11539 struct zt_pvt *p = NULL; 11540 11541 if (!data) { 11542 ast_log(LOG_WARNING, "zapEC requires one argument (on | off)\n"); 11543 } 11544 if (chan && !strcasecmp("ZAP",chan->tech->type)) { 11545 p = chan->tech_pvt; 11546 if (!p) return res; 11547 if (!strcasecmp("on",(char *)data)) { 11548 zt_enable_ec(p); 11549 res = 0; 11550 if (option_verbose > 3) { 11551 ast_verbose(VERBOSE_PREFIX_3 "Enabled echo cancelation on channel %s.\n", chan->name); 11552 } 11553 } else if (!strcasecmp("off",(char *)data)) { 11554 zt_disable_ec(p); 11555 res = 0; 11556 if (option_verbose > 3) { 11557 ast_verbose(VERBOSE_PREFIX_3 "Disabled echo cancelation on channel %s.\n", chan->name); 11558 } 11559 } else { 11560 ast_log(LOG_WARNING, "Unknown argument %s to zapEC\n", (char *)data); 11561 } 11562 } else { 11563 ast_log(LOG_WARNING, "zapNoEC only works on ZAP channels, check your extensions.conf!\n"); 11564 res = 0; 11565 } 11566 11567 return res; 11568 }
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 3777 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_indicate(), ast_log(), ast_mutex_unlock(), ast_queue_control(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_RINGING, ast_channel::cdr, ast_channel::lock, LOG_DEBUG, LOG_WARNING, zt_subchannel::owner, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), unalloc_sub(), and zt_subchannel::zfd.
03778 { 03779 /* In order to transfer, we need at least one of the channels to 03780 actually be in a call bridge. We can't conference two applications 03781 together (but then, why would we want to?) */ 03782 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 03783 /* The three-way person we're about to transfer to could still be in MOH, so 03784 stop if now if appropriate */ 03785 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 03786 ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 03787 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 03788 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 03789 } 03790 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) { 03791 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 03792 } 03793 if (p->subs[SUB_REAL].owner->cdr) { 03794 /* Move CDR from second channel to current one */ 03795 p->subs[SUB_THREEWAY].owner->cdr = 03796 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr); 03797 p->subs[SUB_REAL].owner->cdr = NULL; 03798 } 03799 if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) { 03800 /* Move CDR from second channel's bridge to current one */ 03801 p->subs[SUB_THREEWAY].owner->cdr = 03802 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr); 03803 ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL; 03804 } 03805 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 03806 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03807 ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name); 03808 return -1; 03809 } 03810 /* Orphan the channel after releasing the lock */ 03811 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03812 unalloc_sub(p, SUB_THREEWAY); 03813 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 03814 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 03815 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 03816 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 03817 } 03818 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) { 03819 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 03820 } 03821 if (p->subs[SUB_THREEWAY].owner->cdr) { 03822 /* Move CDR from second channel to current one */ 03823 p->subs[SUB_REAL].owner->cdr = 03824 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr); 03825 p->subs[SUB_THREEWAY].owner->cdr = NULL; 03826 } 03827 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) { 03828 /* Move CDR from second channel's bridge to current one */ 03829 p->subs[SUB_REAL].owner->cdr = 03830 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr); 03831 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL; 03832 } 03833 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 03834 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03835 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name); 03836 return -1; 03837 } 03838 /* Three-way is now the REAL */ 03839 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03840 ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock); 03841 unalloc_sub(p, SUB_THREEWAY); 03842 /* Tell the caller not to hangup */ 03843 return 1; 03844 } else { 03845 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 03846 p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name); 03847 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03848 return -1; 03849 } 03850 return 0; 03851 }
static int available | ( | struct zt_pvt * | p, | |
int | channelmatch, | |||
int | groupmatch, | |||
int * | busy, | |||
int * | channelmatched, | |||
int * | groupmatched | |||
) | [inline, static] |
Definition at line 7950 of file chan_zap.c.
References ast_channel::_state, ast_log(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::callwaiting, zt_pvt::channel, zt_pvt::dnd, zt_pvt::group, zt_pvt::guardtime, zt_subchannel::inthreeway, LOG_DEBUG, LOG_WARNING, zt_pvt::oprmode, zt_pvt::outgoing, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_request().
07951 { 07952 int res; 07953 ZT_PARAMS par; 07954 07955 /* First, check group matching */ 07956 if (groupmatch) { 07957 if ((p->group & groupmatch) != groupmatch) 07958 return 0; 07959 *groupmatched = 1; 07960 } 07961 /* Check to see if we have a channel match */ 07962 if (channelmatch != -1) { 07963 if (p->channel != channelmatch) 07964 return 0; 07965 *channelmatched = 1; 07966 } 07967 /* We're at least busy at this point */ 07968 if (busy) { 07969 if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS)) 07970 *busy = 1; 07971 } 07972 /* If do not disturb, definitely not */ 07973 if (p->dnd) 07974 return 0; 07975 /* If guard time, definitely not */ 07976 if (p->guardtime && (time(NULL) < p->guardtime)) 07977 return 0; 07978 07979 /* If no owner definitely available */ 07980 if (!p->owner) { 07981 #ifdef HAVE_PRI 07982 /* Trust PRI */ 07983 if (p->pri) { 07984 if (p->resetting || p->call) 07985 return 0; 07986 else 07987 return 1; 07988 } 07989 #endif 07990 #ifdef HAVE_GSMAT 07991 if (p->gsm.modul) { 07992 return gsm_available(p->gsm.modul); 07993 } 07994 07995 #endif 07996 if (!(p->radio || (p->oprmode < 0))) 07997 { 07998 if (!p->sig || (p->sig == SIG_FXSLS)) 07999 return 1; 08000 /* Check hook state */ 08001 if (p->subs[SUB_REAL].zfd > -1) 08002 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 08003 else { 08004 /* Assume not off hook on CVRS */ 08005 res = 0; 08006 par.rxisoffhook = 0; 08007 } 08008 if (res) { 08009 ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel); 08010 } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 08011 /* When "onhook" that means no battery on the line, and thus 08012 it is out of service..., if it's on a TDM card... If it's a channel 08013 bank, there is no telling... */ 08014 if (par.rxbits > -1) 08015 return 1; 08016 if (par.rxisoffhook) 08017 return 1; 08018 else 08019 #ifdef ZAP_CHECK_HOOKSTATE 08020 return 0; 08021 #else 08022 return 1; 08023 #endif 08024 } else if (par.rxisoffhook) { 08025 ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel); 08026 /* Not available when the other end is off hook */ 08027 return 0; 08028 } 08029 } 08030 return 1; 08031 } 08032 08033 /* If it's not an FXO, forget about call wait */ 08034 if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 08035 return 0; 08036 08037 if (!p->callwaiting) { 08038 /* If they don't have call waiting enabled, then for sure they're unavailable at this point */ 08039 return 0; 08040 } 08041 08042 if (p->subs[SUB_CALLWAIT].zfd > -1) { 08043 /* If there is already a call waiting call, then we can't take a second one */ 08044 return 0; 08045 } 08046 08047 if ((p->owner->_state != AST_STATE_UP) && 08048 ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) { 08049 /* If the current call is not up, then don't allow the call */ 08050 return 0; 08051 } 08052 if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) { 08053 /* Can't take a call wait when the three way calling hasn't been merged yet. */ 08054 return 0; 08055 } 08056 /* We're cool */ 08057 return 1; 08058 }
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 12232 of file chan_zap.c.
References ast_log(), ast_strdupa, ast_verbose(), zt_chan_conf::chan, CHAN_PSEUDO, LOG_ERROR, LOG_WARNING, mkintf(), option_verbose, zt_pvt::sig, sig2str, strsep(), and VERBOSE_PREFIX_3.
Referenced by process_zap().
12233 { 12234 char *c, *chan; 12235 int x, start, finish; 12236 struct zt_pvt *tmp; 12237 #ifdef HAVE_PRI 12238 struct zt_pri *pri; 12239 int trunkgroup, y; 12240 #endif 12241 12242 if ((reload == 0) && (conf.chan.sig < 0)) { 12243 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 12244 return -1; 12245 } 12246 12247 c = ast_strdupa(value); 12248 12249 #ifdef HAVE_PRI 12250 pri = NULL; 12251 if (iscrv) { 12252 if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) { 12253 ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno); 12254 return -1; 12255 } 12256 if (trunkgroup < 1) { 12257 ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno); 12258 return -1; 12259 } 12260 c += y; 12261 for (y = 0; y < NUM_SPANS; y++) { 12262 if (pris[y].trunkgroup == trunkgroup) { 12263 pri = pris + y; 12264 break; 12265 } 12266 } 12267 if (!pri) { 12268 ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno); 12269 return -1; 12270 } 12271 } 12272 #endif 12273 12274 while ((chan = strsep(&c, ","))) { 12275 if (sscanf(chan, "%d-%d", &start, &finish) == 2) { 12276 /* Range */ 12277 } else if (sscanf(chan, "%d", &start)) { 12278 /* Just one */ 12279 finish = start; 12280 } else if (!strcasecmp(chan, "pseudo")) { 12281 finish = start = CHAN_PSEUDO; 12282 if (found_pseudo) 12283 *found_pseudo = 1; 12284 } else { 12285 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan); 12286 return -1; 12287 } 12288 if (finish < start) { 12289 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 12290 x = finish; 12291 finish = start; 12292 start = x; 12293 } 12294 12295 for (x = start; x <= finish; x++) { 12296 #ifdef HAVE_PRI 12297 tmp = mkintf(x, conf, pri, reload); 12298 #else 12299 tmp = mkintf(x, conf, NULL, reload); 12300 #endif 12301 12302 if (tmp) { 12303 if (option_verbose > 2) { 12304 #ifdef HAVE_PRI 12305 if (pri) 12306 ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig)); 12307 else 12308 #endif 12309 ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig)); 12310 } 12311 } else { 12312 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n", 12313 (reload == 1) ? "reconfigure" : "register", value); 12314 return -1; 12315 } 12316 } 12317 } 12318 12319 return 0; 12320 }
static int bump_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1772 of file chan_zap.c.
References ast_log(), errno, zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, zt_pvt::txgain, and zt_subchannel::zfd.
Referenced by ss_thread().
01773 { 01774 int res; 01775 01776 /* Bump receive gain by 5.0db */ 01777 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law); 01778 if (res) { 01779 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno)); 01780 return -1; 01781 } 01782 01783 return 0; 01784 }
Definition at line 8060 of file chan_zap.c.
References ast_log(), ast_malloc, ast_mutex_init(), zt_pvt::destroy, destroy_zt_pvt(), errno, iflist, zt_pvt::lock, LOG_ERROR, LOG_WARNING, zt_pvt::next, SUB_REAL, zt_pvt::subs, zt_subchannel::zfd, and zt_open().
Referenced by zt_request().
08061 { 08062 struct zt_pvt *p; 08063 ZT_BUFFERINFO bi; 08064 int res; 08065 08066 if ((p = ast_malloc(sizeof(*p)))) { 08067 memcpy(p, src, sizeof(struct zt_pvt)); 08068 ast_mutex_init(&p->lock); 08069 p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo"); 08070 /* Allocate a zapata structure */ 08071 if (p->subs[SUB_REAL].zfd < 0) { 08072 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 08073 destroy_zt_pvt(&p); 08074 return NULL; 08075 } 08076 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 08077 if (!res) { 08078 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 08079 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 08080 bi.numbufs = numbufs; 08081 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 08082 if (res < 0) { 08083 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n"); 08084 } 08085 } else 08086 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n"); 08087 } 08088 p->destroy = 1; 08089 p->next = iflist; 08090 iflist = p; 08091 return p; 08092 }
static int check_for_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3853 of file chan_zap.c.
References ast_log(), ast_verbose(), zt_pvt::channel, zt_pvt::confno, zt_subchannel::curconf, LOG_WARNING, zt_pvt::master, option_verbose, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, and zt_subchannel::zfd.
Referenced by zt_handle_event().
03854 { 03855 ZT_CONFINFO ci; 03856 /* Fine if we already have a master, etc */ 03857 if (p->master || (p->confno > -1)) 03858 return 0; 03859 memset(&ci, 0, sizeof(ci)); 03860 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 03861 ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel); 03862 return 0; 03863 } 03864 /* If we have no master and don't have a confno, then 03865 if we're in a conference, it's probably a MeetMe room or 03866 some such, so don't let us 3-way out! */ 03867 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 03868 if (option_verbose > 2) 03869 ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n"); 03870 return 1; 03871 } 03872 return 0; 03873 }
static int conf_add | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index, | |||
int | slavechannel | |||
) | [static] |
Definition at line 1408 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().
01409 { 01410 /* If the conference already exists, and we're already in it 01411 don't bother doing anything */ 01412 ZT_CONFINFO zi; 01413 01414 memset(&zi, 0, sizeof(zi)); 01415 zi.chan = 0; 01416 01417 if (slavechannel > 0) { 01418 /* If we have only one slave, do a digital mon */ 01419 zi.confmode = ZT_CONF_DIGITALMON; 01420 zi.confno = slavechannel; 01421 } else { 01422 if (!index) { 01423 /* Real-side and pseudo-side both participate in conference */ 01424 zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER | 01425 ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 01426 } else 01427 zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER; 01428 zi.confno = p->confno; 01429 } 01430 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode)) 01431 return 0; 01432 if (c->zfd < 0) 01433 return 0; 01434 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01435 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno); 01436 return -1; 01437 } 01438 if (slavechannel < 1) { 01439 p->confno = zi.confno; 01440 } 01441 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01442 ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01443 return 0; 01444 }
static int conf_del | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c, | |||
int | index | |||
) | [static] |
Definition at line 1457 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().
01458 { 01459 ZT_CONFINFO zi; 01460 if (/* Can't delete if there's no zfd */ 01461 (c->zfd < 0) || 01462 /* Don't delete from the conference if it's not our conference */ 01463 !isourconf(p, c) 01464 /* Don't delete if we don't think it's conferenced at all (implied) */ 01465 ) return 0; 01466 memset(&zi, 0, sizeof(zi)); 01467 zi.chan = 0; 01468 zi.confno = 0; 01469 zi.confmode = 0; 01470 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01471 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01472 return -1; 01473 } 01474 ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01475 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01476 return 0; 01477 }
Definition at line 2446 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().
02447 { 02448 int owned = 0; 02449 int i = 0; 02450 02451 if (!now) { 02452 if (cur->owner) { 02453 owned = 1; 02454 } 02455 02456 for (i = 0; i < 3; i++) { 02457 if (cur->subs[i].owner) { 02458 owned = 1; 02459 } 02460 } 02461 if (!owned) { 02462 if (prev) { 02463 prev->next = cur->next; 02464 if (prev->next) 02465 prev->next->prev = prev; 02466 else 02467 ifend = prev; 02468 } else { 02469 iflist = cur->next; 02470 if (iflist) 02471 iflist->prev = NULL; 02472 else 02473 ifend = NULL; 02474 } 02475 if (cur->subs[SUB_REAL].zfd > -1) { 02476 zt_close(cur->subs[SUB_REAL].zfd); 02477 } 02478 destroy_zt_pvt(&cur); 02479 } 02480 } else { 02481 if (prev) { 02482 prev->next = cur->next; 02483 if (prev->next) 02484 prev->next->prev = prev; 02485 else 02486 ifend = prev; 02487 } else { 02488 iflist = cur->next; 02489 if (iflist) 02490 iflist->prev = NULL; 02491 else 02492 ifend = NULL; 02493 } 02494 if (cur->subs[SUB_REAL].zfd > -1) { 02495 zt_close(cur->subs[SUB_REAL].zfd); 02496 } 02497 destroy_zt_pvt(&cur); 02498 } 02499 return 0; 02500 }
static void destroy_zt_pvt | ( | struct zt_pvt ** | pvt | ) | [static] |
Definition at line 2431 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().
02432 { 02433 struct zt_pvt *p = *pvt; 02434 /* Remove channel from the list */ 02435 if (p->prev) 02436 p->prev->next = p->next; 02437 if (p->next) 02438 p->next->prev = p->prev; 02439 if (p->use_smdi) 02440 ASTOBJ_UNREF(p->smdi_iface, ast_smdi_interface_destroy); 02441 ast_mutex_destroy(&p->lock); 02442 free(p); 02443 *pvt = NULL; 02444 }
static int digit_to_dtmfindex | ( | char | digit | ) | [static] |
Definition at line 1168 of file chan_zap.c.
Referenced by zt_digit_begin().
01169 { 01170 if (isdigit(digit)) 01171 return ZT_TONE_DTMF_BASE + (digit - '0'); 01172 else if (digit >= 'A' && digit <= 'D') 01173 return ZT_TONE_DTMF_A + (digit - 'A'); 01174 else if (digit >= 'a' && digit <= 'd') 01175 return ZT_TONE_DTMF_A + (digit - 'a'); 01176 else if (digit == '*') 01177 return ZT_TONE_DTMF_s; 01178 else if (digit == '#') 01179 return ZT_TONE_DTMF_p; 01180 else 01181 return -1; 01182 }
static void disable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3378 of file chan_zap.c.
References ast_dsp_set_features(), zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_bridge(), and zt_call().
03379 { 03380 #ifdef ZT_TONEDETECT 03381 int val; 03382 #endif 03383 03384 p->ignoredtmf = 1; 03385 03386 #ifdef ZT_TONEDETECT 03387 val = 0; 03388 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03389 #endif 03390 if (!p->hardwaredtmf && p->dsp) { 03391 p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT; 03392 ast_dsp_set_features(p->dsp, p->dsp_features); 03393 } 03394 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 7104 of file chan_zap.c.
References ast_app_has_voicemail(), ast_calloc, ast_fdisset(), AST_LAW, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), zt_pvt::channel, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, errno, event2str(), pollfd::events, pollfd::fd, free, handle_init_event(), iflist, last, LOG_DEBUG, LOG_WARNING, zt_pvt::mailbox, MAX_CALLERID_SIZE, zt_pvt::msgstate, zt_pvt::next, zt_pvt::onhooktime, option_debug, zt_subchannel::owner, zt_pvt::owner, poll(), POLLIN, POLLPRI, zt_pvt::radio, pollfd::revents, zt_pvt::sig, SUB_REAL, zt_pvt::subs, vmwi_generate(), zt_subchannel::zfd, and zt_get_event().
07105 { 07106 int count, res, res2, spoint, pollres=0; 07107 struct zt_pvt *i; 07108 struct zt_pvt *last = NULL; 07109 time_t thispass = 0, lastpass = 0; 07110 int found; 07111 char buf[1024]; 07112 struct pollfd *pfds=NULL; 07113 int lastalloc = -1; 07114 /* This thread monitors all the frame relay interfaces which are not yet in use 07115 (and thus do not have a separate thread) indefinitely */ 07116 /* From here on out, we die whenever asked */ 07117 #if 0 07118 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 07119 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 07120 return NULL; 07121 } 07122 ast_log(LOG_DEBUG, "Monitor starting...\n"); 07123 #endif 07124 for (;;) { 07125 /* Lock the interface list */ 07126 ast_mutex_lock(&iflock); 07127 if (!pfds || (lastalloc != ifcount)) { 07128 if (pfds) { 07129 free(pfds); 07130 pfds = NULL; 07131 } 07132 if (ifcount) { 07133 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) { 07134 ast_mutex_unlock(&iflock); 07135 return NULL; 07136 } 07137 } 07138 lastalloc = ifcount; 07139 } 07140 /* Build the stuff we're going to poll on, that is the socket of every 07141 zt_pvt that does not have an associated owner channel */ 07142 count = 0; 07143 i = iflist; 07144 while (i) { 07145 if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) { 07146 if (!i->owner && !i->subs[SUB_REAL].owner) { 07147 /* This needs to be watched, as it lacks an owner */ 07148 pfds[count].fd = i->subs[SUB_REAL].zfd; 07149 pfds[count].events = POLLPRI; 07150 pfds[count].revents = 0; 07151 /* Message waiting or r2 channels also get watched for reading */ 07152 if (i->cidspill) 07153 pfds[count].events |= POLLIN; 07154 count++; 07155 } 07156 } 07157 i = i->next; 07158 } 07159 /* Okay, now that we know what to do, release the interface lock */ 07160 ast_mutex_unlock(&iflock); 07161 07162 pthread_testcancel(); 07163 /* Wait at least a second for something to happen */ 07164 res = poll(pfds, count, 1000); 07165 pthread_testcancel(); 07166 /* Okay, poll has finished. Let's see what happened. */ 07167 if (res < 0) { 07168 if ((errno != EAGAIN) && (errno != EINTR)) 07169 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 07170 continue; 07171 } 07172 /* Alright, lock the interface list again, and let's look and see what has 07173 happened */ 07174 ast_mutex_lock(&iflock); 07175 found = 0; 07176 spoint = 0; 07177 lastpass = thispass; 07178 thispass = time(NULL); 07179 i = iflist; 07180 while (i) { 07181 if (thispass != lastpass) { 07182 if (!found && ((i == last) || ((i == iflist) && !last))) { 07183 last = i; 07184 if (last) { 07185 if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) && 07186 (last->sig & __ZT_SIG_FXO)) { 07187 res = ast_app_has_voicemail(last->mailbox, NULL); 07188 if (last->msgstate != res) { 07189 int x; 07190 ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel); 07191 x = ZT_FLUSH_BOTH; 07192 res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 07193 if (res2) 07194 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel); 07195 if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) { 07196 /* Turn on on hook transfer for 4 seconds */ 07197 x = 4000; 07198 ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x); 07199 last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last)); 07200 last->cidpos = 0; 07201 last->msgstate = res; 07202 last->onhooktime = thispass; 07203 } 07204 found ++; 07205 } 07206 } 07207 last = last->next; 07208 } 07209 } 07210 } 07211 if ((i->subs[SUB_REAL].zfd > -1) && i->sig) { 07212 if (i->radio && !i->owner) 07213 { 07214 res = zt_get_event(i->subs[SUB_REAL].zfd); 07215 if (res) 07216 { 07217 if (option_debug) 07218 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 07219 /* Don't hold iflock while handling init events */ 07220 ast_mutex_unlock(&iflock); 07221 handle_init_event(i, res); 07222 ast_mutex_lock(&iflock); 07223 } 07224 i = i->next; 07225 continue; 07226 } 07227 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint); 07228 if (pollres & POLLIN) { 07229 if (i->owner || i->subs[SUB_REAL].owner) { 07230 #ifdef HAVE_PRI 07231 if (!i->pri) 07232 #endif 07233 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd); 07234 i = i->next; 07235 continue; 07236 } 07237 if (!i->cidspill) { 07238 ast_log(LOG_WARNING, "Whoa.... I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd); 07239 i = i->next; 07240 continue; 07241 } 07242 res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf)); 07243 if (res > 0) { 07244 /* We read some number of bytes. Write an equal amount of data */ 07245 if (res > i->cidlen - i->cidpos) 07246 res = i->cidlen - i->cidpos; 07247 res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res); 07248 if (res2 > 0) { 07249 i->cidpos += res2; 07250 if (i->cidpos >= i->cidlen) { 07251 free(i->cidspill); 07252 i->cidspill = 0; 07253 i->cidpos = 0; 07254 i->cidlen = 0; 07255 } 07256 } else { 07257 ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno)); 07258 i->msgstate = -1; 07259 } 07260 } else { 07261 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 07262 } 07263 if (option_debug) 07264 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 07265 /* Don't hold iflock while handling init events -- race with chlock */ 07266 ast_mutex_unlock(&iflock); 07267 handle_init_event(i, res); 07268 ast_mutex_lock(&iflock); 07269 } 07270 if (pollres & POLLPRI) { 07271 if (i->owner || i->subs[SUB_REAL].owner) { 07272 #ifdef HAVE_PRI 07273 if (!i->pri) 07274 #endif 07275 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd); 07276 i = i->next; 07277 continue; 07278 } 07279 res = zt_get_event(i->subs[SUB_REAL].zfd); 07280 if (option_debug) 07281 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 07282 /* Don't hold iflock while handling init events */ 07283 ast_mutex_unlock(&iflock); 07284 handle_init_event(i, res); 07285 ast_mutex_lock(&iflock); 07286 } 07287 } 07288 i=i->next; 07289 } 07290 ast_mutex_unlock(&iflock); 07291 } 07292 /* Never reached */ 07293 return NULL; 07294 07295 }
static void enable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3396 of file chan_zap.c.
References ast_dsp_set_features(), CHAN_PSEUDO, zt_pvt::channel, zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_answer(), and zt_bridge().
03397 { 03398 #ifdef ZT_TONEDETECT 03399 int val; 03400 #endif 03401 03402 if (p->channel == CHAN_PSEUDO) 03403 return; 03404 03405 p->ignoredtmf = 0; 03406 03407 #ifdef ZT_TONEDETECT 03408 val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 03409 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03410 #endif 03411 if (!p->hardwaredtmf && p->dsp) { 03412 p->dsp_features |= DSP_FEATURE_DTMF_DETECT; 03413 ast_dsp_set_features(p->dsp, p->dsp_features); 03414 } 03415 }
static char* event2str | ( | int | event | ) | [static] |
Definition at line 1325 of file chan_zap.c.
Referenced by __zt_exception(), do_monitor(), ss_thread(), and zt_handle_event().
01326 { 01327 static char buf[256]; 01328 if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1)) 01329 return events[event]; 01330 sprintf(buf, "Event %d", event); /* safe */ 01331 return buf; 01332 }
static void fill_rxgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1696 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_rxgain().
01697 { 01698 int j; 01699 int k; 01700 float linear_gain = pow(10.0, gain / 20.0); 01701 01702 switch (law) { 01703 case ZT_LAW_ALAW: 01704 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01705 if (gain) { 01706 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01707 if (k > 32767) k = 32767; 01708 if (k < -32767) k = -32767; 01709 g->rxgain[j] = AST_LIN2A(k); 01710 } else { 01711 g->rxgain[j] = j; 01712 } 01713 } 01714 break; 01715 case ZT_LAW_MULAW: 01716 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01717 if (gain) { 01718 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01719 if (k > 32767) k = 32767; 01720 if (k < -32767) k = -32767; 01721 g->rxgain[j] = AST_LIN2MU(k); 01722 } else { 01723 g->rxgain[j] = j; 01724 } 01725 } 01726 break; 01727 } 01728 }
static void fill_txgain | ( | struct zt_gains * | g, | |
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1662 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_txgain().
01663 { 01664 int j; 01665 int k; 01666 float linear_gain = pow(10.0, gain / 20.0); 01667 01668 switch (law) { 01669 case ZT_LAW_ALAW: 01670 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01671 if (gain) { 01672 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01673 if (k > 32767) k = 32767; 01674 if (k < -32767) k = -32767; 01675 g->txgain[j] = AST_LIN2A(k); 01676 } else { 01677 g->txgain[j] = j; 01678 } 01679 } 01680 break; 01681 case ZT_LAW_MULAW: 01682 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01683 if (gain) { 01684 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01685 if (k > 32767) k = 32767; 01686 if (k < -32767) k = -32767; 01687 g->txgain[j] = AST_LIN2MU(k); 01688 } else { 01689 g->txgain[j] = j; 01690 } 01691 } 01692 break; 01693 } 01694 }
static struct zt_pvt* find_channel | ( | int | channel | ) | [static, read] |
Definition at line 11978 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().
11979 { 11980 struct zt_pvt *p = iflist; 11981 while (p) { 11982 if (p->channel == channel) { 11983 break; 11984 } 11985 p = p->next; 11986 } 11987 return p; 11988 }
static int get_alarms | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3875 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_WARNING, zt_pvt::span, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
03876 { 03877 int res; 03878 ZT_SPANINFO zi; 03879 memset(&zi, 0, sizeof(zi)); 03880 zi.spanno = p->span; 03881 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi); 03882 if (res < 0) { 03883 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 03884 return 0; 03885 } 03886 return zi.alarms; 03887 }
static int handle_init_event | ( | struct zt_pvt * | i, | |
int | event | |||
) | [static] |
Definition at line 6868 of file chan_zap.c.
References alarm2str(), ast_hangup(), ast_log(), ast_pthread_create, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verbose(), zt_pvt::channel, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::cidspill, errno, EVENT_FLAG_SYSTEM, free, get_alarms(), zt_pvt::hanguponpolarityswitch, has_voicemail(), zt_pvt::immediate, zt_pvt::inalarm, LOG_NOTICE, LOG_WARNING, manager_event(), zt_pvt::polarity, POLARITY_REV, zt_pvt::radio, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ss_thread(), SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_2, zap_destroy_channel_bynum(), zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_new(), and zt_set_hook().
Referenced by do_monitor().
06869 { 06870 int res; 06871 pthread_t threadid; 06872 pthread_attr_t attr; 06873 struct ast_channel *chan; 06874 pthread_attr_init(&attr); 06875 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06876 /* Handle an event on a given channel for the monitor thread. */ 06877 switch (event) { 06878 case ZT_EVENT_NONE: 06879 case ZT_EVENT_BITSCHANGED: 06880 break; 06881 case ZT_EVENT_WINKFLASH: 06882 case ZT_EVENT_RINGOFFHOOK: 06883 if (i->inalarm) break; 06884 if (i->radio) break; 06885 /* Got a ring/answer. What kind of channel are we? */ 06886 switch (i->sig) { 06887 case SIG_FXOLS: 06888 case SIG_FXOGS: 06889 case SIG_FXOKS: 06890 res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06891 if (res && (errno == EBUSY)) 06892 break; 06893 if (i->cidspill) { 06894 /* Cancel VMWI spill */ 06895 free(i->cidspill); 06896 i->cidspill = NULL; 06897 } 06898 if (i->immediate) { 06899 zt_enable_ec(i); 06900 /* The channel is immediately up. Start right away */ 06901 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 06902 chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0); 06903 if (!chan) { 06904 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 06905 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06906 if (res < 0) 06907 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06908 } 06909 } else { 06910 /* Check for callerid, digits, etc */ 06911 chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0); 06912 if (chan) { 06913 if (has_voicemail(i)) 06914 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 06915 else 06916 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 06917 if (res < 0) 06918 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 06919 if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06920 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06921 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06922 if (res < 0) 06923 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06924 ast_hangup(chan); 06925 } 06926 } else 06927 ast_log(LOG_WARNING, "Unable to create channel\n"); 06928 } 06929 break; 06930 case SIG_FXSLS: 06931 case SIG_FXSGS: 06932 case SIG_FXSKS: 06933 i->ringt = i->ringt_base; 06934 /* Fall through */ 06935 case SIG_EMWINK: 06936 case SIG_FEATD: 06937 case SIG_FEATDMF: 06938 case SIG_FEATDMF_TA: 06939 case SIG_E911: 06940 case SIG_FGC_CAMA: 06941 case SIG_FGC_CAMAMF: 06942 case SIG_FEATB: 06943 case SIG_EM: 06944 case SIG_EM_E1: 06945 case SIG_SFWINK: 06946 case SIG_SF_FEATD: 06947 case SIG_SF_FEATDMF: 06948 case SIG_SF_FEATB: 06949 case SIG_SF: 06950 /* Check for callerid, digits, etc */ 06951 chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0); 06952 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06953 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06954 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06955 if (res < 0) 06956 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06957 ast_hangup(chan); 06958 } else if (!chan) { 06959 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 06960 } 06961 break; 06962 default: 06963 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06964 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06965 if (res < 0) 06966 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06967 return -1; 06968 } 06969 break; 06970 case ZT_EVENT_NOALARM: 06971 i->inalarm = 0; 06972 #ifdef HAVE_PRI 06973 if (i->pri) { 06974 if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) { 06975 /* dont annoy BRI TE mode users with layer2layer alarms */ 06976 } else { 06977 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); 06978 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 06979 "Channel: %d\r\n", i->channel); 06980 } 06981 } 06982 #else 06983 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); 06984 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 06985 "Channel: %d\r\n", i->channel); 06986 #endif 06987 break; 06988 case ZT_EVENT_ALARM: 06989 i->inalarm = 1; 06990 res = get_alarms(i); 06991 #ifdef HAVE_PRI 06992 if (i->pri) { 06993 if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) { 06994 /* dont annoy BRI TE mode users with layer2layer alarms */ 06995 } else { 06996 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res)); 06997 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 06998 "Alarm: %s\r\n" 06999 "Channel: %d\r\n", 07000 alarm2str(res), i->channel); 07001 } 07002 } 07003 #else 07004 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res)); 07005 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 07006 "Alarm: %s\r\n" 07007 "Channel: %d\r\n", 07008 alarm2str(res), i->channel); 07009 #endif 07010 /* fall thru intentionally */ 07011 case ZT_EVENT_ONHOOK: 07012 if (i->radio) 07013 break; 07014 /* Back on hook. Hang up. */ 07015 switch (i->sig) { 07016 case SIG_FXOLS: 07017 case SIG_FXOGS: 07018 case SIG_FEATD: 07019 case SIG_FEATDMF: 07020 case SIG_FEATDMF_TA: 07021 case SIG_E911: 07022 case SIG_FGC_CAMA: 07023 case SIG_FGC_CAMAMF: 07024 case SIG_FEATB: 07025 case SIG_EM: 07026 case SIG_EM_E1: 07027 case SIG_EMWINK: 07028 case SIG_SF_FEATD: 07029 case SIG_SF_FEATDMF: 07030 case SIG_SF_FEATB: 07031 case SIG_SF: 07032 case SIG_SFWINK: 07033 case SIG_FXSLS: 07034 case SIG_FXSGS: 07035 case SIG_FXSKS: 07036 case SIG_GR303FXSKS: 07037 zt_disable_ec(i); 07038 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 07039 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 07040 break; 07041 case SIG_GR303FXOKS: 07042 case SIG_FXOKS: 07043 zt_disable_ec(i); 07044 /* Diddle the battery for the zhone */ 07045 #ifdef ZHONE_HACK 07046 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 07047 usleep(1); 07048 #endif 07049 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 07050 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 07051 break; 07052 case SIG_PRI: 07053 if (event != ZT_EVENT_ALARM) { 07054 zt_disable_ec(i); 07055 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 07056 } 07057 break; 07058 default: 07059 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 07060 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 07061 return -1; 07062 } 07063 break; 07064 case ZT_EVENT_POLARITY: 07065 switch (i->sig) { 07066 case SIG_FXSLS: 07067 case SIG_FXSKS: 07068 case SIG_FXSGS: 07069 /* We have already got a PR before the channel was 07070 created, but it wasn't handled. We need polarity 07071 to be REV for remote hangup detection to work. 07072 At least in Spain */ 07073 if (i->hanguponpolarityswitch) 07074 i->polarity = POLARITY_REV; 07075 07076 if (i->cid_start == CID_START_POLARITY) { 07077 i->polarity = POLARITY_REV; 07078 ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity " 07079 "CID detection on channel %d\n", 07080 i->channel); 07081 chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0); 07082 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 07083 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 07084 } 07085 } 07086 break; 07087 default: 07088 ast_log(LOG_WARNING, "handle_init_event detected " 07089 "polarity reversal on non-FXO (SIG_FXS) " 07090 "interface %d\n", i->channel); 07091 } 07092 break; 07093 case ZT_EVENT_REMOVED: /* destroy channel */ 07094 ast_log(LOG_NOTICE, 07095 "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 07096 i->channel); 07097 zap_destroy_channel_bynum(i->channel); 07098 break; 07099 } 07100 pthread_attr_destroy(&attr); 07101 return 0; 07102 }
static int handle_zap_show_cadences | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11822 of file chan_zap.c.
References ast_cli(), COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, and term_color().
11823 { 11824 int i, j; 11825 for (i = 0; i < num_cadence; i++) { 11826 char output[1024]; 11827 char tmp[16], tmp2[64]; 11828 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 11829 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 11830 11831 for (j = 0; j < 16; j++) { 11832 if (cadences[i].ringcadence[j] == 0) 11833 break; 11834 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 11835 if (cidrings[i] * 2 - 1 == j) 11836 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 11837 else 11838 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 11839 if (j != 0) 11840 strncat(output, ",", sizeof(output) - strlen(output) - 1); 11841 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 11842 } 11843 ast_cli(fd,"%s\n",output); 11844 } 11845 return 0; 11846 }
static int has_voicemail | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1893 of file chan_zap.c.
References ast_app_has_voicemail(), and zt_pvt::mailbox.
01894 { 01895 01896 return ast_app_has_voicemail(p->mailbox, NULL); 01897 }
static int isourconf | ( | struct zt_pvt * | p, | |
struct zt_subchannel * | c | |||
) | [static] |
Definition at line 1446 of file chan_zap.c.
References zt_pvt::channel, zt_pvt::confno, and zt_subchannel::curconf.
Referenced by conf_del().
01447 { 01448 /* If they're listening to our channel, they're ours */ 01449 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON)) 01450 return 1; 01451 /* If they're a talker on our (allocated) conference, they're ours */ 01452 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER)) 01453 return 1; 01454 return 0; 01455 }
Definition at line 1479 of file chan_zap.c.
References zt_subchannel::inthreeway, zt_pvt::law, MAX_SLAVES, zt_pvt::slaves, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by update_conf().
01480 { 01481 int x; 01482 int useslavenative; 01483 struct zt_pvt *slave = NULL; 01484 /* Start out optimistic */ 01485 useslavenative = 1; 01486 /* Update conference state in a stateless fashion */ 01487 for (x = 0; x < 3; x++) { 01488 /* Any three-way calling makes slave native mode *definitely* out 01489 of the question */ 01490 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) 01491 useslavenative = 0; 01492 } 01493 /* If we don't have any 3-way calls, check to see if we have 01494 precisely one slave */ 01495 if (useslavenative) { 01496 for (x = 0; x < MAX_SLAVES; x++) { 01497 if (p->slaves[x]) { 01498 if (slave) { 01499 /* Whoops already have a slave! No 01500 slave native and stop right away */ 01501 slave = NULL; 01502 useslavenative = 0; 01503 break; 01504 } else { 01505 /* We have one slave so far */ 01506 slave = p->slaves[x]; 01507 } 01508 } 01509 } 01510 } 01511 /* If no slave, slave native definitely out */ 01512 if (!slave) 01513 useslavenative = 0; 01514 else if (slave->law != p->law) { 01515 useslavenative = 0; 01516 slave = NULL; 01517 } 01518 if (out) 01519 *out = slave; 01520 return useslavenative; 01521 }
static int load_module | ( | void | ) | [static] |
Definition at line 13169 of file chan_zap.c.
References __unload_module(), action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), action_zapshowchannels(), app_zapEC(), ast_channel_register(), ast_cli_register(), ast_cli_register_multiple(), ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, ast_mutex_init(), AST_PTHREADT_NULL, ast_register_application(), ast_string_field_init, ast_string_field_set, inuse, lock, LOG_ERROR, name, and setup_zap().
13170 { 13171 int res; 13172 13173 #ifdef HAVE_PRI 13174 int y,i; 13175 memset(pris, 0, sizeof(pris)); 13176 for (y = 0; y < NUM_SPANS; y++) { 13177 ast_mutex_init(&pris[y].lock); 13178 pris[y].offset = -1; 13179 pris[y].master = AST_PTHREADT_NULL; 13180 for (i = 0; i < NUM_DCHANS; i++) 13181 pris[y].fds[i] = -1; 13182 } 13183 pri_set_error(zt_pri_error); 13184 pri_set_message(zt_pri_message); 13185 ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec, 13186 zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip); 13187 #endif 13188 #ifdef HAVE_GSMAT 13189 gsm_set_error(zt_gsm_error); 13190 gsm_set_message(zt_gsm_message); 13191 #endif 13192 res = setup_zap(0); 13193 /* Make sure we can register our Zap channel type */ 13194 if (res) 13195 return AST_MODULE_LOAD_DECLINE; 13196 if (ast_channel_register(&zap_tech)) { 13197 ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n"); 13198 __unload_module(); 13199 return -1; 13200 } 13201 #ifdef HAVE_PRI 13202 ast_string_field_init(&inuse, 16); 13203 ast_string_field_set(&inuse, name, "GR-303InUse"); 13204 ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 13205 ast_register_application(zapCD_app, app_zapCD, zapCD_synopsis, zapCD_tdesc); 13206 ast_register_application(zapInband_app, app_zapInband, zapInband_synopsis, zapInband_tdesc); 13207 #endif 13208 ast_register_application(zapEC_app, app_zapEC, zapEC_synopsis, zapEC_tdesc); 13209 ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 13210 #ifdef HAVE_GSMAT 13211 ast_cli_register(&gsm_send_sms); 13212 ast_cli_register(&gsm_send_pdu); 13213 ast_cli_register(&gsm_show_status); 13214 ast_cli_register_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0])); 13215 #endif 13216 13217 memset(round_robin, 0, sizeof(round_robin)); 13218 ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" ); 13219 ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" ); 13220 ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" ); 13221 ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" ); 13222 ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" ); 13223 ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels"); 13224 ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)"); 13225 13226 return res; 13227 }
static struct zt_pvt* mkintf | ( | int | channel, | |
struct zt_chan_conf | conf, | |||
struct zt_pri * | pri, | |||
int | reloading | |||
) | [static, read] |
Definition at line 7448 of file chan_zap.c.
References zt_pvt::accountcode, zt_pvt::adsi, zt_pvt::amaflags, zt_pvt::answeronpolarityswitch, ast_calloc, ast_dsp_digitmode(), ast_log(), ast_mutex_init(), ast_pthread_create, ast_smdi_interface_find(), ast_strlen_zero(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::callgroup, zt_pvt::callprogress, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::callwaitingcallerid, zt_pvt::cancallforward, zt_pvt::canpark, zt_chan_conf::chan, CHAN_PSEUDO, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, CID_SIG_SMDI, zt_pvt::cid_signalling, zt_pvt::cid_start, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, DCHAN_AVAILABLE, zt_pvt::defcontext, zt_pvt::destroy, destroy_zt_pvt(), drings, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echotraining, errno, zt_pvt::exten, zt_pvt::firstradio, zt_pvt::group, gsm_new(), zt_pvt::hanguponpolarityswitch, zt_pvt::hidecallerid, iflist, zt_pvt::immediate, zt_pvt::inalarm, zt_pvt::language, zt_pvt::law, zt_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, zt_pvt::mailbox, zt_pvt::master, MAX_CHANNELS, zt_pvt::mohinterpret, zt_pvt::mohsuggest, zt_pvt::msgstate, zt_pvt::next, zt_pvt::onhooktime, zt_pvt::outsigmod, zt_pvt::permcallwaiting, zt_pvt::permhidecallerid, zt_pvt::pickupgroup, zt_pvt::polarityonanswerdelay, zt_pvt::prev, zt_pvt::priexclusive, zt_pvt::priindication_oob, zt_pvt::pritransfer, zt_pvt::propconfno, zt_pvt::pulse, zt_pvt::radio, zt_pvt::restrictcid, zt_pvt::ringt_base, zt_pvt::rxgain, zt_pvt::sendcalleridafter, set_actual_gain(), zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_GSM, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::smdi_iface, zt_chan_conf::smdi_port, zt_pvt::span, zt_pvt::stripmsd, SUB_REAL, zt_pvt::subs, zt_pvt::threewaycalling, zt_chan_conf::timing, zt_pvt::tonezone, zt_pvt::transfer, zt_pvt::transfertobusy, zt_pvt::txgain, update_conf(), zt_pvt::use_callerid, zt_pvt::use_callingpres, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_close(), zt_open(), and zt_set_hook().
Referenced by build_channels(), and process_zap().
07449 { 07450 /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */ 07451 struct zt_pvt *tmp = NULL, *tmp2, *prev = NULL; 07452 char fn[80]; 07453 #if 1 07454 struct zt_bufferinfo bi; 07455 #endif 07456 struct zt_spaninfo si; 07457 int res; 07458 int span=0; 07459 int here = 0; 07460 int x; 07461 struct zt_pvt **wlist; 07462 struct zt_pvt **wend; 07463 ZT_PARAMS p; 07464 07465 wlist = &iflist; 07466 wend = &ifend; 07467 07468 #ifdef HAVE_PRI 07469 if (pri) { 07470 wlist = &pri->crvs; 07471 wend = &pri->crvend; 07472 } 07473 #endif 07474 07475 tmp2 = *wlist; 07476 prev = NULL; 07477 07478 while (tmp2) { 07479 if (!tmp2->destroy) { 07480 if (tmp2->channel == channel) { 07481 tmp = tmp2; 07482 here = 1; 07483 break; 07484 } 07485 if (tmp2->channel > channel) { 07486 break; 07487 } 07488 } 07489 prev = tmp2; 07490 tmp2 = tmp2->next; 07491 } 07492 07493 if (!here && !reloading) { 07494 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 07495 destroy_zt_pvt(&tmp); 07496 return NULL; 07497 } 07498 ast_mutex_init(&tmp->lock); 07499 ifcount++; 07500 for (x = 0; x < 3; x++) 07501 tmp->subs[x].zfd = -1; 07502 tmp->channel = channel; 07503 } 07504 07505 if (tmp) { 07506 if (!here) { 07507 if ((channel != CHAN_PSEUDO) && !pri) { 07508 snprintf(fn, sizeof(fn), "%d", channel); 07509 /* Open non-blocking */ 07510 if (!here) 07511 tmp->subs[SUB_REAL].zfd = zt_open(fn); 07512 /* Allocate a zapata structure */ 07513 if (tmp->subs[SUB_REAL].zfd < 0) { 07514 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); 07515 destroy_zt_pvt(&tmp); 07516 return NULL; 07517 } 07518 memset(&p, 0, sizeof(p)); 07519 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07520 if (res < 0) { 07521 ast_log(LOG_ERROR, "Unable to get parameters\n"); 07522 destroy_zt_pvt(&tmp); 07523 return NULL; 07524 } 07525 if (p.sigtype != (conf.chan.sig & 0x3ffff)) { 07526 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)); 07527 destroy_zt_pvt(&tmp); 07528 return NULL; 07529 } 07530 tmp->law = p.curlaw; 07531 tmp->span = p.spanno; 07532 span = p.spanno - 1; 07533 } else { 07534 if (channel == CHAN_PSEUDO) 07535 conf.chan.sig = 0; 07536 else if ((conf.chan.sig != SIG_FXOKS) && (conf.chan.sig != SIG_FXSKS)) { 07537 ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n"); 07538 return NULL; 07539 } 07540 } 07541 #ifdef HAVE_PRI 07542 if ((conf.chan.sig == SIG_PRI) || (conf.chan.sig == SIG_GR303FXOKS) || (conf.chan.sig == SIG_GR303FXSKS)) { 07543 int offset; 07544 int myswitchtype; 07545 int matchesdchan; 07546 int x,y; 07547 offset = 0; 07548 if ((conf.chan.sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) { 07549 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 07550 destroy_zt_pvt(&tmp); 07551 return NULL; 07552 } 07553 if (span >= NUM_SPANS) { 07554 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 07555 destroy_zt_pvt(&tmp); 07556 return NULL; 07557 } else { 07558 si.spanno = 0; 07559 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07560 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07561 destroy_zt_pvt(&tmp); 07562 return NULL; 07563 } 07564 /* Store the logical span first based upon the real span */ 07565 tmp->logicalspan = pris[span].prilogicalspan; 07566 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 07567 if (span < 0) { 07568 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 07569 destroy_zt_pvt(&tmp); 07570 return NULL; 07571 } 07572 if (conf.chan.sig == SIG_PRI) 07573 myswitchtype = conf.pri.switchtype; 07574 else 07575 myswitchtype = PRI_SWITCH_GR303_TMC; 07576 /* Make sure this isn't a d-channel */ 07577 matchesdchan=0; 07578 for (x = 0; x < NUM_SPANS; x++) { 07579 for (y = 0; y < NUM_DCHANS; y++) { 07580 if (pris[x].dchannels[y] == tmp->channel) { 07581 matchesdchan = 1; 07582 break; 07583 } 07584 } 07585 } 07586 offset = p.chanpos; 07587 if (!matchesdchan) { 07588 if (pris[span].nodetype && (pris[span].nodetype != conf.pri.nodetype)) { 07589 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype)); 07590 destroy_zt_pvt(&tmp); 07591 return NULL; 07592 } 07593 if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) { 07594 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype)); 07595 destroy_zt_pvt(&tmp); 07596 return NULL; 07597 } 07598 if ((pris[span].dialplan) && (pris[span].dialplan != conf.pri.dialplan)) { 07599 ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan)); 07600 destroy_zt_pvt(&tmp); 07601 return NULL; 07602 } 07603 if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf.pri.idledial)) { 07604 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf.pri.idledial); 07605 destroy_zt_pvt(&tmp); 07606 return NULL; 07607 } 07608 if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf.pri.idleext)) { 07609 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf.pri.idleext); 07610 destroy_zt_pvt(&tmp); 07611 return NULL; 07612 } 07613 if ((pris[span].localdialplan) && (pris[span].localdialplan != conf.pri.localdialplan)) { 07614 ast_log(LOG_ERROR, "Span %d is already a %s local dialing plan\n", span + 1, dialplan2str(pris[span].localdialplan)); 07615 destroy_zt_pvt(&tmp); 07616 return NULL; 07617 } 07618 if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) { 07619 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused); 07620 destroy_zt_pvt(&tmp); 07621 return NULL; 07622 } 07623 if (pris[span].minidle && (pris[span].minidle != conf.pri.minidle)) { 07624 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf.pri.minidle); 07625 destroy_zt_pvt(&tmp); 07626 return NULL; 07627 } 07628 if (pris[span].numchans >= MAX_CHANNELS) { 07629 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 07630 pris[span].trunkgroup); 07631 destroy_zt_pvt(&tmp); 07632 return NULL; 07633 } 07634 pris[span].nodetype = conf.pri.nodetype; 07635 07636 if (conf.pri.nodetype == BRI_NETWORK_PTMP) { 07637 pris[span].dchanavail[0] = DCHAN_AVAILABLE; 07638 pri_find_dchan(&pris[span]); 07639 } 07640 pris[span].switchtype = myswitchtype; 07641 pris[span].nsf = conf.pri.nsf; 07642 pris[span].dialplan = conf.pri.dialplan; 07643 pris[span].localdialplan = conf.pri.localdialplan; 07644 pris[span].pvts[pris[span].numchans++] = tmp; 07645 pris[span].minunused = conf.pri.minunused; 07646 pris[span].minidle = conf.pri.minidle; 07647 pris[span].overlapdial = conf.pri.overlapdial; 07648 pris[span].usercid = conf.pri.usercid; 07649 pris[span].suspended_calls = NULL; 07650 pris[span].holded_calls = NULL; 07651 pris[span].facilityenable = conf.pri.facilityenable; 07652 ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial)); 07653 ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext)); 07654 ast_copy_string(pris[span].nocid, conf.pri.nocid, sizeof(pris[span].nocid)); 07655 ast_copy_string(pris[span].withheldcid, conf.pri.withheldcid, sizeof(pris[span].withheldcid)); 07656 ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix)); 07657 ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix)); 07658 ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix)); 07659 ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix)); 07660 ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix)); 07661 pris[span].resetinterval = conf.pri.resetinterval; 07662 07663 tmp->pri = &pris[span]; 07664 tmp->prioffset = offset; 07665 tmp->call = NULL; 07666 } else { 07667 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset); 07668 destroy_zt_pvt(&tmp); 07669 return NULL; 07670 } 07671 } 07672 } else { 07673 tmp->prioffset = 0; 07674 } 07675 #endif 07676 #ifdef HAVE_GSMAT 07677 if (chan_conf.signalling == SIG_GSM) { 07678 struct zt_bufferinfo bi; 07679 ast_mutex_init(&tmp->gsm.lock); 07680 strncpy(tmp->gsm.pin, gsm_modem_pin, sizeof(tmp->gsm.pin) - 1); 07681 strncpy(tmp->gsm.exten, gsm_modem_exten, sizeof(tmp->gsm.exten) - 1); 07682 tmp->gsm.available = 0; 07683 snprintf(fn, sizeof(fn), "%d", channel + 1); 07684 /* Open non-blocking */ 07685 tmp->gsm.fd = zt_open(fn); 07686 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07687 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07688 bi.numbufs = 16; 07689 bi.bufsize = 1024; 07690 if (ioctl(tmp->gsm.fd, ZT_SET_BUFINFO, &bi)) { 07691 ast_log(LOG_ERROR, "Unable to set buffer info on channel '%s': %s\n", fn, strerror(errno)); 07692 return NULL; 07693 } 07694 tmp->gsm.pvt = tmp; 07695 tmp->gsm.span = tmp->span; 07696 tmp->gsm.modul = gsm_new(tmp->gsm.fd, 0, tmp->gsm.pin, tmp->span, tmp->channel); 07697 if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, tmp->channel)) { 07698 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d: %s\n", tmp->channel, strerror(errno)); 07699 destroy_zt_pvt(&tmp); 07700 return NULL; 07701 } 07702 if (ast_pthread_create(&tmp->gsm.master, NULL, gsm_dchannel, &tmp->gsm)) { 07703 zt_close(tmp->gsm.fd); 07704 } 07705 } 07706 #endif 07707 } else { 07708 conf.chan.sig = tmp->sig; 07709 conf.chan.radio = tmp->radio; 07710 memset(&p, 0, sizeof(p)); 07711 if (tmp->subs[SUB_REAL].zfd > -1) 07712 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07713 } 07714 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 07715 if ((conf.chan.sig == SIG_FXSKS) || (conf.chan.sig == SIG_FXSLS) || 07716 (conf.chan.sig == SIG_EM) || (conf.chan.sig == SIG_EM_E1) || (conf.chan.sig == SIG_EMWINK) || 07717 (conf.chan.sig == SIG_FEATD) || (conf.chan.sig == SIG_FEATDMF) || (conf.chan.sig == SIG_FEATDMF_TA) || 07718 (conf.chan.sig == SIG_FEATB) || (conf.chan.sig == SIG_E911) || 07719 (conf.chan.sig == SIG_SF) || (conf.chan.sig == SIG_SFWINK) || (conf.chan.sig == SIG_FGC_CAMA) || (conf.chan.sig == SIG_FGC_CAMAMF) || 07720 (conf.chan.sig == SIG_SF_FEATD) || (conf.chan.sig == SIG_SF_FEATDMF) || 07721 (conf.chan.sig == SIG_SF_FEATB)) { 07722 p.starttime = 250; 07723 } 07724 if (conf.chan.radio) { 07725 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 07726 p.channo = channel; 07727 p.rxwinktime = 1; 07728 p.rxflashtime = 1; 07729 p.starttime = 1; 07730 p.debouncetime = 5; 07731 } 07732 if (!conf.chan.radio) { 07733 p.channo = channel; 07734 /* Override timing settings based on config file */ 07735 if (conf.timing.prewinktime >= 0) 07736 p.prewinktime = conf.timing.prewinktime; 07737 if (conf.timing.preflashtime >= 0) 07738 p.preflashtime = conf.timing.preflashtime; 07739 if (conf.timing.winktime >= 0) 07740 p.winktime = conf.timing.winktime; 07741 if (conf.timing.flashtime >= 0) 07742 p.flashtime = conf.timing.flashtime; 07743 if (conf.timing.starttime >= 0) 07744 p.starttime = conf.timing.starttime; 07745 if (conf.timing.rxwinktime >= 0) 07746 p.rxwinktime = conf.timing.rxwinktime; 07747 if (conf.timing.rxflashtime >= 0) 07748 p.rxflashtime = conf.timing.rxflashtime; 07749 if (conf.timing.debouncetime >= 0) 07750 p.debouncetime = conf.timing.debouncetime; 07751 } 07752 07753 /* dont set parms on a pseudo-channel (or CRV) */ 07754 if (tmp->subs[SUB_REAL].zfd >= 0) 07755 { 07756 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p); 07757 if (res < 0) { 07758 ast_log(LOG_ERROR, "Unable to set parameters\n"); 07759 destroy_zt_pvt(&tmp); 07760 return NULL; 07761 } 07762 } 07763 #if 1 07764 if (!here && (tmp->subs[SUB_REAL].zfd > -1)) { 07765 memset(&bi, 0, sizeof(bi)); 07766 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07767 if (!res) { 07768 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07769 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07770 bi.numbufs = numbufs; 07771 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07772 if (res < 0) { 07773 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel); 07774 } 07775 } else 07776 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel); 07777 } 07778 #endif 07779 tmp->immediate = conf.chan.immediate; 07780 tmp->transfertobusy = conf.chan.transfertobusy; 07781 tmp->sig = conf.chan.sig; 07782 tmp->outsigmod = conf.chan.outsigmod; 07783 tmp->radio = conf.chan.radio; 07784 tmp->ringt_base = ringt_base; 07785 tmp->firstradio = 0; 07786 if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS)) 07787 tmp->permcallwaiting = conf.chan.callwaiting; 07788 else 07789 tmp->permcallwaiting = 0; 07790 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 07791 tmp->destroy = 0; 07792 tmp->drings = drings; 07793 tmp->usedistinctiveringdetection = conf.chan.usedistinctiveringdetection; 07794 tmp->callwaitingcallerid = conf.chan.callwaitingcallerid; 07795 tmp->threewaycalling = conf.chan.threewaycalling; 07796 tmp->adsi = conf.chan.adsi; 07797 tmp->use_smdi = conf.chan.use_smdi; 07798 tmp->permhidecallerid = conf.chan.hidecallerid; 07799 tmp->callreturn = conf.chan.callreturn; 07800 tmp->echocancel = conf.chan.echocancel; 07801 tmp->echotraining = conf.chan.echotraining; 07802 tmp->pulse = conf.chan.pulse; 07803 tmp->echocanbridged = conf.chan.echocanbridged; 07804 tmp->busydetect = conf.chan.busydetect; 07805 tmp->busycount = conf.chan.busycount; 07806 tmp->busy_tonelength = conf.chan.busy_tonelength; 07807 tmp->busy_quietlength = conf.chan.busy_quietlength; 07808 tmp->callprogress = conf.chan.callprogress; 07809 tmp->cancallforward = conf.chan.cancallforward; 07810 tmp->dtmfrelax = conf.chan.dtmfrelax; 07811 tmp->callwaiting = tmp->permcallwaiting; 07812 tmp->hidecallerid = tmp->permhidecallerid; 07813 tmp->channel = channel; 07814 tmp->stripmsd = conf.chan.stripmsd; 07815 tmp->use_callerid = conf.chan.use_callerid; 07816 tmp->cid_signalling = conf.chan.cid_signalling; 07817 tmp->cid_start = conf.chan.cid_start; 07818 tmp->zaptrcallerid = conf.chan.zaptrcallerid; 07819 tmp->restrictcid = conf.chan.restrictcid; 07820 tmp->use_callingpres = conf.chan.use_callingpres; 07821 tmp->priindication_oob = conf.chan.priindication_oob; 07822 tmp->pritransfer = conf.chan.pritransfer; 07823 tmp->priexclusive = conf.chan.priexclusive; 07824 if (tmp->usedistinctiveringdetection) { 07825 if (!tmp->use_callerid) { 07826 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 07827 tmp->use_callerid = 1; 07828 } 07829 } 07830 07831 if (tmp->cid_signalling == CID_SIG_SMDI) { 07832 if (!tmp->use_smdi) { 07833 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n"); 07834 tmp->use_smdi = 1; 07835 } 07836 } 07837 if (tmp->use_smdi) { 07838 tmp->smdi_iface = ast_smdi_interface_find(conf.smdi_port); 07839 if (!(tmp->smdi_iface)) { 07840 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n"); 07841 tmp->use_smdi = 0; 07842 } 07843 } 07844 07845 ast_copy_string(tmp->accountcode, conf.chan.accountcode, sizeof(tmp->accountcode)); 07846 tmp->amaflags = conf.chan.amaflags; 07847 if (!here) { 07848 tmp->confno = -1; 07849 tmp->propconfno = -1; 07850 } 07851 tmp->canpark = conf.chan.canpark; 07852 tmp->transfer = conf.chan.transfer; 07853 ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext)); 07854 ast_copy_string(tmp->language, conf.chan.language, sizeof(tmp->language)); 07855 ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret)); 07856 ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest)); 07857 ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context)); 07858 ast_copy_string(tmp->cid_num, conf.chan.cid_num, sizeof(tmp->cid_num)); 07859 tmp->cid_ton = 0; 07860 ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name)); 07861 ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox)); 07862 tmp->msgstate = -1; 07863 tmp->group = conf.chan.group; 07864 tmp->callgroup = conf.chan.callgroup; 07865 tmp->pickupgroup= conf.chan.pickupgroup; 07866 tmp->rxgain = conf.chan.rxgain; 07867 tmp->txgain = conf.chan.txgain; 07868 tmp->tonezone = conf.chan.tonezone; 07869 tmp->onhooktime = time(NULL); 07870 if (tmp->subs[SUB_REAL].zfd > -1) { 07871 set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law); 07872 if (tmp->dsp) 07873 ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 07874 update_conf(tmp); 07875 if (!here) { 07876 if (conf.chan.sig != SIG_PRI) 07877 /* Hang it up to be sure it's good */ 07878 zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK); 07879 } 07880 ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone); 07881 #ifdef HAVE_PRI 07882 /* the dchannel is down so put the channel in alarm */ 07883 if (tmp->pri && !pri_is_up(tmp->pri)) 07884 tmp->inalarm = 1; 07885 else 07886 tmp->inalarm = 0; 07887 #endif 07888 memset(&si, 0, sizeof(si)); 07889 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07890 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07891 destroy_zt_pvt(&tmp); 07892 return NULL; 07893 } 07894 if (si.alarms) tmp->inalarm = 1; 07895 } 07896 07897 tmp->polarityonanswerdelay = conf.chan.polarityonanswerdelay; 07898 tmp->answeronpolarityswitch = conf.chan.answeronpolarityswitch; 07899 tmp->hanguponpolarityswitch = conf.chan.hanguponpolarityswitch; 07900 tmp->sendcalleridafter = conf.chan.sendcalleridafter; 07901 07902 } 07903 if (tmp && !here) { 07904 /* nothing on the iflist */ 07905 if (!*wlist) { 07906 *wlist = tmp; 07907 tmp->prev = NULL; 07908 tmp->next = NULL; 07909 *wend = tmp; 07910 } else { 07911 /* at least one member on the iflist */ 07912 struct zt_pvt *working = *wlist; 07913 07914 /* check if we maybe have to put it on the begining */ 07915 if (working->channel > tmp->channel) { 07916 tmp->next = *wlist; 07917 tmp->prev = NULL; 07918 (*wlist)->prev = tmp; 07919 *wlist = tmp; 07920 } else { 07921 /* go through all the members and put the member in the right place */ 07922 while (working) { 07923 /* in the middle */ 07924 if (working->next) { 07925 if (working->channel < tmp->channel && working->next->channel > tmp->channel) { 07926 tmp->next = working->next; 07927 tmp->prev = working; 07928 working->next->prev = tmp; 07929 working->next = tmp; 07930 break; 07931 } 07932 } else { 07933 /* the last */ 07934 if (working->channel < tmp->channel) { 07935 working->next = tmp; 07936 tmp->next = NULL; 07937 tmp->prev = working; 07938 *wend = tmp; 07939 break; 07940 } 07941 } 07942 working = working->next; 07943 } 07944 } 07945 } 07946 } 07947 return tmp; 07948 }
static int my_getsigstr | ( | struct ast_channel * | chan, | |
char * | str, | |||
const char * | term, | |||
int | ms | |||
) | [static] |
Definition at line 5654 of file chan_zap.c.
References ast_waitfordigit().
Referenced by ss_thread().
05655 { 05656 char c; 05657 05658 *str = 0; /* start with empty output buffer */ 05659 for (;;) 05660 { 05661 /* Wait for the first digit (up to specified ms). */ 05662 c = ast_waitfordigit(chan, ms); 05663 /* if timeout, hangup or error, return as such */ 05664 if (c < 1) 05665 return c; 05666 *str++ = c; 05667 *str = 0; 05668 if (strchr(term, c)) 05669 return 1; 05670 } 05671 }
static int my_zt_write | ( | struct zt_pvt * | p, | |
unsigned char * | buf, | |||
int | len, | |||
int | index, | |||
int | linear | |||
) | [static] |
Definition at line 5184 of file chan_zap.c.
References ast_log(), zt_pvt::channel, errno, LOG_DEBUG, option_debug, READ_SIZE, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_write().
05185 { 05186 int sent=0; 05187 int size; 05188 int res; 05189 int fd; 05190 fd = p->subs[index].zfd; 05191 while (len) { 05192 size = len; 05193 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 05194 size = (linear ? READ_SIZE * 2 : READ_SIZE); 05195 res = write(fd, buf, size); 05196 if (res != size) { 05197 if (option_debug) 05198 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 05199 return sent; 05200 } 05201 len -= size; 05202 buf += size; 05203 } 05204 return sent; 05205 }
static int process_zap | ( | struct zt_chan_conf * | confp, | |
struct ast_variable * | v, | |||
int | reload, | |||
int | skipchannels | |||
) | [static] |
Definition at line 12325 of file chan_zap.c.
References zt_pvt::accountcode, zt_pvt::adsi, zt_pvt::amaflags, zt_pvt::answeronpolarityswitch, ast_callerid_split(), ast_cdr_amaflags2int(), ast_get_group(), ast_jb_read_conf(), ast_log(), ast_strlen_zero(), ast_true(), ast_verbose(), build_channels(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::callgroup, zt_pvt::callprogress, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::callwaitingcallerid, zt_pvt::cancallforward, zt_pvt::canpark, zt_chan_conf::chan, CHAN_PSEUDO, zt_pvt::cid_name, zt_pvt::cid_num, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, CID_START_RING, zt_pvt::context, ringContextData::contextData, drings, DSP_DIGITMODE_RELAXDTMF, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echotraining, global_jbconf, zt_pvt::group, zt_pvt::hanguponpolarityswitch, HAVE_PRI, zt_pvt::hidecallerid, zt_pvt::hidecalleridname, zt_pvt::immediate, zt_pvt::language, ast_variable::lineno, LOG_ERROR, LOG_WARNING, zt_pvt::mailbox, MAX_CHANLIST_LEN, mkintf(), zt_pvt::mohinterpret, zt_pvt::mohsuggest, ast_variable::name, ast_variable::next, NUM_CADENCE_MAX, option_verbose, zt_pvt::outsigmod, zt_pvt::pickupgroup, zt_pvt::polarityonanswerdelay, zt_pvt::priexclusive, zt_pvt::priindication_oob, zt_pvt::pritransfer, zt_pvt::pulse, zt_pvt::radio, READ_SIZE, zt_pvt::restrictcid, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::rxgain, zt_pvt::sendcalleridafter, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_GSM, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SFWINK, zt_chan_conf::smdi_port, zt_pvt::stripmsd, strsep(), zt_pvt::threewaycalling, zt_chan_conf::timing, zt_pvt::tonezone, zt_pvt::transfer, zt_pvt::transfertobusy, zt_pvt::txgain, zt_pvt::use_callerid, zt_pvt::use_callingpres, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, ast_variable::value, VERBOSE_PREFIX_3, and zt_pvt::zaptrcallerid.
Referenced by setup_zap().
12326 { 12327 struct zt_pvt *tmp; 12328 char *ringc; /* temporary string for parsing the dring number. */ 12329 int y; 12330 int found_pseudo = 0; 12331 char zapchan[MAX_CHANLIST_LEN] = {}; 12332 12333 for (; v; v = v->next) { 12334 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 12335 continue; 12336 12337 /* Create the interface list */ 12338 if (!strcasecmp(v->name, "channel") 12339 #ifdef HAVE_PRI 12340 || !strcasecmp(v->name, "crv") 12341 #endif 12342 ) { 12343 int iscrv; 12344 if (skipchannels) 12345 continue; 12346 iscrv = !strcasecmp(v->name, "crv"); 12347 if (build_channels(*confp, iscrv, v->value, reload, v->lineno, &found_pseudo)) 12348 return -1; 12349 } else if (!strcasecmp(v->name, "zapchan")) { 12350 ast_copy_string(zapchan, v->value, sizeof(zapchan)); 12351 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 12352 if (ast_true(v->value)) 12353 confp->chan.usedistinctiveringdetection = 1; 12354 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) { 12355 if (ast_true(v->value)) 12356 distinctiveringaftercid = 1; 12357 } else if (!strcasecmp(v->name, "dring1context")) { 12358 ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData)); 12359 } else if (!strcasecmp(v->name, "dring2context")) { 12360 ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData)); 12361 } else if (!strcasecmp(v->name, "dring3context")) { 12362 ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData)); 12363 } else if (!strcasecmp(v->name, "dring1")) { 12364 ringc = v->value; 12365 sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]); 12366 } else if (!strcasecmp(v->name, "dring2")) { 12367 ringc = v->value; 12368 sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]); 12369 } else if (!strcasecmp(v->name, "dring3")) { 12370 ringc = v->value; 12371 sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]); 12372 } else if (!strcasecmp(v->name, "usecallerid")) { 12373 confp->chan.use_callerid = ast_true(v->value); 12374 } else if (!strcasecmp(v->name, "cidsignalling")) { 12375 if (!strcasecmp(v->value, "bell")) 12376 confp->chan.cid_signalling = CID_SIG_BELL; 12377 else if (!strcasecmp(v->value, "v23")) 12378 confp->chan.cid_signalling = CID_SIG_V23; 12379 else if (!strcasecmp(v->value, "dtmf")) 12380 confp->chan.cid_signalling = CID_SIG_DTMF; 12381 else if (!strcasecmp(v->value, "smdi")) 12382 confp->chan.cid_signalling = CID_SIG_SMDI; 12383 else if (!strcasecmp(v->value, "v23_jp")) 12384 confp->chan.cid_signalling = CID_SIG_V23_JP; 12385 else if (ast_true(v->value)) 12386 confp->chan.cid_signalling = CID_SIG_BELL; 12387 } else if (!strcasecmp(v->name, "cidstart")) { 12388 if (!strcasecmp(v->value, "ring")) 12389 confp->chan.cid_start = CID_START_RING; 12390 else if (!strcasecmp(v->value, "polarity")) 12391 confp->chan.cid_start = CID_START_POLARITY; 12392 else if (ast_true(v->value)) 12393 confp->chan.cid_start = CID_START_RING; 12394 } else if (!strcasecmp(v->name, "threewaycalling")) { 12395 confp->chan.threewaycalling = ast_true(v->value); 12396 } else if (!strcasecmp(v->name, "cancallforward")) { 12397 confp->chan.cancallforward = ast_true(v->value); 12398 } else if (!strcasecmp(v->name, "relaxdtmf")) { 12399 if (ast_true(v->value)) 12400 confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 12401 else 12402 confp->chan.dtmfrelax = 0; 12403 } else if (!strcasecmp(v->name, "mailbox")) { 12404 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox)); 12405 } else if (!strcasecmp(v->name, "adsi")) { 12406 confp->chan.adsi = ast_true(v->value); 12407 } else if (!strcasecmp(v->name, "usesmdi")) { 12408 confp->chan.use_smdi = ast_true(v->value); 12409 } else if (!strcasecmp(v->name, "smdiport")) { 12410 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port)); 12411 } else if (!strcasecmp(v->name, "transfer")) { 12412 confp->chan.transfer = ast_true(v->value); 12413 } else if (!strcasecmp(v->name, "canpark")) { 12414 confp->chan.canpark = ast_true(v->value); 12415 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 12416 confp->chan.echocanbridged = ast_true(v->value); 12417 } else if (!strcasecmp(v->name, "busydetect")) { 12418 confp->chan.busydetect = ast_true(v->value); 12419 } else if (!strcasecmp(v->name, "busycount")) { 12420 confp->chan.busycount = atoi(v->value); 12421 } else if (!strcasecmp(v->name, "busypattern")) { 12422 if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) { 12423 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n"); 12424 } 12425 } else if (!strcasecmp(v->name, "callprogress")) { 12426 if (ast_true(v->value)) 12427 confp->chan.callprogress |= 1; 12428 else 12429 confp->chan.callprogress &= ~1; 12430 } else if (!strcasecmp(v->name, "faxdetect")) { 12431 if (!strcasecmp(v->value, "incoming")) { 12432 confp->chan.callprogress |= 4; 12433 confp->chan.callprogress &= ~2; 12434 } else if (!strcasecmp(v->value, "outgoing")) { 12435 confp->chan.callprogress &= ~4; 12436 confp->chan.callprogress |= 2; 12437 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 12438 confp->chan.callprogress |= 6; 12439 else 12440 confp->chan.callprogress &= ~6; 12441 } else if (!strcasecmp(v->name, "echocancel")) { 12442 if (!ast_strlen_zero(v->value)) { 12443 y = atoi(v->value); 12444 } else 12445 y = 0; 12446 if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024)) 12447 confp->chan.echocancel = y; 12448 else { 12449 confp->chan.echocancel = ast_true(v->value); 12450 if (confp->chan.echocancel) 12451 confp->chan.echocancel=128; 12452 } 12453 } else if (!strcasecmp(v->name, "echotraining")) { 12454 if (sscanf(v->value, "%d", &y) == 1) { 12455 if ((y < 10) || (y > 4000)) { 12456 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno); 12457 } else { 12458 confp->chan.echotraining = y; 12459 } 12460 } else if (ast_true(v->value)) { 12461 confp->chan.echotraining = 400; 12462 } else 12463 confp->chan.echotraining = 0; 12464 } else if (!strcasecmp(v->name, "hidecallerid")) { 12465 confp->chan.hidecallerid = ast_true(v->value); 12466 } else if (!strcasecmp(v->name, "hidecalleridname")) { 12467 confp->chan.hidecalleridname = ast_true(v->value); 12468 } else if (!strcasecmp(v->name, "pulsedial")) { 12469 confp->chan.pulse = ast_true(v->value); 12470 } else if (!strcasecmp(v->name, "callreturn")) { 12471 confp->chan.callreturn = ast_true(v->value); 12472 } else if (!strcasecmp(v->name, "callwaiting")) { 12473 confp->chan.callwaiting = ast_true(v->value); 12474 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 12475 confp->chan.callwaitingcallerid = ast_true(v->value); 12476 } else if (!strcasecmp(v->name, "context")) { 12477 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context)); 12478 } else if (!strcasecmp(v->name, "language")) { 12479 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language)); 12480 } else if (!strcasecmp(v->name, "progzone")) { 12481 ast_copy_string(progzone, v->value, sizeof(progzone)); 12482 } else if (!strcasecmp(v->name, "mohinterpret") 12483 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) { 12484 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret)); 12485 } else if (!strcasecmp(v->name, "mohsuggest")) { 12486 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest)); 12487 } else if (!strcasecmp(v->name, "stripmsd")) { 12488 confp->chan.stripmsd = atoi(v->value); 12489 } else if (!strcasecmp(v->name, "jitterbuffers")) { 12490 numbufs = atoi(v->value); 12491 } else if (!strcasecmp(v->name, "group")) { 12492 confp->chan.group = ast_get_group(v->value); 12493 } else if (!strcasecmp(v->name, "callgroup")) { 12494 confp->chan.callgroup = ast_get_group(v->value); 12495 } else if (!strcasecmp(v->name, "pickupgroup")) { 12496 confp->chan.pickupgroup = ast_get_group(v->value); 12497 } else if (!strcasecmp(v->name, "immediate")) { 12498 confp->chan.immediate = ast_true(v->value); 12499 } else if (!strcasecmp(v->name, "transfertobusy")) { 12500 confp->chan.transfertobusy = ast_true(v->value); 12501 } else if (!strcasecmp(v->name, "rxgain")) { 12502 if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) { 12503 ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value); 12504 } 12505 } else if (!strcasecmp(v->name, "txgain")) { 12506 if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) { 12507 ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value); 12508 } 12509 } else if (!strcasecmp(v->name, "tonezone")) { 12510 if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) { 12511 ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value); 12512 } 12513 } else if (!strcasecmp(v->name, "callerid")) { 12514 if (!strcasecmp(v->value, "asreceived")) { 12515 confp->chan.cid_num[0] = '\0'; 12516 confp->chan.cid_name[0] = '\0'; 12517 } else { 12518 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num)); 12519 } 12520 } else if (!strcasecmp(v->name, "fullname")) { 12521 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name)); 12522 } else if (!strcasecmp(v->name, "cid_number")) { 12523 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num)); 12524 } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) { 12525 confp->chan.zaptrcallerid = ast_true(v->value); 12526 } else if (!strcasecmp(v->name, "restrictcid")) { 12527 confp->chan.restrictcid = ast_true(v->value); 12528 } else if (!strcasecmp(v->name, "usecallingpres")) { 12529 confp->chan.use_callingpres = ast_true(v->value); 12530 } else if (!strcasecmp(v->name, "accountcode")) { 12531 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode)); 12532 } else if (!strcasecmp(v->name, "amaflags")) { 12533 y = ast_cdr_amaflags2int(v->value); 12534 if (y < 0) 12535 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 12536 else 12537 confp->chan.amaflags = y; 12538 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 12539 confp->chan.polarityonanswerdelay = atoi(v->value); 12540 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 12541 confp->chan.answeronpolarityswitch = ast_true(v->value); 12542 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 12543 confp->chan.hanguponpolarityswitch = ast_true(v->value); 12544 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 12545 confp->chan.sendcalleridafter = atoi(v->value); 12546 } else if (!reload){ 12547 if (!strcasecmp(v->name, "signalling")) { 12548 confp->chan.outsigmod = -1; 12549 if (!strcasecmp(v->value, "em")) { 12550 confp->chan.sig = SIG_EM; 12551 } else if (!strcasecmp(v->value, "em_e1")) { 12552 confp->chan.sig = SIG_EM_E1; 12553 } else if (!strcasecmp(v->value, "em_w")) { 12554 confp->chan.sig = SIG_EMWINK; 12555 confp->chan.radio = 0; 12556 } else if (!strcasecmp(v->value, "fxs_ls")) { 12557 confp->chan.sig = SIG_FXSLS; 12558 confp->chan.radio = 0; 12559 } else if (!strcasecmp(v->value, "fxs_gs")) { 12560 confp->chan.sig = SIG_FXSGS; 12561 confp->chan.radio = 0; 12562 } else if (!strcasecmp(v->value, "fxs_ks")) { 12563 confp->chan.sig = SIG_FXSKS; 12564 confp->chan.radio = 0; 12565 } else if (!strcasecmp(v->value, "fxo_ls")) { 12566 confp->chan.sig = SIG_FXOLS; 12567 confp->chan.radio = 0; 12568 } else if (!strcasecmp(v->value, "fxo_gs")) { 12569 confp->chan.sig = SIG_FXOGS; 12570 confp->chan.radio = 0; 12571 } else if (!strcasecmp(v->value, "fxo_ks")) { 12572 confp->chan.sig = SIG_FXOKS; 12573 confp->chan.radio = 0; 12574 } else if (!strcasecmp(v->value, "fxs_rx")) { 12575 confp->chan.sig = SIG_FXSKS; 12576 confp->chan.radio = 1; 12577 } else if (!strcasecmp(v->value, "fxo_rx")) { 12578 confp->chan.sig = SIG_FXOLS; 12579 confp->chan.radio = 1; 12580 } else if (!strcasecmp(v->value, "fxs_tx")) { 12581 confp->chan.sig = SIG_FXSLS; 12582 confp->chan.radio = 1; 12583 } else if (!strcasecmp(v->value, "fxo_tx")) { 12584 confp->chan.sig = SIG_FXOGS; 12585 confp->chan.radio = 1; 12586 } else if (!strcasecmp(v->value, "em_rx")) { 12587 confp->chan.sig = SIG_EM; 12588 confp->chan.radio = 1; 12589 } else if (!strcasecmp(v->value, "em_tx")) { 12590 confp->chan.sig = SIG_EM; 12591 confp->chan.radio = 1; 12592 } else if (!strcasecmp(v->value, "em_rxtx")) { 12593 confp->chan.sig = SIG_EM; 12594 confp->chan.radio = 2; 12595 } else if (!strcasecmp(v->value, "em_txrx")) { 12596 confp->chan.sig = SIG_EM; 12597 confp->chan.radio = 2; 12598 } else if (!strcasecmp(v->value, "sf")) { 12599 confp->chan.sig = SIG_SF; 12600 confp->chan.radio = 0; 12601 } else if (!strcasecmp(v->value, "sf_w")) { 12602 confp->chan.sig = SIG_SFWINK; 12603 confp->chan.radio = 0; 12604 } else if (!strcasecmp(v->value, "sf_featd")) { 12605 confp->chan.sig = SIG_FEATD; 12606 confp->chan.radio = 0; 12607 } else if (!strcasecmp(v->value, "sf_featdmf")) { 12608 confp->chan.sig = SIG_FEATDMF; 12609 confp->chan.radio = 0; 12610 } else if (!strcasecmp(v->value, "sf_featb")) { 12611 confp->chan.sig = SIG_SF_FEATB; 12612 confp->chan.radio = 0; 12613 } else if (!strcasecmp(v->value, "sf")) { 12614 confp->chan.sig = SIG_SF; 12615 confp->chan.radio = 0; 12616 } else if (!strcasecmp(v->value, "sf_rx")) { 12617 confp->chan.sig = SIG_SF; 12618 confp->chan.radio = 1; 12619 } else if (!strcasecmp(v->value, "sf_tx")) { 12620 confp->chan.sig = SIG_SF; 12621 confp->chan.radio = 1; 12622 } else if (!strcasecmp(v->value, "sf_rxtx")) { 12623 confp->chan.sig = SIG_SF; 12624 confp->chan.radio = 2; 12625 } else if (!strcasecmp(v->value, "sf_txrx")) { 12626 confp->chan.sig = SIG_SF; 12627 confp->chan.radio = 2; 12628 } else if (!strcasecmp(v->value, "featd")) { 12629 confp->chan.sig = SIG_FEATD; 12630 confp->chan.radio = 0; 12631 } else if (!strcasecmp(v->value, "featdmf")) { 12632 confp->chan.sig = SIG_FEATDMF; 12633 confp->chan.radio = 0; 12634 } else if (!strcasecmp(v->value, "featdmf_ta")) { 12635 confp->chan.sig = SIG_FEATDMF_TA; 12636 confp->chan.radio = 0; 12637 } else if (!strcasecmp(v->value, "e911")) { 12638 confp->chan.sig = SIG_E911; 12639 confp->chan.radio = 0; 12640 } else if (!strcasecmp(v->value, "fgccama")) { 12641 confp->chan.sig = SIG_FGC_CAMA; 12642 confp->chan.radio = 0; 12643 } else if (!strcasecmp(v->value, "fgccamamf")) { 12644 confp->chan.sig = SIG_FGC_CAMAMF; 12645 confp->chan.radio = 0; 12646 } else if (!strcasecmp(v->value, "featb")) { 12647 confp->chan.sig = SIG_FEATB; 12648 confp->chan.radio = 0; 12649 #ifdef HAVE_PRI 12650 } else if (!strcasecmp(v->value, "pri_net")) { 12651 confp->chan.radio = 0; 12652 confp->chan.sig = SIG_PRI; 12653 confp->pri.nodetype = PRI_NETWORK; 12654 } else if (!strcasecmp(v->value, "pri_cpe")) { 12655 confp->chan.sig = SIG_PRI; 12656 confp->chan.radio = 0; 12657 confp->pri.nodetype = PRI_CPE; 12658 } else if (!strcasecmp(v->value, "gr303fxoks_net")) { 12659 confp->chan.sig = SIG_GR303FXOKS; 12660 confp->chan.radio = 0; 12661 confp->pri.nodetype = PRI_NETWORK; 12662 } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) { 12663 confp->chan.sig = SIG_GR303FXSKS; 12664 confp->chan.radio = 0; 12665 confp->pri.nodetype = PRI_CPE; 12666 } else if (!strcasecmp(v->value, "bri_net_ptmp")) { 12667 confp->chan.radio = 0; 12668 confp->chan.sig = SIG_PRI; 12669 confp->pri.nodetype = BRI_NETWORK_PTMP; 12670 } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) { 12671 confp->chan.sig = SIG_PRI; 12672 confp->chan.radio = 0; 12673 confp->pri.nodetype = BRI_CPE_PTMP; 12674 } else if (!strcasecmp(v->value, "bri_net")) { 12675 confp->chan.radio = 0; 12676 confp->chan.sig = SIG_PRI; 12677 confp->pri.nodetype = BRI_NETWORK; 12678 } else if (!strcasecmp(v->value, "bri_cpe")) { 12679 confp->chan.sig = SIG_PRI; 12680 confp->chan.radio = 0; 12681 confp->pri.nodetype = BRI_CPE; 12682 #endif 12683 #ifdef HAVE_GSMAT 12684 } else if (!strcasecmp(v->value, "gsm")) { 12685 confp->chan.sig = SIG_GSM; 12686 confp->chan.radio = 0; 12687 #endif 12688 } else { 12689 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 12690 } 12691 } else if (!strcasecmp(v->name, "outsignalling")) { 12692 if (!strcasecmp(v->value, "em")) { 12693 confp->chan.outsigmod = SIG_EM; 12694 } else if (!strcasecmp(v->value, "em_e1")) { 12695 confp->chan.outsigmod = SIG_EM_E1; 12696 } else if (!strcasecmp(v->value, "em_w")) { 12697 confp->chan.outsigmod = SIG_EMWINK; 12698 } else if (!strcasecmp(v->value, "sf")) { 12699 confp->chan.outsigmod = SIG_SF; 12700 } else if (!strcasecmp(v->value, "sf_w")) { 12701 confp->chan.outsigmod = SIG_SFWINK; 12702 } else if (!strcasecmp(v->value, "sf_featd")) { 12703 confp->chan.outsigmod = SIG_FEATD; 12704 } else if (!strcasecmp(v->value, "sf_featdmf")) { 12705 confp->chan.outsigmod = SIG_FEATDMF; 12706 } else if (!strcasecmp(v->value, "sf_featb")) { 12707 confp->chan.outsigmod = SIG_SF_FEATB; 12708 } else if (!strcasecmp(v->value, "sf")) { 12709 confp->chan.outsigmod = SIG_SF; 12710 } else if (!strcasecmp(v->value, "featd")) { 12711 confp->chan.outsigmod = SIG_FEATD; 12712 } else if (!strcasecmp(v->value, "featdmf")) { 12713 confp->chan.outsigmod = SIG_FEATDMF; 12714 } else if (!strcasecmp(v->value, "featdmf_ta")) { 12715 confp->chan.outsigmod = SIG_FEATDMF_TA; 12716 } else if (!strcasecmp(v->value, "e911")) { 12717 confp->chan.outsigmod = SIG_E911; 12718 } else if (!strcasecmp(v->value, "fgccama")) { 12719 confp->chan.outsigmod = SIG_FGC_CAMA; 12720 } else if (!strcasecmp(v->value, "fgccamamf")) { 12721 confp->chan.outsigmod = SIG_FGC_CAMAMF; 12722 } else if (!strcasecmp(v->value, "featb")) { 12723 confp->chan.outsigmod = SIG_FEATB; 12724 } else { 12725 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 12726 } 12727 #ifdef HAVE_PRI 12728 } else if (!strcasecmp(v->name, "pridialplan")) { 12729 if (!strcasecmp(v->value, "national")) { 12730 confp->pri.dialplan = PRI_NATIONAL_ISDN + 1; 12731 } else if (!strcasecmp(v->value, "unknown")) { 12732 confp->pri.dialplan = PRI_UNKNOWN + 1; 12733 } else if (!strcasecmp(v->value, "private")) { 12734 confp->pri.dialplan = PRI_PRIVATE + 1; 12735 } else if (!strcasecmp(v->value, "international")) { 12736 confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1; 12737 } else if (!strcasecmp(v->value, "local")) { 12738 confp->pri.dialplan = PRI_LOCAL_ISDN + 1; 12739 } else if (!strcasecmp(v->value, "dynamic")) { 12740 confp->pri.dialplan = -1; 12741 } else { 12742 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 12743 } 12744 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 12745 if (!strcasecmp(v->value, "national")) { 12746 confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1; 12747 } else if (!strcasecmp(v->value, "unknown")) { 12748 confp->pri.localdialplan = PRI_UNKNOWN + 1; 12749 } else if (!strcasecmp(v->value, "private")) { 12750 confp->pri.localdialplan = PRI_PRIVATE + 1; 12751 } else if (!strcasecmp(v->value, "international")) { 12752 confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1; 12753 } else if (!strcasecmp(v->value, "local")) { 12754 confp->pri.localdialplan = PRI_LOCAL_ISDN + 1; 12755 } else if (!strcasecmp(v->value, "dynamic")) { 12756 confp->pri.localdialplan = -1; 12757 } else { 12758 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 12759 } 12760 } else if (!strcasecmp(v->name, "switchtype")) { 12761 if (!strcasecmp(v->value, "national")) 12762 confp->pri.switchtype = PRI_SWITCH_NI2; 12763 else if (!strcasecmp(v->value, "ni1")) 12764 confp->pri.switchtype = PRI_SWITCH_NI1; 12765 else if (!strcasecmp(v->value, "dms100")) 12766 confp->pri.switchtype = PRI_SWITCH_DMS100; 12767 else if (!strcasecmp(v->value, "4ess")) 12768 confp->pri.switchtype = PRI_SWITCH_ATT4ESS; 12769 else if (!strcasecmp(v->value, "5ess")) 12770 confp->pri.switchtype = PRI_SWITCH_LUCENT5E; 12771 else if (!strcasecmp(v->value, "euroisdn")) 12772 confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1; 12773 else if (!strcasecmp(v->value, "qsig")) 12774 confp->pri.switchtype = PRI_SWITCH_QSIG; 12775 else { 12776 ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value); 12777 return -1; 12778 } 12779 } else if (!strcasecmp(v->name, "nsf")) { 12780 if (!strcasecmp(v->value, "sdn")) 12781 confp->pri.nsf = PRI_NSF_SDN; 12782 else if (!strcasecmp(v->value, "megacom")) 12783 confp->pri.nsf = PRI_NSF_MEGACOM; 12784 else if (!strcasecmp(v->value, "tollfreemegacom")) 12785 confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM; 12786 else if (!strcasecmp(v->value, "accunet")) 12787 confp->pri.nsf = PRI_NSF_ACCUNET; 12788 else if (!strcasecmp(v->value, "none")) 12789 confp->pri.nsf = PRI_NSF_NONE; 12790 else { 12791 ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value); 12792 confp->pri.nsf = PRI_NSF_NONE; 12793 } 12794 } else if (!strcasecmp(v->name, "priindication")) { 12795 if (!strcasecmp(v->value, "outofband")) 12796 confp->chan.priindication_oob = 1; 12797 else if (!strcasecmp(v->value, "inband")) 12798 confp->chan.priindication_oob = 0; 12799 else if (!strcasecmp(v->value, "passthrough")) 12800 confp->chan.priindication_oob = 2; 12801 else 12802 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband', 'outofband' or 'passthrough' at line %d\n", 12803 v->value, v->lineno); 12804 } else if (!strcasecmp(v->name, "pritransfer")) { 12805 if (!strcasecmp(v->value, "no")) 12806 confp->chan.pritransfer = 0; 12807 else if (!strcasecmp(v->value, "ect")) 12808 confp->chan.pritransfer = 1; 12809 else if (!strcasecmp(v->value, "hangup")) 12810 confp->chan.pritransfer = 2; 12811 else 12812 ast_log(LOG_WARNING, "'%s' is not a valid pri transfer value, should be 'no' , 'ect' or 'hangup' at line %d\n", 12813 v->value, v->lineno); 12814 } else if (!strcasecmp(v->name, "priexclusive")) { 12815 confp->chan.priexclusive = ast_true(v->value); 12816 } else if (!strcasecmp(v->name, "internationalprefix")) { 12817 ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix)); 12818 } else if (!strcasecmp(v->name, "nationalprefix")) { 12819 ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix)); 12820 } else if (!strcasecmp(v->name, "localprefix")) { 12821 ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix)); 12822 } else if (!strcasecmp(v->name, "privateprefix")) { 12823 ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix)); 12824 } else if (!strcasecmp(v->name, "unknownprefix")) { 12825 ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix)); 12826 } else if (!strcasecmp(v->name, "nocid")) { 12827 ast_copy_string(confp->pri.nocid, v->value, sizeof(confp->pri.nocid)); 12828 } else if (!strcasecmp(v->name, "withheldcid")) { 12829 ast_copy_string(confp->pri.withheldcid, v->value, sizeof(confp->pri.withheldcid)); 12830 } else if (!strcasecmp(v->name, "pin")) { 12831 ast_copy_string(gsm_modem_pin, v->value, sizeof(gsm_modem_pin) - 1); 12832 } else if (!strcasecmp(v->name, "exten")) { 12833 ast_copy_string(gsm_modem_exten, v->value, sizeof(gsm_modem_exten) - 1); 12834 } else if (!strcasecmp(v->name, "resetinterval")) { 12835 if (!strcasecmp(v->value, "never")) 12836 confp->pri.resetinterval = -1; 12837 else if (atoi(v->value) >= 60) 12838 confp->pri.resetinterval = atoi(v->value); 12839 else 12840 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n", 12841 v->value, v->lineno); 12842 } else if (!strcasecmp(v->name, "minunused")) { 12843 confp->pri.minunused = atoi(v->value); 12844 } else if (!strcasecmp(v->name, "minidle")) { 12845 confp->pri.minidle = atoi(v->value); 12846 } else if (!strcasecmp(v->name, "idleext")) { 12847 ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext)); 12848 } else if (!strcasecmp(v->name, "idledial")) { 12849 ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial)); 12850 } else if (!strcasecmp(v->name, "pritrustusercid")) { 12851 confp->pri.usercid = ast_true(v->value); 12852 } else if (!strcasecmp(v->name, "overlapdial")) { 12853 confp->pri.overlapdial = ast_true(v->value); 12854 } else if (!strcasecmp(v->name, "pritimer")) { 12855 #ifdef PRI_GETSET_TIMERS 12856 char *timerc, *c; 12857 int timer, timeridx; 12858 c = v->value; 12859 timerc = strsep(&c, ","); 12860 if (timerc) { 12861 timer = atoi(c); 12862 if (!timer) 12863 ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc); 12864 else { 12865 if ((timeridx = pri_timer2idx(timerc)) >= 0) 12866 pritimers[timeridx] = timer; 12867 else 12868 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc); 12869 } 12870 } else 12871 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value); 12872 12873 } else if (!strcasecmp(v->name, "facilityenable")) { 12874 confp->pri.facilityenable = ast_true(v->value); 12875 #endif /* PRI_GETSET_TIMERS */ 12876 #endif /* HAVE_PRI */ 12877 } else if (!strcasecmp(v->name, "cadence")) { 12878 /* setup to scan our argument */ 12879 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 12880 int i; 12881 struct zt_ring_cadence new_cadence; 12882 int cid_location = -1; 12883 int firstcadencepos = 0; 12884 char original_args[80]; 12885 int cadence_is_ok = 1; 12886 12887 ast_copy_string(original_args, v->value, sizeof(original_args)); 12888 /* 16 cadences allowed (8 pairs) */ 12889 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]); 12890 12891 /* Cadence must be even (on/off) */ 12892 if (element_count % 2 == 1) { 12893 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args); 12894 cadence_is_ok = 0; 12895 } 12896 12897 /* Ring cadences cannot be negative */ 12898 for (i = 0; i < element_count; i++) { 12899 if (c[i] == 0) { 12900 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args); 12901 cadence_is_ok = 0; 12902 break; 12903 } else if (c[i] < 0) { 12904 if (i % 2 == 1) { 12905 /* Silence duration, negative possibly okay */ 12906 if (cid_location == -1) { 12907 cid_location = i; 12908 c[i] *= -1; 12909 } else { 12910 ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args); 12911 cadence_is_ok = 0; 12912 break; 12913 } 12914 } else { 12915 if (firstcadencepos == 0) { 12916 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 12917 /* duration will be passed negative to the zaptel driver */ 12918 } else { 12919 ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args); 12920 cadence_is_ok = 0; 12921 break; 12922 } 12923 } 12924 } 12925 } 12926 12927 /* Substitute our scanned cadence */ 12928 for (i = 0; i < 16; i++) { 12929 new_cadence.ringcadence[i] = c[i]; 12930 } 12931 12932 if (cadence_is_ok) { 12933 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 12934 if (element_count < 2) { 12935 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args); 12936 } else { 12937 if (cid_location == -1) { 12938 /* user didn't say; default to first pause */ 12939 cid_location = 1; 12940 } else { 12941 /* convert element_index to cidrings value */ 12942 cid_location = (cid_location + 1) / 2; 12943 } 12944 /* ---we like their cadence; try to install it--- */ 12945 if (!user_has_defined_cadences++) 12946 /* this is the first user-defined cadence; clear the default user cadences */ 12947 num_cadence = 0; 12948 if ((num_cadence+1) >= NUM_CADENCE_MAX) 12949 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args); 12950 else { 12951 cadences[num_cadence] = new_cadence; 12952 cidrings[num_cadence++] = cid_location; 12953 if (option_verbose > 2) 12954 ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args); 12955 } 12956 } 12957 } 12958 } else if (!strcasecmp(v->name, "ringtimeout")) { 12959 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 12960 } else if (!strcasecmp(v->name, "prewink")) { 12961 confp->timing.prewinktime = atoi(v->value); 12962 } else if (!strcasecmp(v->name, "preflash")) { 12963 confp->timing.preflashtime = atoi(v->value); 12964 } else if (!strcasecmp(v->name, "wink")) { 12965 confp->timing.winktime = atoi(v->value); 12966 } else if (!strcasecmp(v->name, "flash")) { 12967 confp->timing.flashtime = atoi(v->value); 12968 } else if (!strcasecmp(v->name, "start")) { 12969 confp->timing.starttime = atoi(v->value); 12970 } else if (!strcasecmp(v->name, "rxwink")) { 12971 confp->timing.rxwinktime = atoi(v->value); 12972 } else if (!strcasecmp(v->name, "rxflash")) { 12973 confp->timing.rxflashtime = atoi(v->value); 12974 } else if (!strcasecmp(v->name, "debounce")) { 12975 confp->timing.debouncetime = atoi(v->value); 12976 } else if (!strcasecmp(v->name, "toneduration")) { 12977 int toneduration; 12978 int ctlfd; 12979 int res; 12980 struct zt_dialparams dps; 12981 12982 ctlfd = open("/dev/zap/ctl", O_RDWR); 12983 if (ctlfd == -1) { 12984 ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n"); 12985 return -1; 12986 } 12987 12988 toneduration = atoi(v->value); 12989 if (toneduration > -1) { 12990 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 12991 res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps); 12992 if (res < 0) { 12993 ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration); 12994 return -1; 12995 } 12996 } 12997 close(ctlfd); 12998 } else if (!strcasecmp(v->name, "defaultcic")) { 12999 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 13000 } else if (!strcasecmp(v->name, "defaultozz")) { 13001 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 13002 } 13003 } else if (!skipchannels) 13004 ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 13005 } 13006 if (zapchan[0]) { 13007 /* The user has set 'zapchan' */ 13008 /*< \todo pass proper line number instead of 0 */ 13009 if (build_channels(*confp, 0, zapchan, reload, 0, &found_pseudo)) { 13010 return -1; 13011 } 13012 } 13013 /*< \todo why check for the pseudo in the per-channel section. 13014 * Any actual use for manual setup of the pseudo channel? */ 13015 if (!found_pseudo && reload == 0) { 13016 /* Make sure pseudo isn't a member of any groups if 13017 we're automatically making it. */ 13018 13019 confp->chan.group = 0; 13020 confp->chan.callgroup = 0; 13021 confp->chan.pickupgroup = 0; 13022 13023 tmp = mkintf(CHAN_PSEUDO, *confp, NULL, reload); 13024 13025 if (tmp) { 13026 if (option_verbose > 2) 13027 ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n"); 13028 } else { 13029 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 13030 } 13031 } 13032 return 0; 13033 }
static int reload | ( | void | ) | [static] |
Definition at line 13372 of file chan_zap.c.
References ast_log(), LOG_WARNING, and setup_zap().
13373 { 13374 int res = 0; 13375 13376 res = setup_zap(1); 13377 if (res) { 13378 ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n"); 13379 return -1; 13380 } 13381 return 0; 13382 }
static int reset_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1523 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().
01524 { 01525 ZT_CONFINFO zi; 01526 memset(&zi, 0, sizeof(zi)); 01527 p->confno = -1; 01528 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf)); 01529 if (p->subs[SUB_REAL].zfd > -1) { 01530 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi)) 01531 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel); 01532 } 01533 return 0; 01534 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 7297 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, and LOG_WARNING.
07298 { 07299 pthread_attr_t attr; 07300 pthread_attr_init(&attr); 07301 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 07302 /* If we're supposed to be stopped -- stay stopped */ 07303 if (monitor_thread == AST_PTHREADT_STOP) 07304 return 0; 07305 ast_mutex_lock(&monlock); 07306 if (monitor_thread == pthread_self()) { 07307 ast_mutex_unlock(&monlock); 07308 ast_log(LOG_WARNING, "Cannot kill myself\n"); 07309 return -1; 07310 } 07311 if (monitor_thread != AST_PTHREADT_NULL) { 07312 /* Wake up the thread */ 07313 pthread_kill(monitor_thread, SIGURG); 07314 } else { 07315 /* Start a new monitor */ 07316 if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) { 07317 ast_mutex_unlock(&monlock); 07318 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 07319 pthread_attr_destroy(&attr); 07320 return -1; 07321 } 07322 } 07323 ast_mutex_unlock(&monlock); 07324 pthread_attr_destroy(&attr); 07325 return 0; 07326 }
static int restore_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1859 of file chan_zap.c.
References ast_log(), errno, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by send_callerid(), zt_handle_event(), and zt_read().
01860 { 01861 int res; 01862 if (p->saveconf.confmode) { 01863 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf); 01864 p->saveconf.confmode = 0; 01865 if (res) { 01866 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno)); 01867 return -1; 01868 } 01869 } 01870 if (option_debug) 01871 ast_log(LOG_DEBUG, "Restored conferencing\n"); 01872 return 0; 01873 }
static int restore_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1786 of file chan_zap.c.
References ast_log(), errno, zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, zt_pvt::txgain, and zt_subchannel::zfd.
Referenced by ss_thread(), and zt_hangup().
01787 { 01788 int res; 01789 01790 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01791 if (res) { 01792 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno)); 01793 return -1; 01794 } 01795 01796 return 0; 01797 }
static int save_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1831 of file chan_zap.c.
References ast_log(), errno, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_callwait(), and zt_handle_event().
01832 { 01833 struct zt_confinfo c; 01834 int res; 01835 if (p->saveconf.confmode) { 01836 ast_log(LOG_WARNING, "Can't save conference -- already in use\n"); 01837 return -1; 01838 } 01839 p->saveconf.chan = 0; 01840 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf); 01841 if (res) { 01842 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno)); 01843 p->saveconf.confmode = 0; 01844 return -1; 01845 } 01846 c.chan = 0; 01847 c.confno = 0; 01848 c.confmode = ZT_CONF_NORMAL; 01849 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c); 01850 if (res) { 01851 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno)); 01852 return -1; 01853 } 01854 if (option_debug) 01855 ast_log(LOG_DEBUG, "Disabled conferencing\n"); 01856 return 0; 01857 }
static int send_callerid | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1899 of file chan_zap.c.
References ast_log(), zt_pvt::callwaitcas, CIDCW_EXPIRE_SAMPLES, zt_pvt::cidcwexpire, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, errno, free, zt_subchannel::linear, LOG_WARNING, restore_conference(), SUB_REAL, zt_pvt::subs, zt_subchannel::zfd, and zt_setlinear().
Referenced by send_cwcidspill(), zt_call(), zt_callwait(), and zt_read().
01900 { 01901 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */ 01902 int res; 01903 /* Take out of linear mode if necessary */ 01904 if (p->subs[SUB_REAL].linear) { 01905 p->subs[SUB_REAL].linear = 0; 01906 zt_setlinear(p->subs[SUB_REAL].zfd, 0); 01907 } 01908 while (p->cidpos < p->cidlen) { 01909 res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos); 01910 if (res < 0) { 01911 if (errno == EAGAIN) 01912 return 0; 01913 else { 01914 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 01915 return -1; 01916 } 01917 } 01918 if (!res) 01919 return 0; 01920 p->cidpos += res; 01921 } 01922 free(p->cidspill); 01923 p->cidspill = NULL; 01924 if (p->callwaitcas) { 01925 /* Wait for CID/CW to expire */ 01926 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES; 01927 } else 01928 restore_conference(p); 01929 return 0; 01930 }
static int send_cwcidspill | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1877 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().
01878 { 01879 p->callwaitcas = 0; 01880 p->cidcwexpire = 0; 01881 if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) 01882 return -1; 01883 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p)); 01884 /* Make sure we account for the end */ 01885 p->cidlen += READ_SIZE * 4; 01886 p->cidpos = 0; 01887 send_callerid(p); 01888 if (option_verbose > 2) 01889 ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num); 01890 return 0; 01891 }
static int set_actual_gain | ( | int | fd, | |
int | chan, | |||
float | rxgain, | |||
float | txgain, | |||
int | law | |||
) | [static] |
Definition at line 1767 of file chan_zap.c.
References set_actual_rxgain(), and set_actual_txgain().
Referenced by bump_gains(), mkintf(), restore_gains(), and zt_call().
01768 { 01769 return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law); 01770 }
static int set_actual_rxgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1749 of file chan_zap.c.
References ast_log(), errno, fill_rxgain(), and LOG_DEBUG.
Referenced by set_actual_gain(), and zt_setoption().
01750 { 01751 struct zt_gains g; 01752 int res; 01753 01754 memset(&g, 0, sizeof(g)); 01755 g.chan = chan; 01756 res = ioctl(fd, ZT_GETGAINS, &g); 01757 if (res) { 01758 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01759 return res; 01760 } 01761 01762 fill_rxgain(&g, gain, law); 01763 01764 return ioctl(fd, ZT_SETGAINS, &g); 01765 }
static int set_actual_txgain | ( | int | fd, | |
int | chan, | |||
float | gain, | |||
int | law | |||
) | [static] |
Definition at line 1730 of file chan_zap.c.
References ast_log(), errno, fill_txgain(), LOG_DEBUG, and option_debug.
Referenced by set_actual_gain(), and zt_setoption().
01731 { 01732 struct zt_gains g; 01733 int res; 01734 01735 memset(&g, 0, sizeof(g)); 01736 g.chan = chan; 01737 res = ioctl(fd, ZT_GETGAINS, &g); 01738 if (res) { 01739 if (option_debug) 01740 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01741 return res; 01742 } 01743 01744 fill_txgain(&g, gain, law); 01745 01746 return ioctl(fd, ZT_SETGAINS, &g); 01747 }
static int setup_zap | ( | int | reload | ) | [static] |
Definition at line 13035 of file chan_zap.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), global_jbconf, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, option_verbose, process_zap(), restart_monitor(), ast_variable::value, VERBOSE_PREFIX_2, and zt_chan_conf_default().
Referenced by load_module(), reload(), and zap_restart().
13036 { 13037 struct ast_config *cfg; 13038 struct ast_variable *v; 13039 struct zt_chan_conf conf = zt_chan_conf_default(); 13040 int res; 13041 13042 #ifdef HAVE_PRI 13043 char *c; 13044 int spanno; 13045 int i, x; 13046 int logicalspan; 13047 int trunkgroup; 13048 int dchannels[NUM_DCHANS]; 13049 #endif 13050 13051 cfg = ast_config_load(config); 13052 13053 /* Error if we have no config file */ 13054 if (!cfg) { 13055 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 13056 return 0; 13057 } 13058 13059 /* It's a little silly to lock it, but we mind as well just to be sure */ 13060 ast_mutex_lock(&iflock); 13061 #ifdef HAVE_PRI 13062 if (!reload) { 13063 /* Process trunkgroups first */ 13064 v = ast_variable_browse(cfg, "trunkgroups"); 13065 while (v) { 13066 if (!strcasecmp(v->name, "trunkgroup")) { 13067 trunkgroup = atoi(v->value); 13068 if (trunkgroup > 0) { 13069 if ((c = strchr(v->value, ','))) { 13070 i = 0; 13071 memset(dchannels, 0, sizeof(dchannels)); 13072 while (c && (i < NUM_DCHANS)) { 13073 dchannels[i] = atoi(c + 1); 13074 if (dchannels[i] < 0) { 13075 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); 13076 } else 13077 i++; 13078 c = strchr(c + 1, ','); 13079 } 13080 if (i) { 13081 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 13082 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); 13083 } else if (option_verbose > 1) 13084 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"); 13085 } else 13086 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno); 13087 } else 13088 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno); 13089 } else 13090 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno); 13091 } else if (!strcasecmp(v->name, "spanmap")) { 13092 spanno = atoi(v->value); 13093 if (spanno > 0) { 13094 if ((c = strchr(v->value, ','))) { 13095 trunkgroup = atoi(c + 1); 13096 if (trunkgroup > 0) { 13097 if ((c = strchr(c + 1, ','))) 13098 logicalspan = atoi(c + 1); 13099 else 13100 logicalspan = 0; 13101 if (logicalspan >= 0) { 13102 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 13103 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 13104 } else if (option_verbose > 1) 13105 ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 13106 } else 13107 ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno); 13108 } else 13109 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno); 13110 } else 13111 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno); 13112 } else 13113 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno); 13114 } else { 13115 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 13116 } 13117 v = v->next; 13118 } 13119 } 13120 #endif 13121 13122 /* Copy the default jb config over global_jbconf */ 13123 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 13124 13125 v = ast_variable_browse(cfg, "channels"); 13126 res = process_zap(&conf, v, reload, 0); 13127 ast_mutex_unlock(&iflock); 13128 ast_config_destroy(cfg); 13129 if (res) 13130 return res; 13131 cfg = ast_config_load("users.conf"); 13132 if (cfg) { 13133 char *cat; 13134 const char *chans; 13135 process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1); 13136 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 13137 if (!strcasecmp(cat, "general")) 13138 continue; 13139 chans = ast_variable_retrieve(cfg, cat, "zapchan"); 13140 if (!ast_strlen_zero(chans)) { 13141 /** \todo At this point we should probably 13142 * duplicate conf, and pass a copy, to prevent 13143 * one section from affecting another 13144 */ 13145 process_zap(&conf, ast_variable_browse(cfg, cat), reload, 0); 13146 } 13147 } 13148 ast_config_destroy(cfg); 13149 } 13150 #ifdef HAVE_PRI 13151 if (!reload) { 13152 for (x = 0; x < NUM_SPANS; x++) { 13153 pris[x].debugfd = -1; 13154 if (pris[x].pvts[0]) { 13155 if (start_pri(pris + x)) { 13156 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 13157 return -1; 13158 } else if (option_verbose > 1) 13159 ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1); 13160 } 13161 } 13162 } 13163 #endif 13164 /* And start the monitor for the first time */ 13165 restart_monitor(); 13166 return 0; 13167 }
static void * ss_thread | ( | void * | data | ) | [static] |
Definition at line 5691 of file chan_zap.c.
References ast_channel::_state, alloc_sub(), ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_CONTROL_RING, AST_CONTROL_UNHOLD, ast_db_put(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_free(), ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree, ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_read(), ast_safe_sleep(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), ast_shrink_phone_number(), ast_smdi_md_message_destroy(), ast_smdi_md_message_wait(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitfor(), ast_waitfordigit(), ast_waitstream(), ASTOBJ_UNREF, bump_gains(), zt_pvt::call_forward, callerid_feed(), callerid_feed_jp(), callerid_free(), callerid_get(), callerid_get_dtmf(), callerid_new(), ast_smdi_md_message::calling_st, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, CID_START_RING, zt_pvt::context, ast_channel::context, ringContextData::contextData, zt_pvt::defcontext, zt_pvt::dnd, zt_pvt::dop, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, zt_pvt::dtmfrelax, errno, event2str(), EVENT_FLAG_SYSTEM, ast_channel::exten, zt_pvt::exten, exten, ast_frame::frametype, free, func, ast_smdi_md_message::fwd_st, ast_channel::hangupcause, zt_pvt::hanguponpolarityswitch, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, zt_pvt::lastcid_num, len, zt_subchannel::linear, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), my_getsigstr(), name, NEED_MFDETECT, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), zt_pvt::polarity, POLARITY_IDLE, POLARITY_REV, restore_gains(), distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::smdi_iface, SMDI_MD_WAIT_TIMEOUT, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech, ast_channel::tech_pvt, zt_pvt::transfer, ast_smdi_md_message::type, unalloc_sub(), zt_pvt::use_callerid, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_enable_ec(), zt_get_event(), zt_get_index(), zt_set_hook(), zt_setlinear(), zt_wait_event(), and zt_wink().
Referenced by handle_init_event(), and zt_handle_event().
05692 { 05693 struct ast_channel *chan = data; 05694 struct zt_pvt *p = chan->tech_pvt; 05695 char exten[AST_MAX_EXTENSION] = ""; 05696 char exten2[AST_MAX_EXTENSION] = ""; 05697 unsigned char buf[256]; 05698 char dtmfcid[300]; 05699 char dtmfbuf[300]; 05700 struct callerid_state *cs = NULL; 05701 char *name = NULL, *number = NULL; 05702 int distMatches; 05703 int curRingData[3]; 05704 int receivedRingT; 05705 int counter1; 05706 int counter; 05707 int samples = 0; 05708 struct ast_smdi_md_message *smdi_msg = NULL; 05709 int flags; 05710 int i; 05711 int timeout; 05712 int getforward = 0; 05713 char *s1, *s2; 05714 int len = 0; 05715 int res; 05716 int index; 05717 int network; 05718 05719 /* in the bizarre case where the channel has become a zombie before we 05720 even get started here, abort safely 05721 */ 05722 if (!p) { 05723 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 05724 ast_hangup(chan); 05725 return NULL; 05726 } 05727 05728 if (option_verbose > 2) 05729 ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name); 05730 index = zt_get_index(chan, p, 1); 05731 if (index < 0) { 05732 ast_log(LOG_WARNING, "Huh?\n"); 05733 ast_hangup(chan); 05734 return NULL; 05735 } 05736 if (p->dsp) 05737 ast_dsp_digitreset(p->dsp); 05738 switch (p->sig) { 05739 #ifdef HAVE_PRI 05740 case SIG_PRI: 05741 /* Now loop looking for an extension */ 05742 ast_copy_string(exten, p->exten, sizeof(exten)); 05743 len = strlen(exten); 05744 res = 0; 05745 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05746 if (len && !ast_ignore_pattern(chan->context, exten)) { 05747 tone_zone_play_tone(p->subs[index].zfd, -1); 05748 } else { 05749 network = p->pri->nodetype == PRI_NETWORK || p->pri->nodetype == BRI_NETWORK || p->pri->nodetype == BRI_NETWORK_PTMP; 05750 if (network) { 05751 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05752 } else { 05753 /* cpe be quiet */ 05754 tone_zone_play_tone(p->subs[index].zfd, -1); 05755 } 05756 } 05757 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) 05758 timeout = matchdigittimeout; 05759 else 05760 timeout = gendigittimeout; 05761 res = ast_waitfordigit(chan, timeout); 05762 if (res < 0) { 05763 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05764 ast_hangup(chan); 05765 return NULL; 05766 } else if (res) { 05767 exten[len++] = res; 05768 exten[len] = '\0'; 05769 } else 05770 break; 05771 } 05772 /* if no extension was received ('unspecified') on overlap call, use the 's' extension */ 05773 if (ast_strlen_zero(exten)) { 05774 if (option_verbose > 2) 05775 ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n"); 05776 exten[0] = 's'; 05777 exten[1] = '\0'; 05778 } 05779 tone_zone_play_tone(p->subs[index].zfd, -1); 05780 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 05781 /* Start the real PBX */ 05782 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05783 if (p->dsp) ast_dsp_digitreset(p->dsp); 05784 zt_enable_ec(p); 05785 ast_setstate(chan, AST_STATE_RING); 05786 res = ast_pbx_run(chan); 05787 if (res) { 05788 ast_log(LOG_WARNING, "PBX exited non-zero!\n"); 05789 } 05790 } else { 05791 ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context); 05792 chan->hangupcause = AST_CAUSE_UNALLOCATED; 05793 ast_hangup(chan); 05794 p->exten[0] = '\0'; 05795 /* Since we send release complete here, we won't get one */ 05796 p->call = NULL; 05797 } 05798 return NULL; 05799 break; 05800 #endif 05801 case SIG_FEATD: 05802 case SIG_FEATDMF: 05803 case SIG_FEATDMF_TA: 05804 case SIG_E911: 05805 case SIG_FGC_CAMAMF: 05806 case SIG_FEATB: 05807 case SIG_EMWINK: 05808 case SIG_SF_FEATD: 05809 case SIG_SF_FEATDMF: 05810 case SIG_SF_FEATB: 05811 case SIG_SFWINK: 05812 if (zt_wink(p, index)) 05813 return NULL; 05814 /* Fall through */ 05815 case SIG_EM: 05816 case SIG_EM_E1: 05817 case SIG_SF: 05818 case SIG_FGC_CAMA: 05819 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05820 if (p->dsp) 05821 ast_dsp_digitreset(p->dsp); 05822 /* set digit mode appropriately */ 05823 if (p->dsp) { 05824 if (NEED_MFDETECT(p)) 05825 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05826 else 05827 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05828 } 05829 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 05830 /* Wait for the first digit only if immediate=no */ 05831 if (!p->immediate) 05832 /* Wait for the first digit (up to 5 seconds). */ 05833 res = ast_waitfordigit(chan, 5000); 05834 else 05835 res = 0; 05836 if (res > 0) { 05837 /* save first char */ 05838 dtmfbuf[0] = res; 05839 switch (p->sig) { 05840 case SIG_FEATD: 05841 case SIG_SF_FEATD: 05842 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05843 if (res > 0) 05844 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05845 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05846 break; 05847 case SIG_FEATDMF_TA: 05848 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05849 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05850 if (zt_wink(p, index)) return NULL; 05851 dtmfbuf[0] = 0; 05852 /* Wait for the first digit (up to 5 seconds). */ 05853 res = ast_waitfordigit(chan, 5000); 05854 if (res <= 0) break; 05855 dtmfbuf[0] = res; 05856 /* fall through intentionally */ 05857 case SIG_FEATDMF: 05858 case SIG_E911: 05859 case SIG_FGC_CAMAMF: 05860 case SIG_SF_FEATDMF: 05861 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05862 /* if international caca, do it again to get real ANO */ 05863 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14)) 05864 { 05865 if (zt_wink(p, index)) return NULL; 05866 dtmfbuf[0] = 0; 05867 /* Wait for the first digit (up to 5 seconds). */ 05868 res = ast_waitfordigit(chan, 5000); 05869 if (res <= 0) break; 05870 dtmfbuf[0] = res; 05871 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05872 } 05873 if (res > 0) { 05874 /* if E911, take off hook */ 05875 if (p->sig == SIG_E911) 05876 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05877 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 05878 } 05879 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05880 break; 05881 case SIG_FEATB: 05882 case SIG_SF_FEATB: 05883 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05884 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05885 break; 05886 case SIG_EMWINK: 05887 /* if we received a '*', we are actually receiving Feature Group D 05888 dial syntax, so use that mode; otherwise, fall through to normal 05889 mode 05890 */ 05891 if (res == '*') { 05892 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05893 if (res > 0) 05894 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05895 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05896 break; 05897 } 05898 default: 05899 /* If we got the first digit, get the rest */ 05900 len = 1; 05901 dtmfbuf[len] = '\0'; 05902 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05903 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05904 timeout = matchdigittimeout; 05905 } else { 05906 timeout = gendigittimeout; 05907 } 05908 res = ast_waitfordigit(chan, timeout); 05909 if (res < 0) { 05910 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05911 ast_hangup(chan); 05912 return NULL; 05913 } else if (res) { 05914 dtmfbuf[len++] = res; 05915 dtmfbuf[len] = '\0'; 05916 } else { 05917 break; 05918 } 05919 } 05920 break; 05921 } 05922 } 05923 if (res == -1) { 05924 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 05925 ast_hangup(chan); 05926 return NULL; 05927 } else if (res < 0) { 05928 ast_log(LOG_DEBUG, "Got hung up before digits finished\n"); 05929 ast_hangup(chan); 05930 return NULL; 05931 } 05932 05933 if (p->sig == SIG_FGC_CAMA) { 05934 char anibuf[100]; 05935 05936 if (ast_safe_sleep(chan,1000) == -1) { 05937 ast_hangup(chan); 05938 return NULL; 05939 } 05940 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05941 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05942 res = my_getsigstr(chan, anibuf, "#", 10000); 05943 if ((res > 0) && (strlen(anibuf) > 2)) { 05944 if (anibuf[strlen(anibuf) - 1] == '#') 05945 anibuf[strlen(anibuf) - 1] = 0; 05946 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 05947 } 05948 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05949 } 05950 05951 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 05952 if (ast_strlen_zero(exten)) 05953 ast_copy_string(exten, "s", sizeof(exten)); 05954 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 05955 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 05956 if (exten[0] == '*') { 05957 char *stringp=NULL; 05958 ast_copy_string(exten2, exten, sizeof(exten2)); 05959 /* Parse out extension and callerid */ 05960 stringp=exten2 +1; 05961 s1 = strsep(&stringp, "*"); 05962 s2 = strsep(&stringp, "*"); 05963 if (s2) { 05964 if (!ast_strlen_zero(p->cid_num)) 05965 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05966 else 05967 ast_set_callerid(chan, s1, NULL, s1); 05968 ast_copy_string(exten, s2, sizeof(exten)); 05969 } else 05970 ast_copy_string(exten, s1, sizeof(exten)); 05971 } else if (p->sig == SIG_FEATD) 05972 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05973 } 05974 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05975 if (exten[0] == '*') { 05976 char *stringp=NULL; 05977 ast_copy_string(exten2, exten, sizeof(exten2)); 05978 /* Parse out extension and callerid */ 05979 stringp=exten2 +1; 05980 s1 = strsep(&stringp, "#"); 05981 s2 = strsep(&stringp, "#"); 05982 if (s2) { 05983 if (!ast_strlen_zero(p->cid_num)) 05984 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05985 else 05986 if (*(s1 + 2)) 05987 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 05988 ast_copy_string(exten, s2 + 1, sizeof(exten)); 05989 } else 05990 ast_copy_string(exten, s1 + 2, sizeof(exten)); 05991 } else 05992 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05993 } 05994 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) { 05995 if (exten[0] == '*') { 05996 char *stringp=NULL; 05997 ast_copy_string(exten2, exten, sizeof(exten2)); 05998 /* Parse out extension and callerid */ 05999 stringp=exten2 +1; 06000 s1 = strsep(&stringp, "#"); 06001 s2 = strsep(&stringp, "#"); 06002 if (s2 && (*(s2 + 1) == '0')) { 06003 if (*(s2 + 2)) 06004 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 06005 } 06006 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 06007 else ast_copy_string(exten, "911", sizeof(exten)); 06008 } else 06009 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 06010 } 06011 if (p->sig == SIG_FEATB) { 06012 if (exten[0] == '*') { 06013 char *stringp=NULL; 06014 ast_copy_string(exten2, exten, sizeof(exten2)); 06015 /* Parse out extension and callerid */ 06016 stringp=exten2 +1; 06017 s1 = strsep(&stringp, "#"); 06018 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 06019 } else 06020 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 06021 } 06022 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 06023 zt_wink(p, index); 06024 /* some switches require a minimum guard time between 06025 the last FGD wink and something that answers 06026 immediately. This ensures it */ 06027 if (ast_safe_sleep(chan,100)) return NULL; 06028 } 06029 zt_enable_ec(p); 06030 if (NEED_MFDETECT(p)) { 06031 if (p->dsp) { 06032 if (!p->hardwaredtmf) 06033 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 06034 else { 06035 ast_dsp_free(p->dsp); 06036 p->dsp = NULL; 06037 } 06038 } 06039 } 06040 06041 if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) { 06042 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 06043 if (p->dsp) ast_dsp_digitreset(p->dsp); 06044 res = ast_pbx_run(chan); 06045 if (res) { 06046 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06047 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06048 } 06049 return NULL; 06050 } else { 06051 if (option_verbose > 2) 06052 ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 06053 sleep(2); 06054 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO); 06055 if (res < 0) 06056 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 06057 else 06058 sleep(1); 06059 res = ast_streamfile(chan, "ss-noservice", chan->language); 06060 if (res >= 0) 06061 ast_waitstream(chan, ""); 06062 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06063 ast_hangup(chan); 06064 return NULL; 06065 } 06066 break; 06067 case SIG_FXOLS: 06068 case SIG_FXOGS: 06069 case SIG_FXOKS: 06070 /* Read the first digit */ 06071 timeout = firstdigittimeout; 06072 /* If starting a threeway call, never timeout on the first digit so someone 06073 can use flash-hook as a "hold" feature */ 06074 if (p->subs[SUB_THREEWAY].owner) 06075 timeout = 999999; 06076 while (len < AST_MAX_EXTENSION-1) { 06077 /* Read digit unless it's supposed to be immediate, in which case the 06078 only answer is 's' */ 06079 if (p->immediate) 06080 res = 's'; 06081 else 06082 res = ast_waitfordigit(chan, timeout); 06083 timeout = 0; 06084 if (res < 0) { 06085 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 06086 res = tone_zone_play_tone(p->subs[index].zfd, -1); 06087 ast_hangup(chan); 06088 return NULL; 06089 } else if (res) { 06090 exten[len++]=res; 06091 exten[len] = '\0'; 06092 } 06093 if (!ast_ignore_pattern(chan->context, exten)) 06094 tone_zone_play_tone(p->subs[index].zfd, -1); 06095 else 06096 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 06097 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) { 06098 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 06099 if (getforward) { 06100 /* Record this as the forwarding extension */ 06101 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 06102 if (option_verbose > 2) 06103 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 06104 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06105 if (res) 06106 break; 06107 usleep(500000); 06108 res = tone_zone_play_tone(p->subs[index].zfd, -1); 06109 sleep(1); 06110 memset(exten, 0, sizeof(exten)); 06111 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 06112 len = 0; 06113 getforward = 0; 06114 } else { 06115 res = tone_zone_play_tone(p->subs[index].zfd, -1); 06116 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 06117 if (!ast_strlen_zero(p->cid_num)) { 06118 if (!p->hidecallerid) 06119 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 06120 else 06121 ast_set_callerid(chan, NULL, NULL, p->cid_num); 06122 } 06123 if (!ast_strlen_zero(p->cid_name)) { 06124 if (!p->hidecallerid) 06125 ast_set_callerid(chan, NULL, p->cid_name, NULL); 06126 } 06127 ast_setstate(chan, AST_STATE_RING); 06128 zt_enable_ec(p); 06129 res = ast_pbx_run(chan); 06130 if (res) { 06131 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06132 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06133 } 06134 return NULL; 06135 } 06136 } else { 06137 /* It's a match, but they just typed a digit, and there is an ambiguous match, 06138 so just set the timeout to matchdigittimeout and wait some more */ 06139 timeout = matchdigittimeout; 06140 } 06141 } else if (res == 0) { 06142 ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n"); 06143 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06144 zt_wait_event(p->subs[index].zfd); 06145 ast_hangup(chan); 06146 return NULL; 06147 } else if (p->callwaiting && !strcmp(exten, "*70")) { 06148 if (option_verbose > 2) 06149 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 06150 /* Disable call waiting if enabled */ 06151 p->callwaiting = 0; 06152 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06153 if (res) { 06154 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 06155 chan->name, strerror(errno)); 06156 } 06157 len = 0; 06158 ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len); 06159 memset(exten, 0, sizeof(exten)); 06160 timeout = firstdigittimeout; 06161 06162 } else if (!strcmp(exten,ast_pickup_ext())) { 06163 /* Scan all channels and see if any there 06164 * ringing channqels with that have call groups 06165 * that equal this channels pickup group 06166 */ 06167 if (index == SUB_REAL) { 06168 /* Switch us from Third call to Call Wait */ 06169 if (p->subs[SUB_THREEWAY].owner) { 06170 /* If you make a threeway call and the *8# a call, it should actually 06171 look like a callwait */ 06172 alloc_sub(p, SUB_CALLWAIT); 06173 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 06174 unalloc_sub(p, SUB_THREEWAY); 06175 } 06176 zt_enable_ec(p); 06177 if (ast_pickup_call(chan)) { 06178 ast_log(LOG_DEBUG, "No call pickup possible...\n"); 06179 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06180 zt_wait_event(p->subs[index].zfd); 06181 } 06182 ast_hangup(chan); 06183 return NULL; 06184 } else { 06185 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 06186 ast_hangup(chan); 06187 return NULL; 06188 } 06189 06190 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 06191 if (option_verbose > 2) 06192 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 06193 /* Disable Caller*ID if enabled */ 06194 p->hidecallerid = 1; 06195 if (chan->cid.cid_num) 06196 free(chan->cid.cid_num); 06197 chan->cid.cid_num = NULL; 06198 if (chan->cid.cid_name) 06199 free(chan->cid.cid_name); 06200 chan->cid.cid_name = NULL; 06201 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06202 if (res) { 06203 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 06204 chan->name, strerror(errno)); 06205 } 06206 len = 0; 06207 memset(exten, 0, sizeof(exten)); 06208 timeout = firstdigittimeout; 06209 } else if (p->callreturn && !strcmp(exten, "*69")) { 06210 res = 0; 06211 if (!ast_strlen_zero(p->lastcid_num)) { 06212 res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language); 06213 } 06214 if (!res) 06215 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06216 break; 06217 } else if (!strcmp(exten, "*78")) { 06218 /* Do not disturb */ 06219 if (option_verbose > 2) 06220 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel); 06221 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 06222 "Channel: Zap/%d\r\n" 06223 "Status: enabled\r\n", p->channel); 06224 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06225 p->dnd = 1; 06226 getforward = 0; 06227 memset(exten, 0, sizeof(exten)); 06228 len = 0; 06229 } else if (!strcmp(exten, "*79")) { 06230 /* Do not disturb */ 06231 if (option_verbose > 2) 06232 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel); 06233 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 06234 "Channel: Zap/%d\r\n" 06235 "Status: disabled\r\n", p->channel); 06236 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06237 p->dnd = 0; 06238 getforward = 0; 06239 memset(exten, 0, sizeof(exten)); 06240 len = 0; 06241 } else if (p->cancallforward && !strcmp(exten, "*72")) { 06242 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06243 getforward = 1; 06244 memset(exten, 0, sizeof(exten)); 06245 len = 0; 06246 } else if (p->cancallforward && !strcmp(exten, "*73")) { 06247 if (option_verbose > 2) 06248 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel); 06249 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06250 memset(p->call_forward, 0, sizeof(p->call_forward)); 06251 getforward = 0; 06252 memset(exten, 0, sizeof(exten)); 06253 len = 0; 06254 } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 06255 p->subs[SUB_THREEWAY].owner && 06256 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 06257 /* This is a three way call, the main call being a real channel, 06258 and we're parking the first call. */ 06259 ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL); 06260 if (option_verbose > 2) 06261 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 06262 break; 06263 } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) { 06264 if (option_verbose > 2) 06265 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num); 06266 res = ast_db_put("blacklist", p->lastcid_num, "1"); 06267 if (!res) { 06268 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06269 memset(exten, 0, sizeof(exten)); 06270 len = 0; 06271 } 06272 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 06273 if (option_verbose > 2) 06274 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 06275 /* Enable Caller*ID if enabled */ 06276 p->hidecallerid = 0; 06277 if (chan->cid.cid_num) 06278 free(chan->cid.cid_num); 06279 chan->cid.cid_num = NULL; 06280 if (chan->cid.cid_name) 06281 free(chan->cid.cid_name); 06282 chan->cid.cid_name = NULL; 06283 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 06284 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 06285 if (res) { 06286 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 06287 chan->name, strerror(errno)); 06288 } 06289 len = 0; 06290 memset(exten, 0, sizeof(exten)); 06291 timeout = firstdigittimeout; 06292 } else if (!strcmp(exten, "*0")) { 06293 struct ast_channel *nbridge = 06294 p->subs[SUB_THREEWAY].owner; 06295 struct zt_pvt *pbridge = NULL; 06296 /* set up the private struct of the bridged one, if any */ 06297 if (nbridge && ast_bridged_channel(nbridge)) 06298 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 06299 if (nbridge && pbridge && 06300 (nbridge->tech == &zap_tech) && 06301 (ast_bridged_channel(nbridge)->tech == &zap_tech) && 06302 ISTRUNK(pbridge)) { 06303 int func = ZT_FLASH; 06304 /* Clear out the dial buffer */ 06305 p->dop.dialstr[0] = '\0'; 06306 /* flash hookswitch */ 06307 if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 06308 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 06309 nbridge->name, strerror(errno)); 06310 } 06311 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06312 unalloc_sub(p, SUB_THREEWAY); 06313 p->owner = p->subs[SUB_REAL].owner; 06314 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 06315 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 06316 ast_hangup(chan); 06317 return NULL; 06318 } else { 06319 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06320 zt_wait_event(p->subs[index].zfd); 06321 tone_zone_play_tone(p->subs[index].zfd, -1); 06322 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06323 unalloc_sub(p, SUB_THREEWAY); 06324 p->owner = p->subs[SUB_REAL].owner; 06325 ast_hangup(chan); 06326 return NULL; 06327 } 06328 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 06329 ((exten[0] != '*') || (strlen(exten) > 2))) { 06330 if (option_debug) 06331 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); 06332 break; 06333 } 06334 if (!timeout) 06335 timeout = gendigittimeout; 06336 if (len && !ast_ignore_pattern(chan->context, exten)) 06337 tone_zone_play_tone(p->subs[index].zfd, -1); 06338 } 06339 break; 06340 case SIG_FXSLS: 06341 case SIG_FXSGS: 06342 case SIG_FXSKS: 06343 #ifdef HAVE_PRI 06344 if (p->pri) { 06345 /* This is a GR-303 trunk actually. Wait for the first ring... */ 06346 struct ast_frame *f; 06347 int res; 06348 time_t start; 06349 06350 time(&start); 06351 ast_setstate(chan, AST_STATE_RING); 06352 while (time(NULL) < start + 3) { 06353 res = ast_waitfor(chan, 1000); 06354 if (res) { 06355 f = ast_read(chan); 06356 if (!f) { 06357 ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n"); 06358 ast_hangup(chan); 06359 return NULL; 06360 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) { 06361 res = 1; 06362 } else 06363 res = 0; 06364 ast_frfree(f); 06365 if (res) { 06366 ast_log(LOG_DEBUG, "Got ring!\n"); 06367 res = 0; 06368 break; 06369 } 06370 } 06371 } 06372 } 06373 #endif 06374 /* check for SMDI messages */ 06375 if (p->use_smdi && p->smdi_iface) { 06376 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT); 06377 06378 if (smdi_msg != NULL) { 06379 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 06380 06381 if (smdi_msg->type == 'B') 06382 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 06383 else if (smdi_msg->type == 'N') 06384 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 06385 06386 ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name); 06387 } else { 06388 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 06389 } 06390 } 06391 06392 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 06393 number = smdi_msg->calling_st; 06394 06395 /* If we want caller id, we're in a prering state due to a polarity reversal 06396 * and we're set to use a polarity reversal to trigger the start of caller id, 06397 * grab the caller id and wait for ringing to start... */ 06398 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) { 06399 /* If set to use DTMF CID signalling, listen for DTMF */ 06400 if (p->cid_signalling == CID_SIG_DTMF) { 06401 int i = 0; 06402 cs = NULL; 06403 ast_log(LOG_DEBUG, "Receiving DTMF cid on " 06404 "channel %s\n", chan->name); 06405 zt_setlinear(p->subs[index].zfd, 0); 06406 res = 2000; 06407 for (;;) { 06408 struct ast_frame *f; 06409 res = ast_waitfor(chan, res); 06410 if (res <= 0) { 06411 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 06412 "Exiting simple switch\n"); 06413 ast_hangup(chan); 06414 return NULL; 06415 } 06416 f = ast_read(chan); 06417 if (!f) 06418 break; 06419 if (f->frametype == AST_FRAME_DTMF) { 06420 dtmfbuf[i++] = f->subclass; 06421 ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass); 06422 res = 2000; 06423 } 06424 ast_frfree(f); 06425 if (chan->_state == AST_STATE_RING || 06426 chan->_state == AST_STATE_RINGING) 06427 break; /* Got ring */ 06428 } 06429 dtmfbuf[i] = '\0'; 06430 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06431 /* Got cid and ring. */ 06432 ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf); 06433 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 06434 ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 06435 dtmfcid, flags); 06436 /* If first byte is NULL, we have no cid */ 06437 if (!ast_strlen_zero(dtmfcid)) 06438 number = dtmfcid; 06439 else 06440 number = NULL; 06441 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 06442 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 06443 cs = callerid_new(p->cid_signalling); 06444 if (cs) { 06445 samples = 0; 06446 #if 1 06447 bump_gains(p); 06448 #endif 06449 /* Take out of linear mode for Caller*ID processing */ 06450 zt_setlinear(p->subs[index].zfd, 0); 06451 06452 /* First we wait and listen for the Caller*ID */ 06453 for (;;) { 06454 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06455 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06456 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06457 callerid_free(cs); 06458 ast_hangup(chan); 06459 return NULL; 06460 } 06461 if (i & ZT_IOMUX_SIGEVENT) { 06462 res = zt_get_event(p->subs[index].zfd); 06463 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06464 06465 if (p->cid_signalling == CID_SIG_V23_JP) { 06466 #ifdef ZT_EVENT_RINGBEGIN 06467 if (res == ZT_EVENT_RINGBEGIN) { 06468 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06469 usleep(1); 06470 } 06471 #endif 06472 } else { 06473 res = 0; 06474 break; 06475 } 06476 } else if (i & ZT_IOMUX_READ) { 06477 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06478 if (res < 0) { 06479 if (errno != ELAST) { 06480 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06481 callerid_free(cs); 06482 ast_hangup(chan); 06483 return NULL; 06484 } 06485 break; 06486 } 06487 samples += res; 06488 06489 if (p->cid_signalling == CID_SIG_V23_JP) { 06490 res = callerid_feed_jp(cs, buf, res, AST_LAW(p)); 06491 } else { 06492 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06493 } 06494 06495 if (res < 0) { 06496 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06497 break; 06498 } else if (res) 06499 break; 06500 else if (samples > (8000 * 10)) 06501 break; 06502 } 06503 } 06504 if (res == 1) { 06505 callerid_get(cs, &name, &number, &flags); 06506 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06507 } 06508 if (res < 0) { 06509 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06510 } 06511 06512 if (p->cid_signalling == CID_SIG_V23_JP) { 06513 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 06514 usleep(1); 06515 res = 4000; 06516 } else { 06517 06518 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 06519 res = 2000; 06520 } 06521 06522 for (;;) { 06523 struct ast_frame *f; 06524 res = ast_waitfor(chan, res); 06525 if (res <= 0) { 06526 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 06527 "Exiting simple switch\n"); 06528 ast_hangup(chan); 06529 return NULL; 06530 } 06531 f = ast_read(chan); 06532 ast_frfree(f); 06533 if (chan->_state == AST_STATE_RING || 06534 chan->_state == AST_STATE_RINGING) 06535 break; /* Got ring */ 06536 } 06537 06538 /* We must have a ring by now, so, if configured, lets try to listen for 06539 * distinctive ringing */ 06540 if (p->usedistinctiveringdetection == 1) { 06541 len = 0; 06542 distMatches = 0; 06543 /* Clear the current ring data array so we dont have old data in it. */ 06544 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06545 curRingData[receivedRingT] = 0; 06546 receivedRingT = 0; 06547 counter = 0; 06548 counter1 = 0; 06549 /* Check to see if context is what it should be, if not set to be. */ 06550 if (strcmp(p->context,p->defcontext) != 0) { 06551 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06552 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06553 } 06554 06555 for (;;) { 06556 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06557 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06558 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06559 callerid_free(cs); 06560 ast_hangup(chan); 06561 return NULL; 06562 } 06563 if (i & ZT_IOMUX_SIGEVENT) { 06564 res = zt_get_event(p->subs[index].zfd); 06565 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06566 res = 0; 06567 /* Let us detect distinctive ring */ 06568 06569 curRingData[receivedRingT] = p->ringt; 06570 06571 if (p->ringt < p->ringt_base/2) 06572 break; 06573 /* Increment the ringT counter so we can match it against 06574 values in zapata.conf for distinctive ring */ 06575 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06576 break; 06577 } else if (i & ZT_IOMUX_READ) { 06578 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06579 if (res < 0) { 06580 if (errno != ELAST) { 06581 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06582 callerid_free(cs); 06583 ast_hangup(chan); 06584 return NULL; 06585 } 06586 break; 06587 } 06588 if (p->ringt) 06589 p->ringt--; 06590 if (p->ringt == 1) { 06591 res = -1; 06592 break; 06593 } 06594 } 06595 } 06596 if (option_verbose > 2) 06597 /* this only shows up if you have n of the dring patterns filled in */ 06598 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06599 06600 for (counter = 0; counter < 3; counter++) { 06601 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06602 channel */ 06603 distMatches = 0; 06604 for (counter1 = 0; counter1 < 3; counter1++) { 06605 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06606 (p->drings.ringnum[counter].ring[counter1]-10)) { 06607 distMatches++; 06608 } 06609 } 06610 if (distMatches == 3) { 06611 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06612 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06613 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06614 if (option_verbose > 2) 06615 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06616 break; 06617 } 06618 } 06619 } 06620 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06621 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06622 #if 1 06623 restore_gains(p); 06624 #endif 06625 } else 06626 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06627 } else { 06628 ast_log(LOG_WARNING, "Channel %s in prering " 06629 "state, but I have nothing to do. " 06630 "Terminating simple switch, should be " 06631 "restarted by the actual ring.\n", 06632 chan->name); 06633 ast_hangup(chan); 06634 return NULL; 06635 } 06636 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 06637 /* FSK Bell202 callerID */ 06638 cs = callerid_new(p->cid_signalling); 06639 if (cs) { 06640 #if 1 06641 bump_gains(p); 06642 #endif 06643 samples = 0; 06644 len = 0; 06645 distMatches = 0; 06646 /* Clear the current ring data array so we dont have old data in it. */ 06647 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06648 curRingData[receivedRingT] = 0; 06649 receivedRingT = 0; 06650 counter = 0; 06651 counter1 = 0; 06652 /* Check to see if context is what it should be, if not set to be. */ 06653 if (strcmp(p->context,p->defcontext) != 0) { 06654 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06655 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06656 } 06657 06658 /* Take out of linear mode for Caller*ID processing */ 06659 zt_setlinear(p->subs[index].zfd, 0); 06660 for (;;) { 06661 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06662 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06663 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06664 callerid_free(cs); 06665 ast_hangup(chan); 06666 return NULL; 06667 } 06668 if (i & ZT_IOMUX_SIGEVENT) { 06669 res = zt_get_event(p->subs[index].zfd); 06670 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06671 /* If we get a PR event, they hung up while processing calerid */ 06672 if ( res == ZT_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) { 06673 ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel); 06674 p->polarity = POLARITY_IDLE; 06675 callerid_free(cs); 06676 ast_hangup(chan); 06677 return NULL; 06678 } 06679 res = 0; 06680 /* Let us detect callerid when the telco uses distinctive ring */ 06681 06682 curRingData[receivedRingT] = p->ringt; 06683 06684 if (p->ringt < p->ringt_base/2) 06685 break; 06686 /* Increment the ringT counter so we can match it against 06687 values in zapata.conf for distinctive ring */ 06688 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06689 break; 06690 } else if (i & ZT_IOMUX_READ) { 06691 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06692 if (res < 0) { 06693 if (errno != ELAST) { 06694 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06695 callerid_free(cs); 06696 ast_hangup(chan); 06697 return NULL; 06698 } 06699 break; 06700 } 06701 if (p->ringt) 06702 p->ringt--; 06703 if (p->ringt == 1) { 06704 res = -1; 06705 break; 06706 } 06707 samples += res; 06708 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06709 if (res < 0) { 06710 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06711 break; 06712 } else if (res) 06713 break; 06714 else if (samples > (8000 * 10)) 06715 break; 06716 } 06717 } 06718 if (res == 1) { 06719 callerid_get(cs, &name, &number, &flags); 06720 if (option_debug) 06721 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06722 } 06723 if (distinctiveringaftercid == 1) { 06724 /* Clear the current ring data array so we dont have old data in it. */ 06725 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) { 06726 curRingData[receivedRingT] = 0; 06727 } 06728 receivedRingT = 0; 06729 if (option_verbose > 2) 06730 ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n"); 06731 for (;;) { 06732 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06733 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06734 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06735 callerid_free(cs); 06736 ast_hangup(chan); 06737 return NULL; 06738 } 06739 if (i & ZT_IOMUX_SIGEVENT) { 06740 res = zt_get_event(p->subs[index].zfd); 06741 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06742 res = 0; 06743 /* Let us detect callerid when the telco uses distinctive ring */ 06744 06745 curRingData[receivedRingT] = p->ringt; 06746 06747 if (p->ringt < p->ringt_base/2) 06748 break; 06749 /* Increment the ringT counter so we can match it against 06750 values in zapata.conf for distinctive ring */ 06751 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06752 break; 06753 } else if (i & ZT_IOMUX_READ) { 06754 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06755 if (res < 0) { 06756 if (errno != ELAST) { 06757 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06758 callerid_free(cs); 06759 ast_hangup(chan); 06760 return NULL; 06761 } 06762 break; 06763 } 06764 if (p->ringt) 06765 p->ringt--; 06766 if (p->ringt == 1) { 06767 res = -1; 06768 break; 06769 } 06770 } 06771 } 06772 } 06773 if (p->usedistinctiveringdetection == 1) { 06774 if (option_verbose > 2) 06775 /* this only shows up if you have n of the dring patterns filled in */ 06776 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06777 06778 for (counter = 0; counter < 3; counter++) { 06779 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06780 channel */ 06781 if (option_verbose > 2) 06782 /* this only shows up if you have n of the dring patterns filled in */ 06783 ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n", 06784 p->drings.ringnum[counter].ring[0], 06785 p->drings.ringnum[counter].ring[1], 06786 p->drings.ringnum[counter].ring[2]); 06787 distMatches = 0; 06788 for (counter1 = 0; counter1 < 3; counter1++) { 06789 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06790 (p->drings.ringnum[counter].ring[counter1]-10)) { 06791 distMatches++; 06792 } 06793 } 06794 if (distMatches == 3) { 06795 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06796 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06797 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06798 if (option_verbose > 2) 06799 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06800 break; 06801 } 06802 } 06803 } 06804 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06805 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06806 #if 1 06807 restore_gains(p); 06808 #endif 06809 if (res < 0) { 06810 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06811 } 06812 } else 06813 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06814 } 06815 else 06816 cs = NULL; 06817 06818 if (number) 06819 ast_shrink_phone_number(number); 06820 ast_set_callerid(chan, number, name, number); 06821 06822 if (smdi_msg) 06823 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 06824 06825 if (cs) 06826 callerid_free(cs); 06827 06828 ast_setstate(chan, AST_STATE_RING); 06829 chan->rings = 1; 06830 p->ringt = p->ringt_base; 06831 res = ast_pbx_run(chan); 06832 if (res) { 06833 ast_hangup(chan); 06834 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06835 } 06836 return NULL; 06837 default: 06838 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 06839 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06840 if (res < 0) 06841 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06842 } 06843 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06844 if (res < 0) 06845 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06846 ast_hangup(chan); 06847 return NULL; 06848 }
static void swap_subs | ( | struct zt_pvt * | p, | |
int | a, | |||
int | b | |||
) | [static] |
Definition at line 1022 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().
01023 { 01024 int tchan; 01025 int tinthreeway; 01026 struct ast_channel *towner; 01027 01028 ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b); 01029 01030 tchan = p->subs[a].chan; 01031 towner = p->subs[a].owner; 01032 tinthreeway = p->subs[a].inthreeway; 01033 01034 p->subs[a].chan = p->subs[b].chan; 01035 p->subs[a].owner = p->subs[b].owner; 01036 p->subs[a].inthreeway = p->subs[b].inthreeway; 01037 01038 p->subs[b].chan = tchan; 01039 p->subs[b].owner = towner; 01040 p->subs[b].inthreeway = tinthreeway; 01041 01042 if (p->subs[a].owner) 01043 p->subs[a].owner->fds[0] = p->subs[a].zfd; 01044 if (p->subs[b].owner) 01045 p->subs[b].owner->fds[0] = p->subs[b].zfd; 01046 wakeup_sub(p, a, NULL); 01047 wakeup_sub(p, b, NULL); 01048 }
static int unalloc_sub | ( | struct zt_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 1148 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().
01149 { 01150 if (!x) { 01151 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel); 01152 return -1; 01153 } 01154 ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel); 01155 if (p->subs[x].zfd > -1) { 01156 zt_close(p->subs[x].zfd); 01157 } 01158 p->subs[x].zfd = -1; 01159 p->subs[x].linear = 0; 01160 p->subs[x].chan = 0; 01161 p->subs[x].owner = NULL; 01162 p->subs[x].inthreeway = 0; 01163 p->polarity = POLARITY_IDLE; 01164 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf)); 01165 return 0; 01166 }
static int unload_module | ( | void | ) | [static] |
Definition at line 12222 of file chan_zap.c.
References __unload_module(), ast_mutex_destroy(), and lock.
12223 { 12224 #ifdef HAVE_PRI 12225 int y; 12226 for (y = 0; y < NUM_SPANS; y++) 12227 ast_mutex_destroy(&pris[y].lock); 12228 #endif 12229 return __unload_module(); 12230 }
static int update_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1536 of file chan_zap.c.
References ast_log(), zt_pvt::channel, conf_add(), conf_del(), zt_pvt::confno, GET_CHANNEL, zt_pvt::inconference, zt_subchannel::inthreeway, isslavenative(), LOG_DEBUG, zt_pvt::master, MAX_SLAVES, option_debug, zt_pvt::slaves, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), mkintf(), zt_bridge(), zt_fixup(), zt_handle_event(), zt_hangup(), and zt_unlink().
01537 { 01538 int needconf = 0; 01539 int x; 01540 int useslavenative; 01541 struct zt_pvt *slave = NULL; 01542 01543 useslavenative = isslavenative(p, &slave); 01544 /* Start with the obvious, general stuff */ 01545 for (x = 0; x < 3; x++) { 01546 /* Look for three way calls */ 01547 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) { 01548 conf_add(p, &p->subs[x], x, 0); 01549 needconf++; 01550 } else { 01551 conf_del(p, &p->subs[x], x); 01552 } 01553 } 01554 /* If we have a slave, add him to our conference now. or DAX 01555 if this is slave native */ 01556 for (x = 0; x < MAX_SLAVES; x++) { 01557 if (p->slaves[x]) { 01558 if (useslavenative) 01559 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 01560 else { 01561 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 01562 needconf++; 01563 } 01564 } 01565 } 01566 /* If we're supposed to be in there, do so now */ 01567 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 01568 if (useslavenative) 01569 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 01570 else { 01571 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 01572 needconf++; 01573 } 01574 } 01575 /* If we have a master, add ourselves to his conference */ 01576 if (p->master) { 01577 if (isslavenative(p->master, NULL)) { 01578 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 01579 } else { 01580 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 01581 } 01582 } 01583 if (!needconf) { 01584 /* Nobody is left (or should be left) in our conference. 01585 Kill it. */ 01586 p->confno = -1; 01587 } 01588 if (option_debug) 01589 ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 01590 return 0; 01591 }
static void wakeup_sub | ( | struct zt_pvt * | p, | |
int | a, | |||
void * | pri | |||
) | [static] |
Definition at line 962 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().
00964 { 00965 #ifdef HAVE_PRI 00966 if (pri) 00967 ast_mutex_unlock(&pri->lock); 00968 #endif 00969 for (;;) { 00970 if (p->subs[a].owner) { 00971 if (ast_mutex_trylock(&p->subs[a].owner->lock)) { 00972 ast_mutex_unlock(&p->lock); 00973 usleep(1); 00974 ast_mutex_lock(&p->lock); 00975 } else { 00976 ast_queue_frame(p->subs[a].owner, &ast_null_frame); 00977 ast_mutex_unlock(&p->subs[a].owner->lock); 00978 break; 00979 } 00980 } else 00981 break; 00982 } 00983 #ifdef HAVE_PRI 00984 if (pri) 00985 ast_mutex_lock(&pri->lock); 00986 #endif 00987 }
static int zap_destroy_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 11574 of file chan_zap.c.
References RESULT_SHOWUSAGE, and zap_destroy_channel_bynum().
11575 { 11576 int channel; 11577 11578 if (argc != 4) 11579 return RESULT_SHOWUSAGE; 11580 11581 channel = atoi(argv[3]); 11582 11583 return zap_destroy_channel_bynum(channel); 11584 }
static int zap_destroy_channel_bynum | ( | int | channel | ) | [static] |
Definition at line 6851 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().
06852 { 06853 struct zt_pvt *tmp = NULL; 06854 struct zt_pvt *prev = NULL; 06855 06856 tmp = iflist; 06857 while (tmp) { 06858 if (tmp->channel == channel) { 06859 destroy_channel(prev, tmp, 1); 06860 return RESULT_SUCCESS; 06861 } 06862 prev = tmp; 06863 tmp = tmp->next; 06864 } 06865 return RESULT_FAILURE; 06866 }
static int zap_fake_event | ( | struct zt_pvt * | p, | |
int | mode | |||
) | [static] |
Definition at line 11962 of file chan_zap.c.
References ast_log(), zt_pvt::fake_event, HANGUP, LOG_WARNING, zt_pvt::owner, and TRANSFER.
Referenced by action_transfer(), and action_transferhangup().
11963 { 11964 if (p) { 11965 switch (mode) { 11966 case TRANSFER: 11967 p->fake_event = ZT_EVENT_WINKFLASH; 11968 break; 11969 case HANGUP: 11970 p->fake_event = ZT_EVENT_ONHOOK; 11971 break; 11972 default: 11973 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name); 11974 } 11975 } 11976 return 0; 11977 }
Definition at line 992 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), zt_pvt::lock, ast_channel::lock, and zt_pvt::owner.
Referenced by action_zapdialoffhook().
00994 { 00995 /* We must unlock the PRI to avoid the possibility of a deadlock */ 00996 #ifdef HAVE_PRI 00997 if (pri) 00998 ast_mutex_unlock(&pri->lock); 00999 #endif 01000 for (;;) { 01001 if (p->owner) { 01002 if (ast_mutex_trylock(&p->owner->lock)) { 01003 ast_mutex_unlock(&p->lock); 01004 usleep(1); 01005 ast_mutex_lock(&p->lock); 01006 } else { 01007 ast_queue_frame(p->owner, f); 01008 ast_mutex_unlock(&p->owner->lock); 01009 break; 01010 } 01011 } else 01012 break; 01013 } 01014 #ifdef HAVE_PRI 01015 if (pri) 01016 ast_mutex_lock(&pri->lock); 01017 #endif 01018 }
static int zap_restart | ( | void | ) | [static] |
Definition at line 11587 of file chan_zap.c.
References ast_log(), ast_verbose(), destroy_channel(), iflist, LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, setup_zap(), and VERBOSE_PREFIX_1.
Referenced by action_zaprestart(), and zap_restart_cmd().
11588 { 11589 if (option_verbose > 0) 11590 ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n"); 11591 while (iflist) { 11592 if (option_debug) 11593 ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel); 11594 /* Also updates iflist: */ 11595 destroy_channel(NULL, iflist, 1); 11596 } 11597 if (option_debug) 11598 ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n"); 11599 if (setup_zap(0) != 0) { 11600 ast_log(LOG_WARNING, "Reload channels from zap config failed!\n"); 11601 return 1; 11602 } 11603 return 0; 11604 }
static int zap_restart_cmd | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 11606 of file chan_zap.c.
References RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and zap_restart().
11607 { 11608 if (argc != 2) { 11609 return RESULT_SHOWUSAGE; 11610 } 11611 11612 if (zap_restart() != 0) 11613 return RESULT_FAILURE; 11614 return RESULT_SUCCESS; 11615 }
static int zap_show_channel | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 11688 of file chan_zap.c.
References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::callwaitcas, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, zt_pvt::destroy, zt_pvt::dialing, zt_pvt::dsp, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echocanon, zt_pvt::exten, zt_pvt::faxhandled, iflist, zt_pvt::inalarm, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::law, zt_subchannel::linear, lock, LOG_WARNING, zt_pvt::master, MAX_SLAVES, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::propconfno, zt_pvt::pulsedial, zt_pvt::radio, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, zt_pvt::sig, sig2str, zt_pvt::slaves, zt_pvt::span, SUB_CALLWAIT, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.
11689 { 11690 int channel; 11691 struct zt_pvt *tmp = NULL; 11692 ZT_CONFINFO ci; 11693 ZT_PARAMS ps; 11694 int x; 11695 ast_mutex_t *lock; 11696 struct zt_pvt *start; 11697 #ifdef HAVE_PRI 11698 char *c; 11699 int trunkgroup; 11700 struct zt_pri *pri=NULL; 11701 #endif 11702 11703 lock = &iflock; 11704 start = iflist; 11705 11706 if (argc != 4) 11707 return RESULT_SHOWUSAGE; 11708 #ifdef HAVE_PRI 11709 if ((c = strchr(argv[3], ':'))) { 11710 if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2) 11711 return RESULT_SHOWUSAGE; 11712 if ((trunkgroup < 1) || (channel < 1)) 11713 return RESULT_SHOWUSAGE; 11714 for (x = 0; x < NUM_SPANS; x++) { 11715 if (pris[x].trunkgroup == trunkgroup) { 11716 pri = pris + x; 11717 break; 11718 } 11719 } 11720 if (pri) { 11721 start = pri->crvs; 11722 lock = &pri->lock; 11723 } else { 11724 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 11725 return RESULT_FAILURE; 11726 } 11727 } else 11728 #endif 11729 channel = atoi(argv[3]); 11730 11731 ast_mutex_lock(lock); 11732 tmp = start; 11733 while (tmp) { 11734 if (tmp->channel == channel) { 11735 #ifdef HAVE_PRI 11736 if (pri) 11737 ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel); 11738 else 11739 #endif 11740 ast_cli(fd, "Channel: %d\n", tmp->channel); 11741 ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd); 11742 ast_cli(fd, "Span: %d\n", tmp->span); 11743 ast_cli(fd, "Extension: %s\n", tmp->exten); 11744 ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 11745 ast_cli(fd, "Context: %s\n", tmp->context); 11746 ast_cli(fd, "Caller ID: %s\n", tmp->cid_num); 11747 ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton); 11748 ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name); 11749 ast_cli(fd, "Destroy: %d\n", tmp->destroy); 11750 ast_cli(fd, "InAlarm: %d\n", tmp->inalarm); 11751 ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 11752 ast_cli(fd, "Radio: %d\n", tmp->radio); 11753 ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>"); 11754 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)" : ""); 11755 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)" : ""); 11756 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)" : ""); 11757 ast_cli(fd, "Confno: %d\n", tmp->confno); 11758 ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno); 11759 ast_cli(fd, "Real in conference: %d\n", tmp->inconference); 11760 ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 11761 ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 11762 ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 11763 ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown"); 11764 ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 11765 ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 11766 ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF"); 11767 if (tmp->master) 11768 ast_cli(fd, "Master Channel: %d\n", tmp->master->channel); 11769 for (x = 0; x < MAX_SLAVES; x++) { 11770 if (tmp->slaves[x]) 11771 ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 11772 } 11773 #ifdef HAVE_PRI 11774 if (tmp->pri) { 11775 ast_cli(fd, "PRI Flags: "); 11776 if (tmp->resetting) 11777 ast_cli(fd, "Resetting "); 11778 if (tmp->call) 11779 ast_cli(fd, "Call "); 11780 if (tmp->bearer) 11781 ast_cli(fd, "Bearer "); 11782 ast_cli(fd, "\n"); 11783 if (tmp->logicalspan) 11784 ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan); 11785 else 11786 ast_cli(fd, "PRI Logical Span: Implicit\n"); 11787 } 11788 11789 #endif 11790 memset(&ci, 0, sizeof(ci)); 11791 ps.channo = tmp->channel; 11792 if (tmp->subs[SUB_REAL].zfd > -1) { 11793 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 11794 ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 11795 } 11796 #ifdef ZT_GETCONFMUTE 11797 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) { 11798 ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 11799 } 11800 #endif 11801 if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 11802 ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel); 11803 } else { 11804 ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 11805 } 11806 } 11807 ast_mutex_unlock(lock); 11808 return RESULT_SUCCESS; 11809 } 11810 tmp = tmp->next; 11811 } 11812 11813 ast_cli(fd, "Unable to find given channel %d\n", channel); 11814 ast_mutex_unlock(lock); 11815 return RESULT_FAILURE; 11816 }
static int zap_show_channels | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 11627 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.
11628 { 11629 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 11630 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 11631 struct zt_pvt *tmp = NULL; 11632 char tmps[20] = ""; 11633 ast_mutex_t *lock; 11634 struct zt_pvt *start; 11635 #ifdef HAVE_PRI 11636 int trunkgroup; 11637 struct zt_pri *pri = NULL; 11638 int x; 11639 #endif 11640 11641 lock = &iflock; 11642 start = iflist; 11643 11644 #ifdef HAVE_PRI 11645 if (argc == 4) { 11646 if ((trunkgroup = atoi(argv[3])) < 1) 11647 return RESULT_SHOWUSAGE; 11648 for (x = 0; x < NUM_SPANS; x++) { 11649 if (pris[x].trunkgroup == trunkgroup) { 11650 pri = pris + x; 11651 break; 11652 } 11653 } 11654 if (pri) { 11655 start = pri->crvs; 11656 lock = &pri->lock; 11657 } else { 11658 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 11659 return RESULT_FAILURE; 11660 } 11661 } else 11662 #endif 11663 if (argc != 3) 11664 return RESULT_SHOWUSAGE; 11665 11666 ast_mutex_lock(lock); 11667 #ifdef HAVE_PRI 11668 ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret"); 11669 #else 11670 ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret"); 11671 #endif 11672 11673 tmp = start; 11674 while (tmp) { 11675 if (tmp->channel > 0) { 11676 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 11677 } else 11678 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 11679 ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret); 11680 tmp = tmp->next; 11681 } 11682 ast_mutex_unlock(lock); 11683 return RESULT_SUCCESS; 11684 #undef FORMAT 11685 #undef FORMAT2 11686 }
static int zap_show_status | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11849 of file chan_zap.c.
References alarms, ast_cli(), ast_log(), errno, FORMAT, FORMAT2, LOG_WARNING, RESULT_FAILURE, and RESULT_SUCCESS.
11849 { 11850 #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" 11851 #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" 11852 11853 int span; 11854 int res; 11855 char alarms[50]; 11856 11857 int ctl; 11858 ZT_SPANINFO s; 11859 11860 ctl = open("/dev/zap/ctl", O_RDWR); 11861 if (ctl < 0) { 11862 ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno)); 11863 ast_cli(fd, "No Zaptel interface found.\n"); 11864 return RESULT_FAILURE; 11865 } 11866 ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4"); 11867 11868 for (span = 1; span < ZT_MAX_SPANS; ++span) { 11869 s.spanno = span; 11870 res = ioctl(ctl, ZT_SPANSTAT, &s); 11871 if (res) { 11872 continue; 11873 } 11874 alarms[0] = '\0'; 11875 if (s.alarms > 0) { 11876 if (s.alarms & ZT_ALARM_BLUE) 11877 strcat(alarms, "BLU/"); 11878 if (s.alarms & ZT_ALARM_YELLOW) 11879 strcat(alarms, "YEL/"); 11880 if (s.alarms & ZT_ALARM_RED) 11881 strcat(alarms, "RED/"); 11882 if (s.alarms & ZT_ALARM_LOOPBACK) 11883 strcat(alarms, "LB/"); 11884 if (s.alarms & ZT_ALARM_RECOVER) 11885 strcat(alarms, "REC/"); 11886 if (s.alarms & ZT_ALARM_NOTOPEN) 11887 strcat(alarms, "NOP/"); 11888 if (!strlen(alarms)) 11889 strcat(alarms, "UUU/"); 11890 if (strlen(alarms)) { 11891 /* Strip trailing / */ 11892 alarms[strlen(alarms) - 1] = '\0'; 11893 } 11894 } else { 11895 if (s.numchans) 11896 strcpy(alarms, "OK"); 11897 else 11898 strcpy(alarms, "UNCONFIGURED"); 11899 } 11900 11901 ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count); 11902 } 11903 close(ctl); 11904 11905 return RESULT_SUCCESS; 11906 #undef FORMAT 11907 #undef FORMAT2 11908 }
static char* zap_sig2str | ( | int | sig | ) | [static] |
Definition at line 1344 of file chan_zap.c.
References SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_GSM, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, and SIG_SFWINK.
01345 { 01346 static char buf[256]; 01347 switch (sig) { 01348 case SIG_EM: 01349 return "E & M Immediate"; 01350 case SIG_EMWINK: 01351 return "E & M Wink"; 01352 case SIG_EM_E1: 01353 return "E & M E1"; 01354 case SIG_FEATD: 01355 return "Feature Group D (DTMF)"; 01356 case SIG_FEATDMF: 01357 return "Feature Group D (MF)"; 01358 case SIG_FEATDMF_TA: 01359 return "Feature Groud D (MF) Tandem Access"; 01360 case SIG_FEATB: 01361 return "Feature Group B (MF)"; 01362 case SIG_E911: 01363 return "E911 (MF)"; 01364 case SIG_FGC_CAMA: 01365 return "FGC/CAMA (Dialpulse)"; 01366 case SIG_FGC_CAMAMF: 01367 return "FGC/CAMA (MF)"; 01368 case SIG_FXSLS: 01369 return "FXS Loopstart"; 01370 case SIG_FXSGS: 01371 return "FXS Groundstart"; 01372 case SIG_FXSKS: 01373 return "FXS Kewlstart"; 01374 case SIG_FXOLS: 01375 return "FXO Loopstart"; 01376 case SIG_FXOGS: 01377 return "FXO Groundstart"; 01378 case SIG_FXOKS: 01379 return "FXO Kewlstart"; 01380 case SIG_PRI: 01381 return "ISDN PRI"; 01382 case SIG_SF: 01383 return "SF (Tone) Immediate"; 01384 case SIG_SFWINK: 01385 return "SF (Tone) Wink"; 01386 case SIG_SF_FEATD: 01387 return "SF (Tone) with Feature Group D (DTMF)"; 01388 case SIG_SF_FEATDMF: 01389 return "SF (Tone) with Feature Group D (MF)"; 01390 case SIG_SF_FEATB: 01391 return "SF (Tone) with Feature Group B (MF)"; 01392 case SIG_GR303FXOKS: 01393 return "GR-303 with FXOKS"; 01394 case SIG_GR303FXSKS: 01395 return "GR-303 with FXSKS"; 01396 case SIG_GSM: 01397 return "GSM"; 01398 case 0: 01399 return "Pseudo"; 01400 default: 01401 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig); 01402 return buf; 01403 } 01404 }
static int zt_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2997 of file chan_zap.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::channel, zt_pvt::dialing, zt_pvt::digital, enable_dtmf_detect(), zt_pvt::hanguponpolarityswitch, zt_subchannel::inthreeway, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::oprmode, zt_subchannel::owner, zt_pvt::owner, zt_pvt::polaritydelaytv, zt_pvt::radio, zt_pvt::ringt, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GSM, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::span, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_subchannel::zfd, zt_enable_ec(), zt_get_index(), zt_set_hook(), and zt_train_ec().
02998 { 02999 struct zt_pvt *p = ast->tech_pvt; 03000 int res = 0; 03001 int index; 03002 int oldstate = ast->_state; 03003 ast_setstate(ast, AST_STATE_UP); 03004 ast_mutex_lock(&p->lock); 03005 index = zt_get_index(ast, p, 0); 03006 if (index < 0) 03007 index = SUB_REAL; 03008 /* nothing to do if a radio channel */ 03009 if ((p->radio || (p->oprmode < 0))) { 03010 ast_mutex_unlock(&p->lock); 03011 return 0; 03012 } 03013 switch (p->sig) { 03014 case SIG_FXSLS: 03015 case SIG_FXSGS: 03016 case SIG_FXSKS: 03017 p->ringt = 0; 03018 /* Fall through */ 03019 case SIG_EM: 03020 case SIG_EM_E1: 03021 case SIG_EMWINK: 03022 case SIG_FEATD: 03023 case SIG_FEATDMF: 03024 case SIG_FEATDMF_TA: 03025 case SIG_E911: 03026 case SIG_FGC_CAMA: 03027 case SIG_FGC_CAMAMF: 03028 case SIG_FEATB: 03029 case SIG_SF: 03030 case SIG_SFWINK: 03031 case SIG_SF_FEATD: 03032 case SIG_SF_FEATDMF: 03033 case SIG_SF_FEATB: 03034 case SIG_FXOLS: 03035 case SIG_FXOGS: 03036 case SIG_FXOKS: 03037 /* Pick up the line */ 03038 ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name); 03039 if (p->hanguponpolarityswitch) { 03040 gettimeofday(&p->polaritydelaytv, NULL); 03041 } 03042 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 03043 tone_zone_play_tone(p->subs[index].zfd, -1); 03044 p->dialing = 0; 03045 if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) { 03046 if (oldstate == AST_STATE_RINGING) { 03047 ast_log(LOG_DEBUG, "Finally swapping real and threeway\n"); 03048 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1); 03049 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03050 p->owner = p->subs[SUB_REAL].owner; 03051 } 03052 } 03053 if (p->sig & __ZT_SIG_FXS) { 03054 zt_enable_ec(p); 03055 zt_train_ec(p); 03056 } 03057 break; 03058 #ifdef HAVE_PRI 03059 case SIG_PRI: 03060 /* Send a pri acknowledge */ 03061 if (!pri_grab(p, p->pri)) { 03062 p->proceeding = 1; 03063 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 03064 pri_rel(p->pri); 03065 /* stop ignoring inband dtmf */ 03066 enable_dtmf_detect(p); 03067 } else { 03068 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 03069 res = -1; 03070 } 03071 /* the audio path is complete now, train the echo canceler */ 03072 zt_train_ec(p); 03073 break; 03074 #endif 03075 #ifdef HAVE_GSMAT 03076 case SIG_GSM: 03077 if (p->gsm.modul) { 03078 gsm_answer(p->gsm.modul); 03079 } 03080 break; 03081 #endif 03082 case 0: 03083 ast_mutex_unlock(&p->lock); 03084 return 0; 03085 default: 03086 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 03087 res = -1; 03088 } 03089 ast_mutex_unlock(&p->lock); 03090 return res; 03091 }
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 3417 of file chan_zap.c.
References ast_channel::_state, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_read(), AST_STATE_RINGING, ast_verbose(), ast_waitfor_n(), ast_write(), zt_pvt::channel, disable_dtmf_detect(), zt_pvt::echocanbridged, enable_dtmf_detect(), ast_channel::fds, ast_frame::frametype, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, master, option_verbose, zt_subchannel::owner, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::sig, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, ast_channel::tech_pvt, zt_pvt::transfer, update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_index(), zt_link(), and zt_unlink().
03418 { 03419 struct ast_channel *who; 03420 struct zt_pvt *p0, *p1, *op0, *op1; 03421 struct zt_pvt *master = NULL, *slave = NULL; 03422 struct ast_frame *f; 03423 int inconf = 0; 03424 int nothingok = 1; 03425 int ofd0, ofd1; 03426 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 03427 int os0 = -1, os1 = -1; 03428 int priority = 0; 03429 struct ast_channel *oc0, *oc1; 03430 enum ast_bridge_result res; 03431 03432 #ifdef PRI_2BCT 03433 int triedtopribridge = 0; 03434 q931_call *q931c0 = NULL, *q931c1 = NULL; 03435 #endif 03436 03437 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 03438 There is code below to handle it properly until DTMF is actually seen, 03439 but due to currently unresolved issues it's ignored... 03440 */ 03441 03442 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 03443 return AST_BRIDGE_FAILED_NOWARN; 03444 03445 ast_mutex_lock(&c0->lock); 03446 while (ast_mutex_trylock(&c1->lock)) { 03447 ast_mutex_unlock(&c0->lock); 03448 usleep(1); 03449 ast_mutex_lock(&c0->lock); 03450 } 03451 03452 p0 = c0->tech_pvt; 03453 p1 = c1->tech_pvt; 03454 /* cant do pseudo-channels here */ 03455 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 03456 ast_mutex_unlock(&c0->lock); 03457 ast_mutex_unlock(&c1->lock); 03458 return AST_BRIDGE_FAILED_NOWARN; 03459 } 03460 03461 oi0 = zt_get_index(c0, p0, 0); 03462 oi1 = zt_get_index(c1, p1, 0); 03463 if ((oi0 < 0) || (oi1 < 0)) { 03464 ast_mutex_unlock(&c0->lock); 03465 ast_mutex_unlock(&c1->lock); 03466 return AST_BRIDGE_FAILED; 03467 } 03468 03469 op0 = p0 = c0->tech_pvt; 03470 op1 = p1 = c1->tech_pvt; 03471 ofd0 = c0->fds[0]; 03472 ofd1 = c1->fds[0]; 03473 oc0 = p0->owner; 03474 oc1 = p1->owner; 03475 03476 if (ast_mutex_trylock(&p0->lock)) { 03477 /* Don't block, due to potential for deadlock */ 03478 ast_mutex_unlock(&c0->lock); 03479 ast_mutex_unlock(&c1->lock); 03480 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03481 return AST_BRIDGE_RETRY; 03482 } 03483 if (ast_mutex_trylock(&p1->lock)) { 03484 /* Don't block, due to potential for deadlock */ 03485 ast_mutex_unlock(&p0->lock); 03486 ast_mutex_unlock(&c0->lock); 03487 ast_mutex_unlock(&c1->lock); 03488 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03489 return AST_BRIDGE_RETRY; 03490 } 03491 03492 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03493 if (p0->owner && p1->owner) { 03494 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 03495 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 03496 master = p0; 03497 slave = p1; 03498 inconf = 1; 03499 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 03500 master = p1; 03501 slave = p0; 03502 inconf = 1; 03503 } else { 03504 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 03505 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 03506 p0->channel, 03507 oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03508 p0->subs[SUB_REAL].inthreeway, p0->channel, 03509 oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03510 p1->subs[SUB_REAL].inthreeway); 03511 } 03512 nothingok = 0; 03513 } 03514 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 03515 if (p1->subs[SUB_THREEWAY].inthreeway) { 03516 master = p1; 03517 slave = p0; 03518 nothingok = 0; 03519 } 03520 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 03521 if (p0->subs[SUB_THREEWAY].inthreeway) { 03522 master = p0; 03523 slave = p1; 03524 nothingok = 0; 03525 } 03526 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 03527 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 03528 don't put us in anything */ 03529 if (p1->subs[SUB_CALLWAIT].inthreeway) { 03530 master = p1; 03531 slave = p0; 03532 nothingok = 0; 03533 } 03534 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 03535 /* Same as previous */ 03536 if (p0->subs[SUB_CALLWAIT].inthreeway) { 03537 master = p0; 03538 slave = p1; 03539 nothingok = 0; 03540 } 03541 } 03542 ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n", 03543 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 03544 if (master && slave) { 03545 /* Stop any tones, or play ringtone as appropriate. If they're bridged 03546 in an active threeway call with a channel that is ringing, we should 03547 indicate ringing. */ 03548 if ((oi1 == SUB_THREEWAY) && 03549 p1->subs[SUB_THREEWAY].inthreeway && 03550 p1->subs[SUB_REAL].owner && 03551 p1->subs[SUB_REAL].inthreeway && 03552 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03553 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name); 03554 tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE); 03555 os1 = p1->subs[SUB_REAL].owner->_state; 03556 } else { 03557 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1); 03558 tone_zone_play_tone(p0->subs[oi0].zfd, -1); 03559 } 03560 if ((oi0 == SUB_THREEWAY) && 03561 p0->subs[SUB_THREEWAY].inthreeway && 03562 p0->subs[SUB_REAL].owner && 03563 p0->subs[SUB_REAL].inthreeway && 03564 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03565 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name); 03566 tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE); 03567 os0 = p0->subs[SUB_REAL].owner->_state; 03568 } else { 03569 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0); 03570 tone_zone_play_tone(p1->subs[oi0].zfd, -1); 03571 } 03572 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03573 if (!p0->echocanbridged || !p1->echocanbridged) { 03574 /* Disable echo cancellation if appropriate */ 03575 zt_disable_ec(p0); 03576 zt_disable_ec(p1); 03577 } 03578 } 03579 zt_link(slave, master); 03580 master->inconference = inconf; 03581 } else if (!nothingok) 03582 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 03583 03584 update_conf(p0); 03585 update_conf(p1); 03586 t0 = p0->subs[SUB_REAL].inthreeway; 03587 t1 = p1->subs[SUB_REAL].inthreeway; 03588 03589 ast_mutex_unlock(&p0->lock); 03590 ast_mutex_unlock(&p1->lock); 03591 03592 ast_mutex_unlock(&c0->lock); 03593 ast_mutex_unlock(&c1->lock); 03594 03595 /* Native bridge failed */ 03596 if ((!master || !slave) && !nothingok) { 03597 zt_enable_ec(p0); 03598 zt_enable_ec(p1); 03599 return AST_BRIDGE_FAILED; 03600 } 03601 03602 if (option_verbose > 2) 03603 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 03604 03605 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03606 disable_dtmf_detect(op0); 03607 03608 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03609 disable_dtmf_detect(op1); 03610 03611 for (;;) { 03612 struct ast_channel *c0_priority[2] = {c0, c1}; 03613 struct ast_channel *c1_priority[2] = {c1, c0}; 03614 03615 /* Here's our main loop... Start by locking things, looking for private parts, 03616 and then balking if anything is wrong */ 03617 ast_mutex_lock(&c0->lock); 03618 while (ast_mutex_trylock(&c1->lock)) { 03619 ast_mutex_unlock(&c0->lock); 03620 usleep(1); 03621 ast_mutex_lock(&c0->lock); 03622 } 03623 03624 p0 = c0->tech_pvt; 03625 p1 = c1->tech_pvt; 03626 03627 if (op0 == p0) 03628 i0 = zt_get_index(c0, p0, 1); 03629 if (op1 == p1) 03630 i1 = zt_get_index(c1, p1, 1); 03631 ast_mutex_unlock(&c0->lock); 03632 ast_mutex_unlock(&c1->lock); 03633 03634 if (!timeoutms || 03635 (op0 != p0) || 03636 (op1 != p1) || 03637 (ofd0 != c0->fds[0]) || 03638 (ofd1 != c1->fds[0]) || 03639 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 03640 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 03641 (oc0 != p0->owner) || 03642 (oc1 != p1->owner) || 03643 (t0 != p0->subs[SUB_REAL].inthreeway) || 03644 (t1 != p1->subs[SUB_REAL].inthreeway) || 03645 (oi0 != i0) || 03646 (oi1 != i1)) { 03647 ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 03648 op0->channel, oi0, op1->channel, oi1); 03649 res = AST_BRIDGE_RETRY; 03650 goto return_from_bridge; 03651 } 03652 03653 #ifdef PRI_2BCT 03654 q931c0 = p0->call; 03655 q931c1 = p1->call; 03656 if (p0->transfer && p1->transfer 03657 && q931c0 && q931c1 03658 && !triedtopribridge) { 03659 pri_channel_bridge(q931c0, q931c1); 03660 triedtopribridge = 1; 03661 } 03662 #endif 03663 03664 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms); 03665 if (!who) { 03666 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 03667 continue; 03668 } 03669 f = ast_read(who); 03670 if (!f || (f->frametype == AST_FRAME_CONTROL)) { 03671 *fo = f; 03672 *rc = who; 03673 res = AST_BRIDGE_COMPLETE; 03674 goto return_from_bridge; 03675 } 03676 if (f->frametype == AST_FRAME_DTMF) { 03677 if ((who == c0) && p0->pulsedial) { 03678 ast_write(c1, f); 03679 } else if ((who == c1) && p1->pulsedial) { 03680 ast_write(c0, f); 03681 } else { 03682 *fo = f; 03683 *rc = who; 03684 res = AST_BRIDGE_COMPLETE; 03685 goto return_from_bridge; 03686 } 03687 } 03688 ast_frfree(f); 03689 03690 /* Swap who gets priority */ 03691 priority = !priority; 03692 } 03693 03694 return_from_bridge: 03695 if (op0 == p0) 03696 zt_enable_ec(p0); 03697 03698 if (op1 == p1) 03699 zt_enable_ec(p1); 03700 03701 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03702 enable_dtmf_detect(op0); 03703 03704 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03705 enable_dtmf_detect(op1); 03706 03707 zt_unlink(slave, master, 1); 03708 03709 return res; 03710 }
static int zt_call | ( | struct ast_channel * | ast, | |
char * | rdest, | |||
int | timeout | |||
) | [static] |
Definition at line 1960 of file chan_zap.c.
References ast_channel::_state, ast_callerid_generate(), AST_LAW, ast_log(), ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), zt_pvt::callwait_name, zt_pvt::callwait_num, zt_pvt::callwaitcas, zt_pvt::callwaitrings, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::dialdest, zt_pvt::dialednone, zt_pvt::dialing, zt_pvt::digital, disable_dtmf_detect(), zt_pvt::distinctivering, zt_pvt::dnid, zt_pvt::dop, zt_pvt::echobreak, zt_pvt::echorest, zt_pvt::echotraining, errno, zt_pvt::finaldial, free, zt_pvt::hidecallerid, zt_pvt::hidecalleridname, IS_DIGITAL, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_pvt::law, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::lowlayercompat, MAX_CALLERID_SIZE, zt_subchannel::needbusy, zt_subchannel::needringing, zt_pvt::oprmode, option_verbose, zt_pvt::outgoing, zt_pvt::outsigmod, zt_pvt::owner, pbx_builtin_getvar_helper(), PRI_TRANS_CAP_DIGITAL, zt_pvt::priexclusive, zt_pvt::pulse, zt_pvt::radio, zt_pvt::rxgain, s, send_callerid(), zt_pvt::sendcalleridafter, set_actual_gain(), zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GSM, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::stripmsd, SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, ast_channel::transfercapability, zt_pvt::txgain, zt_pvt::use_callerid, zt_pvt::use_callingpres, VERBOSE_PREFIX_3, zt_pvt::whichwink, zt_subchannel::zfd, zt_callwait(), and zt_get_index().
01961 { 01962 struct zt_pvt *p = ast->tech_pvt; 01963 int x, res, index,mysig; 01964 char *c, *n, *l; 01965 #ifdef HAVE_PRI 01966 char *s = NULL; 01967 #endif 01968 char dest[256]; /* must be same length as p->dialdest */ 01969 ast_mutex_lock(&p->lock); 01970 ast_copy_string(dest, rdest, sizeof(dest)); 01971 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 01972 if ((ast->_state == AST_STATE_BUSY)) { 01973 p->subs[SUB_REAL].needbusy = 1; 01974 ast_mutex_unlock(&p->lock); 01975 return 0; 01976 } 01977 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 01978 ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name); 01979 ast_mutex_unlock(&p->lock); 01980 return -1; 01981 } 01982 p->dialednone = 0; 01983 if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */ 01984 { 01985 /* Special pseudo -- automatically up */ 01986 ast_setstate(ast, AST_STATE_UP); 01987 ast_mutex_unlock(&p->lock); 01988 return 0; 01989 } 01990 x = ZT_FLUSH_READ | ZT_FLUSH_WRITE; 01991 res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 01992 if (res) 01993 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel); 01994 p->outgoing = 1; 01995 01996 if (IS_DIGITAL(ast->transfercapability)) { 01997 set_actual_gain(p->subs[SUB_REAL].zfd, 0, 0, 0, p->law); 01998 } else { 01999 set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 02000 } 02001 02002 02003 mysig = p->sig; 02004 if (p->outsigmod > -1) 02005 mysig = p->outsigmod; 02006 02007 switch (mysig) { 02008 case SIG_FXOLS: 02009 case SIG_FXOGS: 02010 case SIG_FXOKS: 02011 if (p->owner == ast) { 02012 /* Normal ring, on hook */ 02013 02014 /* Don't send audio while on hook, until the call is answered */ 02015 p->dialing = 1; 02016 if (p->use_callerid) { 02017 /* Generate the Caller-ID spill if desired */ 02018 if (p->cidspill) { 02019 ast_log(LOG_WARNING, "cidspill already exists??\n"); 02020 free(p->cidspill); 02021 } 02022 p->callwaitcas = 0; 02023 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) { 02024 p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p)); 02025 p->cidpos = 0; 02026 send_callerid(p); 02027 } 02028 } 02029 /* Choose proper cadence */ 02030 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) { 02031 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1])) 02032 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name); 02033 p->cidrings = cidrings[p->distinctivering - 1]; 02034 } else { 02035 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL)) 02036 ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name); 02037 p->cidrings = p->sendcalleridafter; 02038 } 02039 02040 /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */ 02041 c = strchr(dest, '/'); 02042 if (c) 02043 c++; 02044 if (c && (strlen(c) < p->stripmsd)) { 02045 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 02046 c = NULL; 02047 } 02048 if (c) { 02049 p->dop.op = ZT_DIAL_OP_REPLACE; 02050 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c); 02051 ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c); 02052 } else { 02053 p->dop.dialstr[0] = '\0'; 02054 } 02055 x = ZT_RING; 02056 if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) { 02057 ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno)); 02058 ast_mutex_unlock(&p->lock); 02059 return -1; 02060 } 02061 p->dialing = 1; 02062 } else { 02063 /* Call waiting call */ 02064 p->callwaitrings = 0; 02065 if (ast->cid.cid_num) 02066 ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num)); 02067 else 02068 p->callwait_num[0] = '\0'; 02069 if (ast->cid.cid_name) 02070 ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name)); 02071 else 02072 p->callwait_name[0] = '\0'; 02073 /* Call waiting tone instead */ 02074 if (zt_callwait(ast)) { 02075 ast_mutex_unlock(&p->lock); 02076 return -1; 02077 } 02078 /* Make ring-back */ 02079 if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE)) 02080 ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name); 02081 02082 } 02083 n = ast->cid.cid_name; 02084 l = ast->cid.cid_num; 02085 if (l) 02086 ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num)); 02087 else 02088 p->lastcid_num[0] = '\0'; 02089 if (n) 02090 ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name)); 02091 else 02092 p->lastcid_name[0] = '\0'; 02093 ast_setstate(ast, AST_STATE_RINGING); 02094 index = zt_get_index(ast, p, 0); 02095 if (index > -1) { 02096 p->subs[index].needringing = 1; 02097 } 02098 break; 02099 case SIG_FXSLS: 02100 case SIG_FXSGS: 02101 case SIG_FXSKS: 02102 case SIG_EMWINK: 02103 case SIG_EM: 02104 case SIG_EM_E1: 02105 case SIG_FEATD: 02106 case SIG_FEATDMF: 02107 case SIG_E911: 02108 case SIG_FGC_CAMA: 02109 case SIG_FGC_CAMAMF: 02110 case SIG_FEATB: 02111 case SIG_SFWINK: 02112 case SIG_SF: 02113 case SIG_SF_FEATD: 02114 case SIG_SF_FEATDMF: 02115 case SIG_FEATDMF_TA: 02116 case SIG_SF_FEATB: 02117 c = strchr(dest, '/'); 02118 if (c) 02119 c++; 02120 else 02121 c = ""; 02122 if (strlen(c) < p->stripmsd) { 02123 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 02124 ast_mutex_unlock(&p->lock); 02125 return -1; 02126 } 02127 #ifdef HAVE_PRI 02128 /* Start the trunk, if not GR-303 */ 02129 if (!p->pri) { 02130 #endif 02131 x = ZT_START; 02132 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 02133 if (res < 0) { 02134 if (errno != EINPROGRESS) { 02135 ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno)); 02136 ast_mutex_unlock(&p->lock); 02137 return -1; 02138 } 02139 } 02140 #ifdef HAVE_PRI 02141 } 02142 #endif 02143 ast_log(LOG_DEBUG, "Dialing '%s'\n", c); 02144 p->dop.op = ZT_DIAL_OP_REPLACE; 02145 02146 c += p->stripmsd; 02147 02148 switch (mysig) { 02149 case SIG_FEATD: 02150 l = ast->cid.cid_num; 02151 if (l) 02152 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c); 02153 else 02154 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c); 02155 break; 02156 case SIG_FEATDMF: 02157 l = ast->cid.cid_num; 02158 if (l) 02159 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c); 02160 else 02161 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c); 02162 break; 02163 case SIG_FEATDMF_TA: 02164 { 02165 const char *cic, *ozz; 02166 02167 /* If you have to go through a Tandem Access point you need to use this */ 02168 ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ"); 02169 if (!ozz) 02170 ozz = defaultozz; 02171 cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC"); 02172 if (!cic) 02173 cic = defaultcic; 02174 if (!ozz || !cic) { 02175 ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n"); 02176 ast_mutex_unlock(&p->lock); 02177 return -1; 02178 } 02179 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic); 02180 snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c); 02181 p->whichwink = 0; 02182 } 02183 break; 02184 case SIG_E911: 02185 ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr)); 02186 break; 02187 case SIG_FGC_CAMA: 02188 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c); 02189 break; 02190 case SIG_FGC_CAMAMF: 02191 case SIG_FEATB: 02192 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c); 02193 break; 02194 default: 02195 if (p->pulse) 02196 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c); 02197 else 02198 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c); 02199 break; 02200 } 02201 02202 if (p->echotraining && (strlen(p->dop.dialstr) > 4)) { 02203 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 02204 strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 02205 p->echorest[sizeof(p->echorest) - 1] = '\0'; 02206 p->echobreak = 1; 02207 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 02208 } else 02209 p->echobreak = 0; 02210 if (!res) { 02211 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 02212 x = ZT_ONHOOK; 02213 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 02214 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 02215 ast_mutex_unlock(&p->lock); 02216 return -1; 02217 } 02218 } else 02219 ast_log(LOG_DEBUG, "Deferring dialing...\n"); 02220 p->dialing = 1; 02221 if (ast_strlen_zero(c)) 02222 p->dialednone = 1; 02223 ast_setstate(ast, AST_STATE_DIALING); 02224 break; 02225 case 0: 02226 /* Special pseudo -- automatically up*/ 02227 ast_setstate(ast, AST_STATE_UP); 02228 break; 02229 case SIG_PRI: 02230 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ 02231 p->dialdest[0] = '\0'; 02232 disable_dtmf_detect(p); 02233 break; 02234 case SIG_GSM: 02235 #ifdef HAVE_GSMAT 02236 if (p->gsm.modul) { 02237 c = strchr(dest, '/'); 02238 if (c) 02239 c++; 02240 else 02241 c = dest; 02242 ast_mutex_lock(&p->gsm.lock); 02243 if (gsm_dial(p->gsm.modul, p->use_callingpres ? ast->cid.cid_pres : 0, c)) { 02244 ast_log(LOG_WARNING, "dialing failed on channel %d\n", p->channel); 02245 ast_mutex_unlock(&p->gsm.lock); 02246 ast_mutex_unlock(&p->lock); 02247 return -1; 02248 } 02249 ast_mutex_unlock(&p->gsm.lock); 02250 } 02251 #endif 02252 break; 02253 default: 02254 ast_log(LOG_DEBUG, "not yet implemented\n"); 02255 ast_mutex_unlock(&p->lock); 02256 return -1; 02257 } 02258 #ifdef HAVE_PRI 02259 if (p->pri) { 02260 struct pri_sr *sr; 02261 #ifdef SUPPORT_USERUSER 02262 const char *useruser; 02263 #endif 02264 int pridialplan; 02265 int dp_strip; 02266 int prilocaldialplan; 02267 int ldp_strip; 02268 int exclusive; 02269 const char *rr_str; 02270 int redirect_reason; 02271 02272 if ((p->pri->nodetype == BRI_NETWORK_PTMP) || (p->pri->nodetype == BRI_NETWORK)) { 02273 // pass NO audio when ringing an isdn phone 02274 p->dialing = 1; 02275 // maybe we could allow passing audio when calling a p2p PBX, but well... ;-) 02276 } 02277 02278 c = strchr(dest, '/'); 02279 if (c) 02280 c++; 02281 else 02282 c = dest; 02283 02284 l = NULL; 02285 n = NULL; 02286 02287 if (!p->hidecallerid) { 02288 l = ast->cid.cid_num; 02289 if (!p->hidecalleridname) { 02290 n = ast->cid.cid_name; 02291 } 02292 } 02293 02294 02295 if (strlen(c) < p->stripmsd) { 02296 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 02297 ast_mutex_unlock(&p->lock); 02298 return -1; 02299 } 02300 strncpy(p->dnid, (c + p->stripmsd), sizeof(p->dnid)-1); 02301 if (mysig != SIG_FXSKS) { 02302 p->dop.op = ZT_DIAL_OP_REPLACE; 02303 s = strchr(c + p->stripmsd, 'w'); 02304 if (s) { 02305 if (strlen(s) > 1) 02306 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s); 02307 else 02308 p->dop.dialstr[0] = '\0'; 02309 *s = '\0'; 02310 } else { 02311 p->dop.dialstr[0] = '\0'; 02312 } 02313 } 02314 if (pri_grab(p, p->pri)) { 02315 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 02316 ast_mutex_unlock(&p->lock); 02317 return -1; 02318 } 02319 if (!(p->call = pri_new_call(p->pri->pri))) { 02320 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 02321 pri_rel(p->pri); 02322 ast_mutex_unlock(&p->lock); 02323 return -1; 02324 } else { 02325 // ast_log(LOG_NOTICE, "call %d\n", p->call); 02326 } 02327 if (!(sr = pri_sr_new())) { 02328 ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); 02329 pri_rel(p->pri); 02330 ast_mutex_unlock(&p->lock); 02331 } 02332 if (p->bearer || (mysig == SIG_FXSKS)) { 02333 if (p->bearer) { 02334 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); 02335 p->bearer->call = p->call; 02336 } else 02337 ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n"); 02338 pri_set_crv(p->pri->pri, p->call, p->channel, 0); 02339 } 02340 p->digital = IS_DIGITAL(ast->transfercapability); 02341 /* Add support for exclusive override */ 02342 if (p->priexclusive) 02343 exclusive = 1; 02344 else { 02345 /* otherwise, traditional behavior */ 02346 if (p->pri->nodetype == PRI_NETWORK) 02347 exclusive = 0; 02348 else 02349 exclusive = 1; 02350 } 02351 02352 pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1); 02353 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 02354 (p->digital ? -1 : 02355 ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)), ast->lowlayercompat); 02356 if (p->pri->facilityenable) 02357 pri_facility_enable(p->pri->pri); 02358 02359 if (option_verbose > 2) 02360 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 02361 dp_strip = 0; 02362 pridialplan = p->pri->dialplan - 1; 02363 if (pridialplan == -2) { /* compute dynamically */ 02364 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02365 dp_strip = strlen(p->pri->internationalprefix); 02366 pridialplan = PRI_INTERNATIONAL_ISDN; 02367 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02368 dp_strip = strlen(p->pri->nationalprefix); 02369 pridialplan = PRI_NATIONAL_ISDN; 02370 } else { 02371 pridialplan = PRI_LOCAL_ISDN; 02372 } 02373 } 02374 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 02375 02376 ldp_strip = 0; 02377 prilocaldialplan = p->pri->localdialplan - 1; 02378 if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */ 02379 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02380 ldp_strip = strlen(p->pri->internationalprefix); 02381 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 02382 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02383 ldp_strip = strlen(p->pri->nationalprefix); 02384 prilocaldialplan = PRI_NATIONAL_ISDN; 02385 } else { 02386 prilocaldialplan = PRI_LOCAL_ISDN; 02387 } 02388 } 02389 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 02390 p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 02391 if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) { 02392 if (!strcasecmp(rr_str, "UNKNOWN")) 02393 redirect_reason = 0; 02394 else if (!strcasecmp(rr_str, "BUSY")) 02395 redirect_reason = 1; 02396 else if (!strcasecmp(rr_str, "NO_REPLY")) 02397 redirect_reason = 2; 02398 else if (!strcasecmp(rr_str, "UNCONDITIONAL")) 02399 redirect_reason = 15; 02400 else 02401 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02402 } else 02403 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02404 pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason); 02405 02406 #ifdef SUPPORT_USERUSER 02407 /* User-user info */ 02408 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 02409 02410 if (useruser) 02411 pri_sr_set_useruser(sr, useruser); 02412 #endif 02413 02414 if (pri_setup(p->pri->pri, p->call, sr)) { 02415 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 02416 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 02417 pri_rel(p->pri); 02418 ast_mutex_unlock(&p->lock); 02419 pri_sr_free(sr); 02420 return -1; 02421 } 02422 pri_sr_free(sr); 02423 ast_setstate(ast, AST_STATE_DIALING); 02424 pri_rel(p->pri); 02425 } 02426 #endif 02427 ast_mutex_unlock(&p->lock); 02428 return 0; 02429 }
static int zt_callwait | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 1932 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().
01933 { 01934 struct zt_pvt *p = ast->tech_pvt; 01935 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 01936 if (p->cidspill) { 01937 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 01938 free(p->cidspill); 01939 } 01940 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 01941 return -1; 01942 save_conference(p); 01943 /* Silence */ 01944 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 01945 if (!p->callwaitrings && p->callwaitingcallerid) { 01946 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 01947 p->callwaitcas = 1; 01948 p->cidlen = 2400 + 680 + READ_SIZE * 4; 01949 } else { 01950 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 01951 p->callwaitcas = 0; 01952 p->cidlen = 2400 + READ_SIZE * 4; 01953 } 01954 p->cidpos = 0; 01955 send_callerid(p); 01956 01957 return 0; 01958 }
static struct zt_chan_conf zt_chan_conf_default | ( | void | ) | [static, read] |
returns a new zt_chan_conf with default values (by-value)
Definition at line 657 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().
00657 { 00658 /* recall that if a field is not included here it is initialized 00659 * to 0 or equivalent 00660 */ 00661 struct zt_chan_conf conf = { 00662 #ifdef HAVE_PRI 00663 .pri = { 00664 .nsf = PRI_NSF_NONE, 00665 .switchtype = PRI_SWITCH_NI2, 00666 .dialplan = PRI_NATIONAL_ISDN + 1, 00667 .localdialplan = PRI_NATIONAL_ISDN + 1, 00668 .nodetype = PRI_CPE, 00669 00670 .minunused = 2, 00671 .idleext = "", 00672 .idledial = "", 00673 .nocid = "No CID available", 00674 .withheldcid = "CID withheld", 00675 .internationalprefix = "", 00676 .nationalprefix = "", 00677 .localprefix = "", 00678 .privateprefix = "", 00679 .unknownprefix = "", 00680 .usercid = 0, 00681 00682 .resetinterval = 3600 00683 }, 00684 #endif 00685 .chan = { 00686 .context = "default", 00687 .cid_num = "", 00688 .cid_name = "", 00689 .mohinterpret = "default", 00690 .mohsuggest = "", 00691 .transfertobusy = 1, 00692 .priindication_oob = 0, 00693 .pritransfer = 0, 00694 00695 .cid_signalling = CID_SIG_BELL, 00696 .cid_start = CID_START_RING, 00697 .zaptrcallerid = 0, 00698 .use_callerid = 1, 00699 .sig = -1, 00700 .outsigmod = -1, 00701 00702 .tonezone = -1, 00703 00704 .echocancel = 1, 00705 00706 .busycount = 3, 00707 00708 .accountcode = "", 00709 00710 .mailbox = "", 00711 00712 00713 .polarityonanswerdelay = 600, 00714 00715 .sendcalleridafter = DEFAULT_CIDRINGS 00716 }, 00717 .timing = { 00718 .prewinktime = -1, 00719 .preflashtime = -1, 00720 .winktime = -1, 00721 .flashtime = -1, 00722 .starttime = -1, 00723 .rxwinktime = -1, 00724 .rxflashtime = -1, 00725 .debouncetime = -1 00726 }, 00727 .smdi_port = "/dev/ttyS0", 00728 }; 00729 00730 return conf; 00731 }
static void zt_close | ( | int | fd | ) | [static] |
Definition at line 1097 of file chan_zap.c.
Referenced by __unload_module(), alloc_sub(), destroy_channel(), mkintf(), and unalloc_sub().
static int zt_confmute | ( | struct zt_pvt * | p, | |
int | muted | |||
) | [inline, static] |
Definition at line 1815 of file chan_zap.c.
References ast_log(), zt_pvt::channel, errno, LOG_WARNING, zt_pvt::sig, SIG_GSM, SIG_PRI, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_handle_dtmfup(), zt_handle_event(), zt_hangup(), and zt_new().
01816 { 01817 int x, y, res; 01818 x = muted; 01819 if ((p->sig == SIG_PRI) || (p->sig == SIG_GSM)) { 01820 y = 1; 01821 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y); 01822 if (res) 01823 ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel); 01824 } 01825 res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x); 01826 if (res < 0) 01827 ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno)); 01828 return res; 01829 }
static int zt_devicestate | ( | void * | data | ) | [static] |
Definition at line 836 of file chan_zap.c.
References ast_channel::_state, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_RINGING, AST_DEVICE_UNKNOWN, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DIALING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), CHAN_PSEUDO, zt_pvt::channel, zt_pvt::cid_num, DCHAN_UP, zt_pvt::dnid, zt_pvt::group, iflist, zt_pvt::lock, lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, zt_pvt::next, NUM_DCHANS, zt_pvt::outgoing, zt_pvt::owner, s, and strsep().
00837 { 00838 int groupmatch = 0; 00839 int channelmatch = 0; 00840 struct zt_pvt *p; 00841 char *dest=NULL; 00842 int x; 00843 char *s; 00844 char opt=0; 00845 int res, y=0; 00846 struct zt_pvt *exit, *start, *end; 00847 ast_mutex_t *lock; 00848 00849 // ast_log(LOG_NOTICE, "data = %s\n", (char *)data); 00850 return AST_DEVICE_UNKNOWN; 00851 00852 /* Assume we're locking the iflock */ 00853 lock = &iflock; 00854 start = iflist; 00855 end = ifend; 00856 00857 if (data) { 00858 dest = ast_strdupa((char *)data); 00859 } else { 00860 ast_log(LOG_WARNING, "Channel requested with no data\n"); 00861 return AST_DEVICE_INVALID; 00862 } 00863 if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') { 00864 /* Retrieve the group number */ 00865 char *stringp=NULL; 00866 stringp=dest + 1; 00867 s = strsep(&stringp, "/"); 00868 if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 00869 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data); 00870 return AST_DEVICE_INVALID; 00871 } 00872 groupmatch = 1 << x; 00873 } else { 00874 char *stringp=NULL; 00875 stringp=dest; 00876 s = strsep(&stringp, "/"); 00877 p = iflist; 00878 if (!strcasecmp(s, "pseudo")) { 00879 /* Special case for pseudo */ 00880 x = CHAN_PSEUDO; 00881 channelmatch = x; 00882 /* bail out */ 00883 return AST_DEVICE_INVALID; 00884 } 00885 00886 else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 00887 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data); 00888 return AST_DEVICE_INVALID; 00889 } else { 00890 channelmatch = x; 00891 ast_log(LOG_NOTICE, "channelmatch = %d\n", channelmatch); 00892 } 00893 } 00894 /* Search for an unowned channel */ 00895 if (ast_mutex_lock(lock)) { 00896 ast_log(LOG_ERROR, "Unable to lock interface list???\n"); 00897 return AST_DEVICE_INVALID; 00898 } 00899 p = iflist; 00900 exit = iflist; 00901 res = AST_DEVICE_INVALID; /* start pessimistic */ 00902 while(p) { 00903 if (p) { 00904 ast_mutex_lock(&p->lock); 00905 if ((groupmatch && ((p->group & groupmatch) != 0)) || (channelmatch && (p->channel == channelmatch))) { 00906 #ifdef ZAPATA_PRI 00907 if (p->pri) { 00908 for(d=0;d<NUM_DCHANS;d++) { 00909 if (p->pri->dchanavail[d] & DCHAN_UP) { 00910 res = AST_DEVICE_UNKNOWN; 00911 } 00912 } 00913 } 00914 #endif 00915 if ((!ast_strlen_zero(p->cid_num) && (strncasecmp(p->cid_num, dest, strlen(p->cid_num)))) || (!ast_strlen_zero(p->dnid) && (strncasecmp(p->dnid, dest, strlen(p->dnid))))) { 00916 res = AST_DEVICE_UNKNOWN; 00917 if (p->owner) { 00918 if ((p->owner->_state == AST_STATE_RINGING) && (p->outgoing)) { 00919 res = AST_DEVICE_RINGING; 00920 } 00921 if (((p->owner->_state == AST_STATE_RINGING) && (!p->outgoing)) || (p->owner->_state == AST_STATE_UP) || (p->owner->_state == AST_STATE_DIALING) || (p->owner->_state == AST_STATE_RESERVED) || (p->owner->_state == AST_STATE_RING)){ 00922 res = AST_DEVICE_INUSE; 00923 } 00924 } 00925 if ((res == AST_DEVICE_INUSE) || (res == AST_DEVICE_RINGING)) { 00926 /* stop searching now, one non-idle channel is sufficient */ 00927 ast_mutex_unlock(&p->lock); 00928 break; 00929 } 00930 } 00931 } 00932 ast_mutex_unlock(&p->lock); 00933 } 00934 p = p->next; 00935 } 00936 ast_mutex_unlock(lock); 00937 00938 return res; 00939 00940 }
static int zt_digit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 1184 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().
01185 { 01186 struct zt_pvt *pvt; 01187 int index; 01188 int dtmf = -1; 01189 01190 pvt = chan->tech_pvt; 01191 01192 ast_mutex_lock(&pvt->lock); 01193 01194 index = zt_get_index(chan, pvt, 0); 01195 01196 if ((index != SUB_REAL) || !pvt->owner) 01197 goto out; 01198 01199 #ifdef HAVE_PRI 01200 if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) { 01201 if (pvt->setup_ack) { 01202 if (!pri_grab(pvt, pvt->pri)) { 01203 pri_information(pvt->pri->pri, pvt->call, digit); 01204 pri_rel(pvt->pri); 01205 } else 01206 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span); 01207 } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) { 01208 int res; 01209 ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit); 01210 res = strlen(pvt->dialdest); 01211 pvt->dialdest[res++] = digit; 01212 pvt->dialdest[res] = '\0'; 01213 } 01214 goto out; 01215 } 01216 #endif 01217 if ((dtmf = digit_to_dtmfindex(digit)) == -1) 01218 goto out; 01219 01220 if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) { 01221 int res; 01222 ZT_DIAL_OPERATION zo = { 01223 .op = ZT_DIAL_OP_APPEND, 01224 .dialstr[0] = 'T', 01225 .dialstr[1] = digit, 01226 .dialstr[2] = 0, 01227 }; 01228 if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo))) 01229 ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit); 01230 else 01231 pvt->dialing = 1; 01232 } else { 01233 ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit); 01234 pvt->dialing = 1; 01235 pvt->begindigit = digit; 01236 } 01237 01238 out: 01239 ast_mutex_unlock(&pvt->lock); 01240 01241 return 0; 01242 }
static int zt_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 1244 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().
01245 { 01246 struct zt_pvt *pvt; 01247 int res = 0; 01248 int index; 01249 int x; 01250 01251 pvt = chan->tech_pvt; 01252 01253 ast_mutex_lock(&pvt->lock); 01254 01255 index = zt_get_index(chan, pvt, 0); 01256 01257 if ((index != SUB_REAL) || !pvt->owner || pvt->pulse) 01258 goto out; 01259 01260 #ifdef HAVE_PRI 01261 /* This means that the digit was already sent via PRI signalling */ 01262 if (pvt->sig == SIG_PRI && !pvt->begindigit) 01263 goto out; 01264 #endif 01265 01266 if (pvt->begindigit) { 01267 x = -1; 01268 ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit); 01269 res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x); 01270 pvt->dialing = 0; 01271 pvt->begindigit = 0; 01272 } 01273 01274 out: 01275 ast_mutex_unlock(&pvt->lock); 01276 01277 return res; 01278 }
static void zt_disable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1647 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echocanon, LOG_DEBUG, LOG_WARNING, option_debug, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), app_zapEC(), handle_init_event(), zt_bridge(), zt_handle_event(), zt_hangup(), and zt_setoption().
01648 { 01649 int x; 01650 int res; 01651 if (p->echocancel) { 01652 x = 0; 01653 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01654 if (res) 01655 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel); 01656 else if (option_debug) 01657 ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel); 01658 } 01659 p->echocanon = 0; 01660 }
static void zt_enable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1593 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::digital, zt_pvt::echocancel, zt_pvt::echocanon, zt_pvt::faxhandled, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::sig, SIG_PRI, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by app_zapEC(), handle_init_event(), ss_thread(), zt_answer(), zt_bridge(), zt_handle_event(), and zt_setoption().
01594 { 01595 int x; 01596 int res; 01597 if (!p) 01598 return; 01599 if (p->faxhandled) { 01600 ast_log(LOG_DEBUG, "Not enabling echo cancellation on a fax/modem call\n"); 01601 return; 01602 } 01603 if (p->echocanon) { 01604 ast_log(LOG_DEBUG, "Echo cancellation already on\n"); 01605 return; 01606 } 01607 if (p->digital) { 01608 ast_log(LOG_DEBUG, "Echo cancellation does not make any sense on digital connections!\n"); 01609 return; 01610 } 01611 if (p->echocancel) { 01612 if (p->sig == SIG_PRI) { 01613 x = 1; 01614 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x); 01615 if (res) 01616 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel); 01617 } 01618 x = p->echocancel; 01619 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01620 if (res) 01621 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel); 01622 else { 01623 p->echocanon = 1; 01624 if (option_debug) 01625 ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel); 01626 } 01627 } else if (option_debug) 01628 ast_log(LOG_DEBUG, "No echo cancellation requested\n"); 01629 }
static struct ast_frame * zt_exception | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 4886 of file chan_zap.c.
References __zt_exception(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::lock, and ast_channel::tech_pvt.
04887 { 04888 struct zt_pvt *p = ast->tech_pvt; 04889 struct ast_frame *f; 04890 ast_mutex_lock(&p->lock); 04891 f = __zt_exception(ast); 04892 ast_mutex_unlock(&p->lock); 04893 return f; 04894 }
static int zt_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 3712 of file chan_zap.c.
References ast_channel::_state, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RINGING, zt_pvt::channel, zt_pvt::lock, LOG_DEBUG, LOG_ERROR, zt_subchannel::owner, zt_pvt::owner, zt_pvt::subs, ast_channel::tech_pvt, update_conf(), zt_indicate(), and zt_unlink().
03713 { 03714 struct zt_pvt *p = newchan->tech_pvt; 03715 int x; 03716 if (newchan && newchan->tech_pvt) { 03717 p = newchan->tech_pvt; 03718 } 03719 if (!p) { 03720 if (newchan) { 03721 ast_log(LOG_ERROR, "channel %s has no tech_pvt structure\n", newchan->name); 03722 } 03723 return 0; 03724 } 03725 ast_mutex_lock(&p->lock); 03726 ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name); 03727 if (p->owner == oldchan) { 03728 p->owner = newchan; 03729 } 03730 for (x = 0; x < 3; x++) 03731 if (p->subs[x].owner == oldchan) { 03732 if (!x) 03733 zt_unlink(NULL, p, 0); 03734 p->subs[x].owner = newchan; 03735 } 03736 if (newchan->_state == AST_STATE_RINGING) 03737 zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0); 03738 update_conf(p); 03739 ast_mutex_unlock(&p->lock); 03740 return 0; 03741 }
static int zt_func_read | ( | struct ast_channel * | chan, | |
char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 3278 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.
03279 { 03280 struct zt_pvt *p = chan->tech_pvt; 03281 03282 if (!strcasecmp(data, "rxgain")) { 03283 ast_mutex_lock(&p->lock); 03284 snprintf(buf, len, "%f", p->rxgain); 03285 ast_mutex_unlock(&p->lock); 03286 } else if (!strcasecmp(data, "txgain")) { 03287 ast_mutex_lock(&p->lock); 03288 snprintf(buf, len, "%f", p->txgain); 03289 ast_mutex_unlock(&p->lock); 03290 } else { 03291 ast_copy_string(buf, "", len); 03292 } 03293 return 0; 03294 }
static int zt_get_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_getevent which ignores a bunch of events.
Definition at line 264 of file chan_zap.c.
Referenced by __zt_exception(), do_monitor(), ss_thread(), and zt_handle_event().
00265 { 00266 int j; 00267 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00268 return -1; 00269 return j; 00270 }
static int zt_get_index | ( | struct ast_channel * | ast, | |
struct zt_pvt * | p, | |||
int | nullok | |||
) | [static] |
Definition at line 942 of file chan_zap.c.
References ast_log(), LOG_WARNING, zt_subchannel::owner, and zt_pvt::subs.
Referenced by __zt_exception(), ss_thread(), zt_answer(), zt_bridge(), zt_call(), zt_digit_begin(), zt_digit_end(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_read(), zt_setoption(), zt_tdd_sendtext(), and zt_write().
00943 { 00944 int res; 00945 if (p->subs[0].owner == ast) 00946 res = 0; 00947 else if (p->subs[1].owner == ast) 00948 res = 1; 00949 else if (p->subs[2].owner == ast) 00950 res = 2; 00951 else { 00952 res = -1; 00953 if (!nullok) 00954 ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n"); 00955 } 00956 return res; 00957 }
static void zt_handle_dtmfup | ( | struct ast_channel * | ast, | |
int | index, | |||
struct ast_frame ** | dest | |||
) | [static] |
Definition at line 3889 of file chan_zap.c.
References ast_async_goto(), AST_CONTROL_ANSWER, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_NULL, ast_log(), ast_verbose(), zt_pvt::callprogress, zt_pvt::callwaitcas, ast_channel::cid, ast_callerid::cid_num, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_channel::context, ast_channel::exten, zt_subchannel::f, zt_pvt::faxhandled, ast_frame::frametype, free, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, option_debug, option_verbose, pbx_builtin_setvar_helper(), S_OR, send_cwcidspill(), ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, VERBOSE_PREFIX_3, and zt_confmute().
Referenced by zt_handle_event(), and zt_read().
03890 { 03891 struct zt_pvt *p = ast->tech_pvt; 03892 struct ast_frame *f = *dest; 03893 03894 if (option_debug) 03895 ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name); 03896 03897 if (p->confirmanswer) { 03898 if (option_debug) 03899 ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name); 03900 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 03901 of a DTMF digit */ 03902 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03903 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03904 *dest = &p->subs[index].f; 03905 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 03906 p->confirmanswer = 0; 03907 } else if (p->callwaitcas) { 03908 if ((f->subclass == 'A') || (f->subclass == 'D')) { 03909 if (option_debug) 03910 ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n"); 03911 if (p->cidspill) 03912 free(p->cidspill); 03913 send_cwcidspill(p); 03914 } 03915 if ((f->subclass != 'm') && (f->subclass != 'u')) 03916 p->callwaitcas = 0; 03917 p->subs[index].f.frametype = AST_FRAME_NULL; 03918 p->subs[index].f.subclass = 0; 03919 *dest = &p->subs[index].f; 03920 } else if (f->subclass == 'f') { 03921 /* Fax tone -- Handle and return NULL */ 03922 if ((p->callprogress & 0x6) && !p->faxhandled) { 03923 p->faxhandled++; 03924 if (strcmp(ast->exten, "fax")) { 03925 const char *target_context = S_OR(ast->macrocontext, ast->context); 03926 03927 if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) { 03928 if (option_verbose > 2) 03929 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name); 03930 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 03931 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 03932 if (ast_async_goto(ast, target_context, "fax", 1)) 03933 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 03934 } else { 03935 if (option_verbose > 2) 03936 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 03937 } 03938 } else if (option_debug) 03939 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 03940 } else if (option_debug) 03941 ast_log(LOG_DEBUG, "Fax already handled\n"); 03942 zt_confmute(p, 0); 03943 p->subs[index].f.frametype = AST_FRAME_NULL; 03944 p->subs[index].f.subclass = 0; 03945 *dest = &p->subs[index].f; 03946 } else if (f->subclass == 'm') { 03947 /* Confmute request */ 03948 zt_confmute(p, 1); 03949 p->subs[index].f.frametype = AST_FRAME_NULL; 03950 p->subs[index].f.subclass = 0; 03951 *dest = &p->subs[index].f; 03952 } else if (f->subclass == 'u') { 03953 /* Unmute */ 03954 zt_confmute(p, 0); 03955 p->subs[index].f.frametype = AST_FRAME_NULL; 03956 p->subs[index].f.subclass = 0; 03957 *dest = &p->subs[index].f; 03958 } else 03959 zt_confmute(p, 0); 03960 }
static struct ast_frame* zt_handle_event | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 3962 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, alarm2str(), alloc_sub(), zt_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_pthread_create, ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdup, ast_strlen_zero(), ast_verbose(), attempt_transfer(), zt_pvt::callprogress, zt_pvt::callwaitcas, zt_pvt::callwaitingrepeat, CANPROGRESSDETECT, zt_pvt::channel, check_for_conference(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, zt_pvt::cid_name, ast_callerid::cid_name, cid_name, zt_pvt::cid_num, ast_callerid::cid_num, cid_num, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_frame::data, ast_frame::datalen, zt_pvt::dialdest, zt_pvt::dialednone, zt_pvt::dialing, zt_pvt::dop, zt_pvt::dsp, zt_pvt::echobreak, zt_pvt::echocanon, zt_pvt::echorest, zt_pvt::echotraining, errno, event2str(), EVENT_FLAG_SYSTEM, zt_subchannel::f, zt_pvt::fake_event, zt_pvt::finaldial, zt_pvt::flashtime, ast_frame::frametype, free, get_alarms(), zt_pvt::hanguponpolarityswitch, has_voicemail(), zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_event(), MIN_MS_SINCE_FLASH, zt_pvt::mohsuggest, zt_pvt::msgstate, zt_subchannel::needanswer, zt_subchannel::needflash, zt_subchannel::needhold, zt_subchannel::needringing, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::onhooktime, zt_pvt::oprmode, zt_pvt::oprpeer, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::outsigmod, zt_pvt::overlapdial, zt_subchannel::owner, zt_pvt::owner, ast_channel::pbx, zt_pvt::polarity, POLARITY_IDLE, POLARITY_REV, zt_pvt::polaritydelaytv, zt_pvt::polarityonanswerdelay, zt_pvt::pulsedial, zt_pvt::radio, restore_conference(), ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, S_OR, ast_frame::samples, save_conference(), zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ast_frame::src, ss_thread(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::threewaycalling, zt_pvt::transfer, zt_pvt::transfertobusy, unalloc_sub(), update_conf(), VERBOSE_PREFIX_3, zt_pvt::whichwink, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_enable_ec(), ZT_EVENT_DTMFDOWN, ZT_EVENT_DTMFUP, zt_get_event(), zt_get_index(), zt_handle_dtmfup(), zt_new(), zt_ring_phone(), zt_set_hook(), and zt_train_ec().
Referenced by __zt_exception().
03963 { 03964 int res, x; 03965 int index, mysig; 03966 char *c; 03967 struct zt_pvt *p = ast->tech_pvt; 03968 pthread_t threadid; 03969 pthread_attr_t attr; 03970 struct ast_channel *chan; 03971 struct ast_frame *f; 03972 03973 index = zt_get_index(ast, p, 0); 03974 mysig = p->sig; 03975 if (p->outsigmod > -1) 03976 mysig = p->outsigmod; 03977 p->subs[index].f.frametype = AST_FRAME_NULL; 03978 p->subs[index].f.subclass = 0; 03979 p->subs[index].f.datalen = 0; 03980 p->subs[index].f.samples = 0; 03981 p->subs[index].f.mallocd = 0; 03982 p->subs[index].f.offset = 0; 03983 p->subs[index].f.src = "zt_handle_event"; 03984 p->subs[index].f.data = NULL; 03985 f = &p->subs[index].f; 03986 03987 if (index < 0) 03988 return &p->subs[index].f; 03989 if (p->fake_event) { 03990 res = p->fake_event; 03991 p->fake_event = 0; 03992 } else 03993 res = zt_get_event(p->subs[index].zfd); 03994 03995 if (option_debug) 03996 ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index); 03997 03998 if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) { 03999 p->pulsedial = (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0; 04000 04001 ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 04002 #ifdef HAVE_PRI 04003 if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) { 04004 /* absorb event */ 04005 } else { 04006 #endif 04007 p->subs[index].f.frametype = AST_FRAME_DTMF_END; 04008 p->subs[index].f.subclass = res & 0xff; 04009 #ifdef HAVE_PRI 04010 } 04011 #endif 04012 zt_handle_dtmfup(ast, index, &f); 04013 return f; 04014 } 04015 04016 if (res & ZT_EVENT_DTMFDOWN) { 04017 if (option_debug) 04018 ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff); 04019 /* Mute conference */ 04020 zt_confmute(p, 1); 04021 p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN; 04022 p->subs[index].f.subclass = res & 0xff; 04023 return &p->subs[index].f; 04024 } 04025 04026 switch (res) { 04027 #ifdef ZT_EVENT_EC_DISABLED 04028 case ZT_EVENT_EC_DISABLED: 04029 if (option_verbose > 2) 04030 ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel); 04031 p->echocanon = 0; 04032 break; 04033 #endif 04034 case ZT_EVENT_BITSCHANGED: 04035 ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig)); 04036 case ZT_EVENT_PULSE_START: 04037 /* Stop tone if there's a pulse start and the PBX isn't started */ 04038 if (!ast->pbx) 04039 tone_zone_play_tone(p->subs[index].zfd, -1); 04040 break; 04041 case ZT_EVENT_DIALCOMPLETE: 04042 if (p->inalarm) break; 04043 if ((p->radio || (p->oprmode < 0))) break; 04044 if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) { 04045 ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name); 04046 return NULL; 04047 } 04048 if (!x) { /* if not still dialing in driver */ 04049 zt_enable_ec(p); 04050 if (p->echobreak) { 04051 zt_train_ec(p); 04052 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 04053 p->dop.op = ZT_DIAL_OP_REPLACE; 04054 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04055 p->echobreak = 0; 04056 } else { 04057 p->dialing = 0; 04058 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) { 04059 /* if thru with dialing after offhook */ 04060 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 04061 ast_setstate(ast, AST_STATE_UP); 04062 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04063 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04064 break; 04065 } else { /* if to state wait for offhook to dial rest */ 04066 /* we now wait for off hook */ 04067 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 04068 } 04069 } 04070 if (ast->_state == AST_STATE_DIALING) { 04071 if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 04072 ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n"); 04073 } 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)))) { 04074 ast_setstate(ast, AST_STATE_RINGING); 04075 } else if (!p->answeronpolarityswitch) { 04076 ast_setstate(ast, AST_STATE_UP); 04077 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04078 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04079 /* If aops=0 and hops=1, this is necessary */ 04080 p->polarity = POLARITY_REV; 04081 } else { 04082 /* Start clean, so we can catch the change to REV polarity when party answers */ 04083 p->polarity = POLARITY_IDLE; 04084 } 04085 } 04086 } 04087 } 04088 break; 04089 case ZT_EVENT_ALARM: 04090 #ifdef HAVE_PRI 04091 if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) { 04092 /* T309 is not enabled : hangup calls when alarm occurs */ 04093 if (p->call) { 04094 if (p->pri && p->pri->pri) { 04095 if (!pri_grab(p, p->pri)) { 04096 pri_hangup(p->pri->pri, p->call, -1, -1); 04097 pri_destroycall(p->pri->pri, p->call); 04098 p->call = NULL; 04099 pri_rel(p->pri); 04100 } else 04101 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 04102 } else 04103 ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n"); 04104 } 04105 if (p->owner) 04106 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04107 } 04108 if (p->bearer) 04109 p->bearer->inalarm = 1; 04110 else 04111 #endif 04112 p->inalarm = 1; 04113 res = get_alarms(p); 04114 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm2str(res)); 04115 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 04116 "Alarm: %s\r\n" 04117 "Channel: %d\r\n", 04118 alarm2str(res), p->channel); 04119 #ifdef HAVE_LIBPRI 04120 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 04121 /* fall through intentionally */ 04122 } else { 04123 break; 04124 } 04125 #endif 04126 case ZT_EVENT_ONHOOK: 04127 if (p->radio) { 04128 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04129 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 04130 break; 04131 } 04132 if (p->oprmode < 0) 04133 { 04134 if (p->oprmode != -1) break; 04135 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 04136 { 04137 /* Make sure it starts ringing */ 04138 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 04139 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING); 04140 save_conference(p->oprpeer); 04141 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04142 } 04143 break; 04144 } 04145 switch (p->sig) { 04146 case SIG_FXOLS: 04147 case SIG_FXOGS: 04148 case SIG_FXOKS: 04149 p->onhooktime = time(NULL); 04150 p->msgstate = -1; 04151 /* Check for some special conditions regarding call waiting */ 04152 if (index == SUB_REAL) { 04153 /* The normal line was hung up */ 04154 if (p->subs[SUB_CALLWAIT].owner) { 04155 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 04156 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 04157 if (option_verbose > 2) 04158 ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel); 04159 unalloc_sub(p, SUB_CALLWAIT); 04160 #if 0 04161 p->subs[index].needanswer = 0; 04162 p->subs[index].needringing = 0; 04163 #endif 04164 p->callwaitingrepeat = 0; 04165 p->cidcwexpire = 0; 04166 p->owner = NULL; 04167 /* Don't start streaming audio yet if the incoming call isn't up yet */ 04168 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 04169 p->dialing = 1; 04170 zt_ring_phone(p); 04171 } else if (p->subs[SUB_THREEWAY].owner) { 04172 unsigned int mssinceflash; 04173 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 04174 the private structure -- not especially easy or clean */ 04175 while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) { 04176 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 04177 ast_mutex_unlock(&p->lock); 04178 ast_mutex_unlock(&ast->lock); 04179 usleep(1); 04180 /* We can grab ast and p in that order, without worry. We should make sure 04181 nothing seriously bad has happened though like some sort of bizarre double 04182 masquerade! */ 04183 ast_mutex_lock(&ast->lock); 04184 ast_mutex_lock(&p->lock); 04185 if (p->owner != ast) { 04186 ast_log(LOG_WARNING, "This isn't good...\n"); 04187 return NULL; 04188 } 04189 } 04190 if (!p->subs[SUB_THREEWAY].owner) { 04191 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 04192 return NULL; 04193 } 04194 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 04195 ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash); 04196 if (mssinceflash < MIN_MS_SINCE_FLASH) { 04197 /* It hasn't been long enough since the last flashook. This is probably a bounce on 04198 hanging up. Hangup both channels now */ 04199 if (p->subs[SUB_THREEWAY].owner) 04200 ast_queue_hangup(p->subs[SUB_THREEWAY].owner); 04201 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04202 ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 04203 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04204 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 04205 if (p->transfer) { 04206 /* In any case this isn't a threeway call anymore */ 04207 p->subs[SUB_REAL].inthreeway = 0; 04208 p->subs[SUB_THREEWAY].inthreeway = 0; 04209 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 04210 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 04211 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04212 /* Swap subs and dis-own channel */ 04213 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04214 p->owner = NULL; 04215 /* Ring the phone */ 04216 zt_ring_phone(p); 04217 } else { 04218 if ((res = attempt_transfer(p)) < 0) { 04219 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04220 if (p->subs[SUB_THREEWAY].owner) 04221 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04222 } else if (res) { 04223 /* Don't actually hang up at this point */ 04224 if (p->subs[SUB_THREEWAY].owner) 04225 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04226 break; 04227 } 04228 } 04229 } else { 04230 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04231 if (p->subs[SUB_THREEWAY].owner) 04232 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04233 } 04234 } else { 04235 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 04236 /* Swap subs and dis-own channel */ 04237 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04238 p->owner = NULL; 04239 /* Ring the phone */ 04240 zt_ring_phone(p); 04241 } 04242 } 04243 } else { 04244 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index); 04245 } 04246 /* Fall through */ 04247 default: 04248 zt_disable_ec(p); 04249 return NULL; 04250 } 04251 break; 04252 case ZT_EVENT_RINGOFFHOOK: 04253 if (p->inalarm) break; 04254 if (p->oprmode < 0) 04255 { 04256 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 04257 { 04258 /* Make sure it stops ringing */ 04259 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 04260 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1); 04261 restore_conference(p->oprpeer); 04262 } 04263 break; 04264 } 04265 if (p->radio) 04266 { 04267 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04268 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04269 break; 04270 } 04271 /* for E911, its supposed to wait for offhook then dial 04272 the second half of the dial string */ 04273 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 04274 c = strchr(p->dialdest, '/'); 04275 if (c) 04276 c++; 04277 else 04278 c = p->dialdest; 04279 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 04280 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 04281 if (strlen(p->dop.dialstr) > 4) { 04282 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 04283 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 04284 p->echorest[sizeof(p->echorest) - 1] = '\0'; 04285 p->echobreak = 1; 04286 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 04287 } else 04288 p->echobreak = 0; 04289 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 04290 x = ZT_ONHOOK; 04291 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 04292 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 04293 return NULL; 04294 } 04295 p->dialing = 1; 04296 return &p->subs[index].f; 04297 } 04298 switch (p->sig) { 04299 case SIG_FXOLS: 04300 case SIG_FXOGS: 04301 case SIG_FXOKS: 04302 switch (ast->_state) { 04303 case AST_STATE_RINGING: 04304 zt_enable_ec(p); 04305 zt_train_ec(p); 04306 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04307 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04308 /* Make sure it stops ringing */ 04309 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04310 ast_log(LOG_DEBUG, "channel %d answered\n", p->channel); 04311 if (p->cidspill) { 04312 /* Cancel any running CallerID spill */ 04313 free(p->cidspill); 04314 p->cidspill = NULL; 04315 } 04316 p->dialing = 0; 04317 p->callwaitcas = 0; 04318 if (p->confirmanswer) { 04319 /* Ignore answer if "confirm answer" is enabled */ 04320 p->subs[index].f.frametype = AST_FRAME_NULL; 04321 p->subs[index].f.subclass = 0; 04322 } else if (!ast_strlen_zero(p->dop.dialstr)) { 04323 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 04324 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04325 if (res < 0) { 04326 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04327 p->dop.dialstr[0] = '\0'; 04328 return NULL; 04329 } else { 04330 ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 04331 p->subs[index].f.frametype = AST_FRAME_NULL; 04332 p->subs[index].f.subclass = 0; 04333 p->dialing = 1; 04334 } 04335 p->dop.dialstr[0] = '\0'; 04336 ast_setstate(ast, AST_STATE_DIALING); 04337 } else 04338 ast_setstate(ast, AST_STATE_UP); 04339 return &p->subs[index].f; 04340 case AST_STATE_DOWN: 04341 ast_setstate(ast, AST_STATE_RING); 04342 ast->rings = 1; 04343 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04344 p->subs[index].f.subclass = AST_CONTROL_OFFHOOK; 04345 ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel); 04346 return &p->subs[index].f; 04347 case AST_STATE_UP: 04348 /* Make sure it stops ringing */ 04349 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04350 /* Okay -- probably call waiting*/ 04351 if (ast_bridged_channel(p->owner)) 04352 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04353 p->subs[index].needunhold = 1; 04354 break; 04355 case AST_STATE_RESERVED: 04356 /* Start up dialtone */ 04357 if (has_voicemail(p)) 04358 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 04359 else 04360 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 04361 break; 04362 default: 04363 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 04364 } 04365 break; 04366 case SIG_FXSLS: 04367 case SIG_FXSGS: 04368 case SIG_FXSKS: 04369 if (ast->_state == AST_STATE_RING) { 04370 p->ringt = p->ringt_base; 04371 } 04372 04373 /* Fall through */ 04374 case SIG_EM: 04375 case SIG_EM_E1: 04376 case SIG_EMWINK: 04377 case SIG_FEATD: 04378 case SIG_FEATDMF: 04379 case SIG_FEATDMF_TA: 04380 case SIG_E911: 04381 case SIG_FGC_CAMA: 04382 case SIG_FGC_CAMAMF: 04383 case SIG_FEATB: 04384 case SIG_SF: 04385 case SIG_SFWINK: 04386 case SIG_SF_FEATD: 04387 case SIG_SF_FEATDMF: 04388 case SIG_SF_FEATB: 04389 if (ast->_state == AST_STATE_PRERING) 04390 ast_setstate(ast, AST_STATE_RING); 04391 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 04392 if (option_debug) 04393 ast_log(LOG_DEBUG, "Ring detected\n"); 04394 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04395 p->subs[index].f.subclass = AST_CONTROL_RING; 04396 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 04397 if (option_debug) 04398 ast_log(LOG_DEBUG, "Line answered\n"); 04399 if (p->confirmanswer) { 04400 p->subs[index].f.frametype = AST_FRAME_NULL; 04401 p->subs[index].f.subclass = 0; 04402 } else { 04403 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04404 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04405 ast_setstate(ast, AST_STATE_UP); 04406 } 04407 } else if (ast->_state != AST_STATE_RING) 04408 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 04409 break; 04410 default: 04411 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 04412 } 04413 break; 04414 #ifdef ZT_EVENT_RINGBEGIN 04415 case ZT_EVENT_RINGBEGIN: 04416 switch (p->sig) { 04417 case SIG_FXSLS: 04418 case SIG_FXSGS: 04419 case SIG_FXSKS: 04420 if (ast->_state == AST_STATE_RING) { 04421 p->ringt = p->ringt_base; 04422 } 04423 break; 04424 } 04425 break; 04426 #endif 04427 case ZT_EVENT_RINGEROFF: 04428 if (p->inalarm) break; 04429 if ((p->radio || (p->oprmode < 0))) break; 04430 ast->rings++; 04431 if ((ast->rings > p->cidrings) && (p->cidspill)) { 04432 ast_log(LOG_WARNING, "Didn't finish Caller-ID spill. Cancelling.\n"); 04433 free(p->cidspill); 04434 p->cidspill = NULL; 04435 p->callwaitcas = 0; 04436 } 04437 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04438 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04439 break; 04440 case ZT_EVENT_RINGERON: 04441 break; 04442 case ZT_EVENT_NOALARM: 04443 p->inalarm = 0; 04444 #ifdef HAVE_PRI 04445 /* Extremely unlikely but just in case */ 04446 if (p->bearer) 04447 p->bearer->inalarm = 0; 04448 #endif 04449 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 04450 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 04451 "Channel: %d\r\n", p->channel); 04452 break; 04453 case ZT_EVENT_WINKFLASH: 04454 if (p->inalarm) break; 04455 if (p->radio) break; 04456 if (p->oprmode < 0) break; 04457 if (p->oprmode > 1) 04458 { 04459 struct zt_params par; 04460 04461 if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1) 04462 { 04463 if (!par.rxisoffhook) 04464 { 04465 /* Make sure it stops ringing */ 04466 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF); 04467 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING); 04468 save_conference(p); 04469 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04470 } 04471 } 04472 break; 04473 } 04474 /* Remember last time we got a flash-hook */ 04475 gettimeofday(&p->flashtime, NULL); 04476 switch (mysig) { 04477 case SIG_FXOLS: 04478 case SIG_FXOGS: 04479 case SIG_FXOKS: 04480 ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 04481 index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 04482 p->callwaitcas = 0; 04483 04484 if (index != SUB_REAL) { 04485 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel); 04486 goto winkflashdone; 04487 } 04488 04489 if (p->subs[SUB_CALLWAIT].owner) { 04490 /* Swap to call-wait */ 04491 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 04492 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 04493 p->owner = p->subs[SUB_REAL].owner; 04494 ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name); 04495 if (p->owner->_state == AST_STATE_RINGING) { 04496 ast_setstate(p->owner, AST_STATE_UP); 04497 p->subs[SUB_REAL].needanswer = 1; 04498 } 04499 p->callwaitingrepeat = 0; 04500 p->cidcwexpire = 0; 04501 /* Start music on hold if appropriate */ 04502 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 04503 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 04504 S_OR(p->mohsuggest, NULL), 04505 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04506 } 04507 p->subs[SUB_CALLWAIT].needhold = 1; 04508 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 04509 ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD, 04510 S_OR(p->mohsuggest, NULL), 04511 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04512 } 04513 p->subs[SUB_REAL].needunhold = 1; 04514 } else if (!p->subs[SUB_THREEWAY].owner) { 04515 char cid_num[256]; 04516 char cid_name[256]; 04517 04518 if (!p->threewaycalling) { 04519 /* Just send a flash if no 3-way calling */ 04520 p->subs[SUB_REAL].needflash = 1; 04521 goto winkflashdone; 04522 } else if (!check_for_conference(p)) { 04523 if (p->zaptrcallerid && p->owner) { 04524 if (p->owner->cid.cid_num) 04525 ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num)); 04526 if (p->owner->cid.cid_name) 04527 ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name)); 04528 } 04529 /* XXX This section needs much more error checking!!! XXX */ 04530 /* Start a 3-way call if feasible */ 04531 if (!((ast->pbx) || 04532 (ast->_state == AST_STATE_UP) || 04533 (ast->_state == AST_STATE_RING))) { 04534 ast_log(LOG_DEBUG, "Flash when call not up or ringing\n"); 04535 goto winkflashdone; 04536 } 04537 if (alloc_sub(p, SUB_THREEWAY)) { 04538 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 04539 goto winkflashdone; 04540 } 04541 /* Make new channel */ 04542 chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0); 04543 if (p->zaptrcallerid) { 04544 if (!p->origcid_num) 04545 p->origcid_num = ast_strdup(p->cid_num); 04546 if (!p->origcid_name) 04547 p->origcid_name = ast_strdup(p->cid_name); 04548 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 04549 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 04550 } 04551 /* Swap things around between the three-way and real call */ 04552 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04553 /* Disable echo canceller for better dialing */ 04554 zt_disable_ec(p); 04555 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL); 04556 if (res) 04557 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 04558 p->owner = chan; 04559 pthread_attr_init(&attr); 04560 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04561 if (!chan) { 04562 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 04563 } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 04564 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 04565 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 04566 zt_enable_ec(p); 04567 ast_hangup(chan); 04568 } else { 04569 if (option_verbose > 2) 04570 ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel); 04571 /* Start music on hold if appropriate */ 04572 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 04573 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 04574 S_OR(p->mohsuggest, NULL), 04575 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04576 } 04577 p->subs[SUB_THREEWAY].needhold = 1; 04578 } 04579 pthread_attr_destroy(&attr); 04580 } 04581 } else { 04582 /* Already have a 3 way call */ 04583 if (p->subs[SUB_THREEWAY].inthreeway) { 04584 /* Call is already up, drop the last person */ 04585 if (option_debug) 04586 ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel); 04587 /* If the primary call isn't answered yet, use it */ 04588 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 04589 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 04590 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04591 p->owner = p->subs[SUB_REAL].owner; 04592 } 04593 /* Drop the last call and stop the conference */ 04594 if (option_verbose > 2) 04595 ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name); 04596 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04597 p->subs[SUB_REAL].inthreeway = 0; 04598 p->subs[SUB_THREEWAY].inthreeway = 0; 04599 } else { 04600 /* Lets see what we're up to */ 04601 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 04602 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 04603 int otherindex = SUB_THREEWAY; 04604 04605 if (option_verbose > 2) 04606 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); 04607 /* Put them in the threeway, and flip */ 04608 p->subs[SUB_THREEWAY].inthreeway = 1; 04609 p->subs[SUB_REAL].inthreeway = 1; 04610 if (ast->_state == AST_STATE_UP) { 04611 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04612 otherindex = SUB_REAL; 04613 } 04614 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 04615 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 04616 p->subs[otherindex].needunhold = 1; 04617 p->owner = p->subs[SUB_REAL].owner; 04618 if (ast->_state == AST_STATE_RINGING) { 04619 ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n"); 04620 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04621 res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 04622 } 04623 } else { 04624 if (option_verbose > 2) 04625 ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name); 04626 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04627 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04628 p->owner = p->subs[SUB_REAL].owner; 04629 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 04630 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 04631 p->subs[SUB_REAL].needunhold = 1; 04632 zt_enable_ec(p); 04633 } 04634 04635 } 04636 } 04637 winkflashdone: 04638 update_conf(p); 04639 break; 04640 case SIG_EM: 04641 case SIG_EM_E1: 04642 case SIG_EMWINK: 04643 case SIG_FEATD: 04644 case SIG_SF: 04645 case SIG_SFWINK: 04646 case SIG_SF_FEATD: 04647 case SIG_FXSLS: 04648 case SIG_FXSGS: 04649 if (p->dialing) 04650 ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel); 04651 else 04652 ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 04653 break; 04654 case SIG_FEATDMF_TA: 04655 switch (p->whichwink) { 04656 case 0: 04657 ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04658 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04659 break; 04660 case 1: 04661 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 04662 break; 04663 case 2: 04664 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 04665 return NULL; 04666 } 04667 p->whichwink++; 04668 /* Fall through */ 04669 case SIG_FEATDMF: 04670 case SIG_E911: 04671 case SIG_FGC_CAMAMF: 04672 case SIG_FGC_CAMA: 04673 case SIG_FEATB: 04674 case SIG_SF_FEATDMF: 04675 case SIG_SF_FEATB: 04676 /* FGD MF *Must* wait for wink */ 04677 if (!ast_strlen_zero(p->dop.dialstr)) 04678 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04679 else if (res < 0) { 04680 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04681 p->dop.dialstr[0] = '\0'; 04682 return NULL; 04683 } else 04684 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04685 p->dop.dialstr[0] = '\0'; 04686 break; 04687 default: 04688 ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig); 04689 } 04690 break; 04691 case ZT_EVENT_HOOKCOMPLETE: 04692 if (p->inalarm) break; 04693 if ((p->radio || (p->oprmode < 0))) break; 04694 switch (mysig) { 04695 case SIG_FXSLS: /* only interesting for FXS */ 04696 case SIG_FXSGS: 04697 case SIG_FXSKS: 04698 case SIG_EM: 04699 case SIG_EM_E1: 04700 case SIG_EMWINK: 04701 case SIG_FEATD: 04702 case SIG_SF: 04703 case SIG_SFWINK: 04704 case SIG_SF_FEATD: 04705 if (!ast_strlen_zero(p->dop.dialstr)) 04706 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04707 else if (res < 0) { 04708 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04709 p->dop.dialstr[0] = '\0'; 04710 return NULL; 04711 } else 04712 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04713 p->dop.dialstr[0] = '\0'; 04714 p->dop.op = ZT_DIAL_OP_REPLACE; 04715 break; 04716 case SIG_FEATDMF: 04717 case SIG_FEATDMF_TA: 04718 case SIG_E911: 04719 case SIG_FGC_CAMA: 04720 case SIG_FGC_CAMAMF: 04721 case SIG_FEATB: 04722 case SIG_SF_FEATDMF: 04723 case SIG_SF_FEATB: 04724 ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 04725 break; 04726 default: 04727 break; 04728 } 04729 break; 04730 case ZT_EVENT_POLARITY: 04731 /* 04732 * If we get a Polarity Switch event, check to see 04733 * if we should change the polarity state and 04734 * mark the channel as UP or if this is an indication 04735 * of remote end disconnect. 04736 */ 04737 if (p->polarity == POLARITY_IDLE) { 04738 p->polarity = POLARITY_REV; 04739 if (p->answeronpolarityswitch && 04740 ((ast->_state == AST_STATE_DIALING) || 04741 (ast->_state == AST_STATE_RINGING))) { 04742 ast_log(LOG_DEBUG, "Answering on polarity switch!\n"); 04743 ast_setstate(p->owner, AST_STATE_UP); 04744 if (p->hanguponpolarityswitch) { 04745 gettimeofday(&p->polaritydelaytv, NULL); 04746 } 04747 } else 04748 ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 04749 } 04750 /* Removed else statement from here as it was preventing hangups from ever happening*/ 04751 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 04752 if (p->hanguponpolarityswitch && 04753 (p->polarityonanswerdelay > 0) && 04754 (p->polarity == POLARITY_REV) && 04755 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 04756 /* Added log_debug information below to provide a better indication of what is going on */ 04757 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) ); 04758 04759 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 04760 ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 04761 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 04762 p->polarity = POLARITY_IDLE; 04763 } else { 04764 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); 04765 } 04766 } else { 04767 p->polarity = POLARITY_IDLE; 04768 ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 04769 } 04770 /* Added more log_debug information below to provide a better indication of what is going on */ 04771 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) ); 04772 break; 04773 default: 04774 ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel); 04775 } 04776 return &p->subs[index].f; 04777 }
static int zt_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2642 of file chan_zap.c.
References ast_channel::_state, ast_bridged_channel(), ast_channel_setoption(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_dsp_digitmode(), ast_dsp_free(), ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_AUDIO_MODE, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, ast_queue_control(), ast_queue_control_data(), AST_STATE_DIALING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_verbose(), zt_pvt::callwaitcas, zt_pvt::callwaiting, zt_pvt::callwaitingrepeat, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, zt_pvt::destroy, destroy_channel(), zt_pvt::dialing, zt_pvt::didtdd, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dtmfrelax, zt_pvt::exten, zt_pvt::faxhandled, free, zt_pvt::guardtime, ast_channel::hangupcause, zt_pvt::hidecallerid, iflist, zt_subchannel::inthreeway, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, zt_pvt::mohsuggest, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needringing, zt_pvt::next, zt_pvt::onhooktime, zt_pvt::oprmode, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_getvar_helper(), zt_pvt::permcallwaiting, zt_pvt::permhidecallerid, zt_pvt::polarity, POLARITY_IDLE, zt_pvt::prev, zt_pvt::pulsedial, zt_pvt::radio, zt_pvt::rdnis, reset_conf(), restart_monitor(), restore_gains(), zt_pvt::ringt, S_OR, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GSM, SIG_PRI, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, unalloc_sub(), update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_get_index(), zt_set_hook(), and zt_setlinear().
02643 { 02644 int res; 02645 int index,x, law; 02646 /*static int restore_gains(struct zt_pvt *p);*/ 02647 struct zt_pvt *p = ast->tech_pvt; 02648 struct zt_pvt *tmp = NULL; 02649 struct zt_pvt *prev = NULL; 02650 ZT_PARAMS par; 02651 02652 if (option_debug) 02653 ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name); 02654 if (!ast->tech_pvt) { 02655 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 02656 return 0; 02657 } 02658 02659 ast_mutex_lock(&p->lock); 02660 02661 index = zt_get_index(ast, p, 1); 02662 02663 if (p->sig == SIG_PRI) { 02664 x = 1; 02665 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02666 } 02667 02668 x = 0; 02669 zt_confmute(p, 0); 02670 restore_gains(p); 02671 if (p->origcid_num) { 02672 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 02673 free(p->origcid_num); 02674 p->origcid_num = NULL; 02675 } 02676 if (p->origcid_name) { 02677 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 02678 free(p->origcid_name); 02679 p->origcid_name = NULL; 02680 } 02681 if (p->dsp) 02682 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 02683 if (p->exten) 02684 p->exten[0] = '\0'; 02685 02686 if (option_debug) 02687 ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 02688 p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 02689 02690 if (index > -1) { 02691 /* Real channel, do some fixup */ 02692 p->subs[index].owner = NULL; 02693 p->subs[index].needanswer = 0; 02694 p->subs[index].needflash = 0; 02695 p->subs[index].needringing = 0; 02696 p->subs[index].needbusy = 0; 02697 p->subs[index].needcongestion = 0; 02698 p->subs[index].linear = 0; 02699 p->subs[index].needcallerid = 0; 02700 p->polarity = POLARITY_IDLE; 02701 zt_setlinear(p->subs[index].zfd, 0); 02702 if (index == SUB_REAL) { 02703 if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) { 02704 ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n"); 02705 if (p->subs[SUB_CALLWAIT].inthreeway) { 02706 /* We had flipped over to answer a callwait and now it's gone */ 02707 ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n"); 02708 /* Move to the call-wait, but un-own us until they flip back. */ 02709 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02710 unalloc_sub(p, SUB_CALLWAIT); 02711 p->owner = NULL; 02712 } else { 02713 /* The three way hung up, but we still have a call wait */ 02714 ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 02715 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02716 unalloc_sub(p, SUB_THREEWAY); 02717 if (p->subs[SUB_REAL].inthreeway) { 02718 /* This was part of a three way call. Immediately make way for 02719 another call */ 02720 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02721 p->owner = p->subs[SUB_REAL].owner; 02722 } else { 02723 /* This call hasn't been completed yet... Set owner to NULL */ 02724 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02725 p->owner = NULL; 02726 } 02727 p->subs[SUB_REAL].inthreeway = 0; 02728 } 02729 } else if (p->subs[SUB_CALLWAIT].zfd > -1) { 02730 /* Move to the call-wait and switch back to them. */ 02731 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02732 unalloc_sub(p, SUB_CALLWAIT); 02733 p->owner = p->subs[SUB_REAL].owner; 02734 if (p->owner->_state != AST_STATE_UP) 02735 p->subs[SUB_REAL].needanswer = 1; 02736 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 02737 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 02738 } else if (p->subs[SUB_THREEWAY].zfd > -1) { 02739 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02740 unalloc_sub(p, SUB_THREEWAY); 02741 if (p->subs[SUB_REAL].inthreeway) { 02742 /* This was part of a three way call. Immediately make way for 02743 another call */ 02744 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02745 p->owner = p->subs[SUB_REAL].owner; 02746 } else { 02747 /* This call hasn't been completed yet... Set owner to NULL */ 02748 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02749 p->owner = NULL; 02750 } 02751 p->subs[SUB_REAL].inthreeway = 0; 02752 } 02753 } else if (index == SUB_CALLWAIT) { 02754 /* Ditch the holding callwait call, and immediately make it availabe */ 02755 if (p->subs[SUB_CALLWAIT].inthreeway) { 02756 /* This is actually part of a three way, placed on hold. Place the third part 02757 on music on hold now */ 02758 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 02759 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 02760 S_OR(p->mohsuggest, NULL), 02761 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02762 } 02763 p->subs[SUB_THREEWAY].inthreeway = 0; 02764 /* Make it the call wait now */ 02765 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 02766 unalloc_sub(p, SUB_THREEWAY); 02767 } else 02768 unalloc_sub(p, SUB_CALLWAIT); 02769 } else if (index == SUB_THREEWAY) { 02770 if (p->subs[SUB_CALLWAIT].inthreeway) { 02771 /* The other party of the three way call is currently in a call-wait state. 02772 Start music on hold for them, and take the main guy out of the third call */ 02773 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 02774 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 02775 S_OR(p->mohsuggest, NULL), 02776 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02777 } 02778 p->subs[SUB_CALLWAIT].inthreeway = 0; 02779 } 02780 p->subs[SUB_REAL].inthreeway = 0; 02781 /* If this was part of a three way call index, let us make 02782 another three way call */ 02783 unalloc_sub(p, SUB_THREEWAY); 02784 } else { 02785 /* This wasn't any sort of call, but how are we an index? */ 02786 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 02787 } 02788 } 02789 02790 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 02791 int outgoing = p->outgoing; 02792 p->owner = NULL; 02793 p->ringt = 0; 02794 p->distinctivering = 0; 02795 p->confirmanswer = 0; 02796 p->cidrings = 1; 02797 p->outgoing = 0; 02798 p->digital = 0; 02799 p->faxhandled = 0; 02800 p->pulsedial = 0; 02801 p->onhooktime = time(NULL); 02802 #ifdef HAVE_PRI 02803 p->proceeding = 0; 02804 p->progress = 0; 02805 p->alerting = 0; 02806 p->setup_ack = 0; 02807 #endif 02808 if (p->dsp) { 02809 ast_dsp_free(p->dsp); 02810 p->dsp = NULL; 02811 } 02812 02813 law = ZT_LAW_DEFAULT; 02814 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law); 02815 if (res < 0) 02816 ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel); 02817 /* Perform low level hangup if no owner left */ 02818 #ifdef HAVE_PRI 02819 if (p->pri) { 02820 #ifdef SUPPORT_USERUSER 02821 const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO"); 02822 #endif 02823 02824 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */ 02825 if (p->call && (!p->bearer || (p->bearer->call == p->call))) { 02826 if (!pri_grab(p, p->pri)) { 02827 if (p->alreadyhungup) { 02828 ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); 02829 02830 #ifdef SUPPORT_USERUSER 02831 pri_call_set_useruser(p->call, useruser); 02832 #endif 02833 02834 pri_hangup(p->pri->pri, p->call, -1, -1); 02835 p->call = NULL; 02836 if (p->bearer) 02837 p->bearer->call = NULL; 02838 } else { 02839 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 02840 int icause = ast->hangupcause ? ast->hangupcause : -1; 02841 ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); 02842 02843 #ifdef SUPPORT_USERUSER 02844 pri_call_set_useruser(p->call, useruser); 02845 #endif 02846 02847 p->alreadyhungup = 1; 02848 if (p->bearer) 02849 p->bearer->alreadyhungup = 1; 02850 if (cause) { 02851 if (atoi(cause)) 02852 icause = atoi(cause); 02853 } 02854 02855 pri_hangup(p->pri->pri, p->call, icause, -1); 02856 02857 /* if we send a rel9999ease complete we wont ge no hangup event, so clear the call here */ 02858 if (icause == 34 || icause == 44 || icause == 82 || icause == 1 || icause == 81 || icause == 17) { 02859 if ((ast->_state == AST_STATE_RING) || (ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING) || (ast->_state == AST_STATE_RESERVED)) { 02860 p->call = NULL; 02861 } else { 02862 ast_log(LOG_ERROR, "What is wrong with you? You cannot use cause %d number when in state %d!\n", icause, ast->_state); 02863 icause = 16; /* Note, in pri_hangup() libpri will already override the cause */ 02864 } 02865 } 02866 02867 if (p->pri->nodetype == BRI_NETWORK_PTMP) { 02868 if ((icause == 16 || icause == -1) && (ast->_state != AST_STATE_UP)) { 02869 if (outgoing) { 02870 p->call = NULL; 02871 } 02872 } 02873 } 02874 02875 02876 } 02877 if (res < 0) 02878 ast_log(LOG_WARNING, "pri_disconnect failed\n"); 02879 pri_rel(p->pri); 02880 } else { 02881 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02882 res = -1; 02883 } 02884 } else { 02885 if (p->bearer) 02886 ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call); 02887 p->call = NULL; 02888 res = 0; 02889 } 02890 } 02891 #endif 02892 #ifdef HAVE_GSMAT 02893 if (p->gsm.modul) { 02894 if (!p->alreadyhungup) 02895 gsm_hangup(p->gsm.modul); 02896 } 02897 #endif 02898 if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_GSM)) 02899 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 02900 if (res < 0) { 02901 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 02902 } 02903 switch (p->sig) { 02904 case SIG_FXOGS: 02905 case SIG_FXOLS: 02906 case SIG_FXOKS: 02907 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 02908 if (!res) { 02909 #if 0 02910 ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 02911 #endif 02912 /* If they're off hook, try playing congestion */ 02913 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0)))) 02914 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 02915 else 02916 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02917 } 02918 break; 02919 case SIG_FXSGS: 02920 case SIG_FXSLS: 02921 case SIG_FXSKS: 02922 /* Make sure we're not made available for at least two seconds assuming 02923 we were actually used for an inbound or outbound call. */ 02924 if (ast->_state != AST_STATE_RESERVED) { 02925 time(&p->guardtime); 02926 p->guardtime += 2; 02927 } 02928 break; 02929 default: 02930 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02931 } 02932 if (p->cidspill) 02933 free(p->cidspill); 02934 if (p->sig) 02935 zt_disable_ec(p); 02936 x = 0; 02937 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 02938 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 02939 p->didtdd = 0; 02940 p->cidspill = NULL; 02941 p->callwaitcas = 0; 02942 p->callwaiting = p->permcallwaiting; 02943 p->hidecallerid = p->permhidecallerid; 02944 p->dialing = 0; 02945 p->rdnis[0] = '\0'; 02946 update_conf(p); 02947 reset_conf(p); 02948 /* Restore data mode */ 02949 if (p->sig == SIG_PRI) { 02950 x = 0; 02951 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02952 } 02953 #ifdef HAVE_PRI 02954 if (p->bearer) { 02955 ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel); 02956 /* Free up the bearer channel as well, and 02957 don't use its file descriptor anymore */ 02958 update_conf(p->bearer); 02959 reset_conf(p->bearer); 02960 p->bearer->owner = NULL; 02961 p->bearer->realcall = NULL; 02962 p->bearer = NULL; 02963 p->subs[SUB_REAL].zfd = -1; 02964 p->pri = NULL; 02965 } 02966 #endif 02967 restart_monitor(); 02968 } 02969 02970 p->callwaitingrepeat = 0; 02971 p->cidcwexpire = 0; 02972 p->oprmode = 0; 02973 ast->tech_pvt = NULL; 02974 ast_mutex_unlock(&p->lock); 02975 ast_module_unref(ast_module_info->self); 02976 if (option_verbose > 2) 02977 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name); 02978 02979 ast_mutex_lock(&iflock); 02980 tmp = iflist; 02981 prev = NULL; 02982 if (p->destroy) { 02983 while (tmp) { 02984 if (tmp == p) { 02985 destroy_channel(prev, tmp, 0); 02986 break; 02987 } else { 02988 prev = tmp; 02989 tmp = tmp->next; 02990 } 02991 } 02992 } 02993 ast_mutex_unlock(&iflock); 02994 return 0; 02995 }
static int zt_indicate | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5292 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, errno, func, ast_channel::hangupcause, ISTRUNK, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::mohinterpret, option_debug, zt_pvt::outgoing, zt_pvt::priindication_oob, zt_pvt::radio, zt_pvt::sig, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_set_hook().
Referenced by zt_fixup().
05293 { 05294 struct zt_pvt *p = chan->tech_pvt; 05295 int res=-1; 05296 int index; 05297 int func = ZT_FLASH; 05298 ast_mutex_lock(&p->lock); 05299 index = zt_get_index(chan, p, 0); 05300 if (option_debug) 05301 ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name); 05302 if (index == SUB_REAL) { 05303 switch (condition) { 05304 case AST_CONTROL_BUSY: 05305 #ifdef HAVE_PRI 05306 if ((p->priindication_oob == 1) && p->sig == SIG_PRI) { 05307 chan->hangupcause = AST_CAUSE_USER_BUSY; 05308 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05309 res = 0; 05310 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05311 if (p->pri->pri) { 05312 if (!pri_grab(p, p->pri)) { 05313 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05314 pri_rel(p->pri); 05315 } 05316 else 05317 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05318 } 05319 p->progress = 1; 05320 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05321 } else 05322 #endif 05323 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05324 break; 05325 case AST_CONTROL_RINGING: 05326 #ifdef HAVE_PRI 05327 if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) { 05328 if (p->pri->pri) { 05329 if (!pri_grab(p, p->pri)) { 05330 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05331 pri_rel(p->pri); 05332 } 05333 else 05334 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05335 } 05336 p->alerting = 1; 05337 } 05338 #endif 05339 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE); 05340 if (chan->_state != AST_STATE_UP) { 05341 if ((chan->_state != AST_STATE_RING) || 05342 ((p->sig != SIG_FXSKS) && 05343 (p->sig != SIG_FXSLS) && 05344 (p->sig != SIG_FXSGS))) 05345 ast_setstate(chan, AST_STATE_RINGING); 05346 } 05347 break; 05348 case AST_CONTROL_PROCEEDING: 05349 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 05350 #ifdef HAVE_PRI 05351 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05352 if (p->pri->pri) { 05353 if (!pri_grab(p, p->pri)) { 05354 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05355 pri_rel(p->pri); 05356 } 05357 else 05358 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05359 } 05360 p->proceeding = 1; 05361 } 05362 #endif 05363 /* don't continue in ast_indicate */ 05364 res = 0; 05365 break; 05366 case AST_CONTROL_PROGRESS: 05367 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 05368 #ifdef HAVE_PRI 05369 p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */ 05370 if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05371 if (p->pri->pri) { 05372 if (!pri_grab(p, p->pri)) { 05373 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05374 pri_rel(p->pri); 05375 } 05376 else 05377 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05378 } 05379 p->progress = 1; 05380 } 05381 #endif 05382 /* don't continue in ast_indicate */ 05383 res = 0; 05384 break; 05385 case AST_CONTROL_CONGESTION: 05386 chan->hangupcause = AST_CAUSE_CONGESTION; 05387 #ifdef HAVE_PRI 05388 if ((p->priindication_oob == 1) && p->sig == SIG_PRI) { 05389 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 05390 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05391 res = 0; 05392 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05393 if (p->pri) { 05394 if (!pri_grab(p, p->pri)) { 05395 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05396 pri_rel(p->pri); 05397 } else 05398 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05399 } 05400 p->progress = 1; 05401 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05402 } else 05403 #endif 05404 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05405 break; 05406 case AST_CONTROL_HOLD: 05407 #ifdef HAVE_PRI 05408 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05409 if (!pri_grab(p, p->pri)) { 05410 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 05411 pri_rel(p->pri); 05412 } else 05413 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05414 } else 05415 #endif 05416 ast_moh_start(chan, data, p->mohinterpret); 05417 break; 05418 case AST_CONTROL_UNHOLD: 05419 #ifdef HAVE_PRI 05420 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05421 if (!pri_grab(p, p->pri)) { 05422 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 05423 pri_rel(p->pri); 05424 } else 05425 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05426 } else 05427 #endif 05428 ast_moh_stop(chan); 05429 break; 05430 case AST_CONTROL_RADIO_KEY: 05431 if (p->radio) 05432 res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 05433 res = 0; 05434 break; 05435 case AST_CONTROL_RADIO_UNKEY: 05436 if (p->radio) 05437 res = zt_set_hook(p->subs[index].zfd, ZT_RINGOFF); 05438 res = 0; 05439 break; 05440 case AST_CONTROL_FLASH: 05441 /* flash hookswitch */ 05442 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 05443 /* Clear out the dial buffer */ 05444 p->dop.dialstr[0] = '\0'; 05445 if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 05446 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 05447 chan->name, strerror(errno)); 05448 } else 05449 res = 0; 05450 } else 05451 res = 0; 05452 break; 05453 case -1: 05454 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05455 break; 05456 } 05457 } else 05458 res = 0; 05459 ast_mutex_unlock(&p->lock); 05460 return res; 05461 }
Definition at line 3355 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_DEBUG, LOG_WARNING, zt_pvt::master, MAX_SLAVES, and zt_pvt::slaves.
Referenced by zt_bridge().
03355 { 03356 int x; 03357 if (!slave || !master) { 03358 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 03359 return; 03360 } 03361 for (x = 0; x < MAX_SLAVES; x++) { 03362 if (!master->slaves[x]) { 03363 master->slaves[x] = slave; 03364 break; 03365 } 03366 } 03367 if (x >= MAX_SLAVES) { 03368 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 03369 master->slaves[MAX_SLAVES - 1] = slave; 03370 } 03371 if (slave->master) 03372 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 03373 slave->master = master; 03374 03375 ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 03376 }
static struct ast_channel * zt_new | ( | struct zt_pvt * | i, | |
int | state, | |||
int | startpbx, | |||
int | index, | |||
int | law, | |||
int | transfercapability | |||
) | [static, read] |
> b2 can be freed now, it's been copied into the channel structure
Definition at line 5463 of file chan_zap.c.
References accountcode, zt_pvt::accountcode, zt_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, zt_pvt::amaflags, AST_ADSI_UNAVAILABLE, ast_channel_alloc(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_busy_count(), ast_dsp_set_busy_pattern(), ast_dsp_set_call_progress_zone(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), ast_random(), ast_safe_string_alloc(), AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_transfercapability2str(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::call_forward, zt_pvt::callgroup, ast_channel::callgroup, zt_pvt::callingpres, zt_pvt::callprogress, CANBUSYDETECT, CANPROGRESSDETECT, CHAN_PSEUDO, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, zt_pvt::cid_name, zt_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cid_ton, ast_callerid::cid_ton, ast_channel::context, zt_pvt::context, zt_pvt::digital, zt_pvt::dnid, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, zt_pvt::dsp_features, DSP_PROGRESS_TALK, zt_pvt::dtmfrelax, ast_channel::exten, zt_pvt::exten, zt_pvt::fake_event, ast_channel::fds, free, global_jbconf, zt_pvt::hardwaredtmf, language, zt_pvt::language, zt_subchannel::linear, LOG_DEBUG, LOG_WARNING, ast_channel::nativeformats, NEED_MFDETECT, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), zt_pvt::pickupgroup, ast_channel::pickupgroup, PRI_TRANS_CAP_DIGITAL, ast_channel::rawreadformat, ast_channel::rawwriteformat, zt_pvt::rdnis, ast_channel::readformat, ast_channel::rings, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_PRI, SUB_REAL, zt_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, ast_channel::writeformat, zt_subchannel::zfd, zt_confmute(), and zt_setlinear().
Referenced by handle_init_event(), zt_handle_event(), and zt_request().
05464 { 05465 struct ast_channel *tmp; 05466 int deflaw; 05467 int res; 05468 int x,y; 05469 int features; 05470 char *b2 = NULL; 05471 ZT_PARAMS ps; 05472 if (i->subs[index].owner) { 05473 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]); 05474 return NULL; 05475 } 05476 y = 1; 05477 do { 05478 if (b2) 05479 free(b2); 05480 #ifdef HAVE_PRI 05481 if (i->bearer || (i->pri && (i->sig == SIG_FXSKS))) 05482 b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y); 05483 else 05484 #endif 05485 if (i->channel == CHAN_PSEUDO) 05486 b2 = ast_safe_string_alloc("pseudo-%ld", ast_random()); 05487 else 05488 b2 = ast_safe_string_alloc("%d-%d", i->channel, y); 05489 for (x = 0; x < 3; x++) { 05490 if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name)) 05491 break; 05492 } 05493 y++; 05494 } while (x < 3); 05495 tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2); 05496 if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */ 05497 free(b2); 05498 if (!tmp) 05499 return NULL; 05500 tmp->tech = &zap_tech; 05501 ps.channo = i->channel; 05502 res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps); 05503 if (res) { 05504 ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n"); 05505 ps.curlaw = ZT_LAW_MULAW; 05506 } 05507 if (ps.curlaw == ZT_LAW_ALAW) 05508 deflaw = AST_FORMAT_ALAW; 05509 else 05510 deflaw = AST_FORMAT_ULAW; 05511 if (law) { 05512 if (law == ZT_LAW_ALAW) 05513 deflaw = AST_FORMAT_ALAW; 05514 else 05515 deflaw = AST_FORMAT_ULAW; 05516 } 05517 tmp->fds[0] = i->subs[index].zfd; 05518 tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw; 05519 /* Start out assuming ulaw since it's smaller :) */ 05520 tmp->rawreadformat = deflaw; 05521 tmp->readformat = deflaw; 05522 tmp->rawwriteformat = deflaw; 05523 tmp->writeformat = deflaw; 05524 i->subs[index].linear = 0; 05525 zt_setlinear(i->subs[index].zfd, i->subs[index].linear); 05526 features = 0; 05527 if (index == SUB_REAL) { 05528 if (i->busydetect && CANBUSYDETECT(i)) 05529 features |= DSP_FEATURE_BUSY_DETECT; 05530 if ((i->callprogress & 1) && CANPROGRESSDETECT(i)) 05531 features |= DSP_FEATURE_CALL_PROGRESS; 05532 if ((!i->outgoing && (i->callprogress & 4)) || 05533 (i->outgoing && (i->callprogress & 2))) { 05534 features |= DSP_FEATURE_FAX_DETECT; 05535 } 05536 #ifdef ZT_TONEDETECT 05537 x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 05538 if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) { 05539 #endif 05540 i->hardwaredtmf = 0; 05541 features |= DSP_FEATURE_DTMF_DETECT; 05542 #ifdef ZT_TONEDETECT 05543 } else if (NEED_MFDETECT(i)) { 05544 i->hardwaredtmf = 1; 05545 features |= DSP_FEATURE_DTMF_DETECT; 05546 } 05547 #endif 05548 } 05549 if (features) { 05550 if (i->dsp) { 05551 ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name); 05552 } else { 05553 if (i->channel != CHAN_PSEUDO) 05554 i->dsp = ast_dsp_new(); 05555 else 05556 i->dsp = NULL; 05557 if (i->dsp) { 05558 i->dsp_features = features & ~DSP_PROGRESS_TALK; 05559 #ifdef HAVE_PRI 05560 /* We cannot do progress detection until receives PROGRESS message */ 05561 if (i->outgoing && (i->sig == SIG_PRI)) { 05562 /* Remember requested DSP features, don't treat 05563 talking as ANSWER */ 05564 features = 0; 05565 } 05566 #endif 05567 ast_dsp_set_features(i->dsp, features); 05568 ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 05569 if (!ast_strlen_zero(progzone)) 05570 ast_dsp_set_call_progress_zone(i->dsp, progzone); 05571 if (i->busydetect && CANBUSYDETECT(i)) { 05572 ast_dsp_set_busy_count(i->dsp, i->busycount); 05573 ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength); 05574 } 05575 } 05576 } 05577 } 05578 05579 if (state == AST_STATE_RING) 05580 tmp->rings = 1; 05581 tmp->tech_pvt = i; 05582 #ifdef HAVE_PRI 05583 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS) || (i->sig == SIG_PRI)) { 05584 #else 05585 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 05586 #endif 05587 /* Only FXO signalled stuff can be picked up */ /* i dont think so, mr. ulaw! we alaws like to pick up BRIs/PRIs */ 05588 tmp->callgroup = i->callgroup; 05589 tmp->pickupgroup = i->pickupgroup; 05590 } 05591 if (!ast_strlen_zero(i->language)) 05592 ast_string_field_set(tmp, language, i->language); 05593 if (!i->owner) 05594 i->owner = tmp; 05595 if (!ast_strlen_zero(i->accountcode)) 05596 ast_string_field_set(tmp, accountcode, i->accountcode); 05597 if (i->amaflags) 05598 tmp->amaflags = i->amaflags; 05599 i->subs[index].owner = tmp; 05600 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05601 ast_string_field_set(tmp, call_forward, i->call_forward); 05602 /* If we've been told "no ADSI" then enforce it */ 05603 if (!i->adsi) 05604 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05605 if (!ast_strlen_zero(i->exten)) 05606 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05607 if (!ast_strlen_zero(i->rdnis)) 05608 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05609 if (!ast_strlen_zero(i->dnid)) 05610 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05611 05612 /* Don't use ast_set_callerid() here because it will 05613 * generate a needless NewCallerID event */ 05614 #ifdef PRI_ANI 05615 if (!ast_strlen_zero(i->cid_ani)) 05616 tmp->cid.cid_ani = ast_strdup(i->cid_ani); 05617 else 05618 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05619 #else 05620 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05621 #endif 05622 tmp->cid.cid_pres = i->callingpres; 05623 tmp->cid.cid_ton = i->cid_ton; 05624 #ifdef HAVE_PRI 05625 tmp->transfercapability = transfercapability; 05626 pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability)); 05627 if (transfercapability & PRI_TRANS_CAP_DIGITAL) 05628 i->digital = 1; 05629 /* Assume calls are not idle calls unless we're told differently */ 05630 i->isidlecall = 0; 05631 i->alreadyhungup = 0; 05632 #endif 05633 /* clear the fake event in case we posted one before we had ast_channel */ 05634 i->fake_event = 0; 05635 /* Assure there is no confmute on this channel */ 05636 zt_confmute(i, 0); 05637 /* Configure the new channel jb */ 05638 ast_jb_configure(tmp, &global_jbconf); 05639 if (startpbx) { 05640 if (ast_pbx_start(tmp)) { 05641 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05642 ast_hangup(tmp); 05643 i->owner = NULL; 05644 return NULL; 05645 } 05646 } 05647 05648 ast_module_ref(ast_module_info->self); 05649 05650 return tmp; 05651 }
static int zt_open | ( | char * | fn | ) | [static] |
Definition at line 1050 of file chan_zap.c.
References ast_log(), errno, LOG_WARNING, and READ_SIZE.
Referenced by alloc_sub(), chandup(), and mkintf().
01051 { 01052 int fd; 01053 int isnum; 01054 int chan = 0; 01055 int bs; 01056 int x; 01057 isnum = 1; 01058 for (x = 0; x < strlen(fn); x++) { 01059 if (!isdigit(fn[x])) { 01060 isnum = 0; 01061 break; 01062 } 01063 } 01064 if (isnum) { 01065 chan = atoi(fn); 01066 if (chan < 1) { 01067 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn); 01068 return -1; 01069 } 01070 fn = "/dev/zap/channel"; 01071 } 01072 fd = open(fn, O_RDWR | O_NONBLOCK); 01073 if (fd < 0) { 01074 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno)); 01075 return -1; 01076 } 01077 if (chan) { 01078 if (ioctl(fd, ZT_SPECIFY, &chan)) { 01079 x = errno; 01080 close(fd); 01081 errno = x; 01082 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno)); 01083 return -1; 01084 } 01085 } 01086 bs = READ_SIZE; 01087 if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) { 01088 ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno)); 01089 x = errno; 01090 close(fd); 01091 errno = x; 01092 return -1; 01093 } 01094 return fd; 01095 }
static struct ast_frame * zt_read | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 4896 of file chan_zap.c.
References __zt_exception(), ast_channel::_state, ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_dsp_process(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_callerid(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_subchannel::buffer, zt_pvt::busydetect, zt_pvt::callprogress, zt_pvt::callwaitcas, zt_pvt::callwaitingrepeat, zt_pvt::callwaitrings, zt_pvt::channel, CHECK_BLOCKING, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, ast_frame::data, ast_frame::datalen, ast_frame::delivery, zt_pvt::dialing, zt_pvt::dsp, errno, zt_subchannel::f, zt_pvt::fake_event, zt_pvt::firstradio, ast_frame::frametype, zt_pvt::ignoredtmf, zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needhold, zt_subchannel::needringing, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::oprmode, option_verbose, zt_pvt::outgoing, zt_pvt::overlapdial, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::radio, ast_channel::rawreadformat, READ_SIZE, restore_conference(), ast_channel::rings, zt_pvt::ringt, S_OR, ast_frame::samples, send_callerid(), zt_pvt::sig, SIG_PRI, ast_frame::src, SUB_CALLWAIT, SUB_REAL, ast_frame::subclass, zt_pvt::subs, zt_pvt::tdd, tdd_feed(), ast_channel::tech_pvt, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_callwait(), zt_get_index(), zt_handle_dtmfup(), and zt_setlinear().
04897 { 04898 struct zt_pvt *p = ast->tech_pvt; 04899 int res; 04900 int index; 04901 void *readbuf; 04902 struct ast_frame *f; 04903 04904 04905 ast_mutex_lock(&p->lock); 04906 04907 index = zt_get_index(ast, p, 0); 04908 04909 /* Hang up if we don't really exist */ 04910 if (index < 0) { 04911 ast_log(LOG_WARNING, "We dont exist?\n"); 04912 ast_mutex_unlock(&p->lock); 04913 return NULL; 04914 } 04915 04916 if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL; 04917 04918 p->subs[index].f.frametype = AST_FRAME_NULL; 04919 p->subs[index].f.datalen = 0; 04920 p->subs[index].f.samples = 0; 04921 p->subs[index].f.mallocd = 0; 04922 p->subs[index].f.offset = 0; 04923 p->subs[index].f.subclass = 0; 04924 p->subs[index].f.delivery = ast_tv(0,0); 04925 p->subs[index].f.src = "zt_read"; 04926 p->subs[index].f.data = NULL; 04927 04928 /* make sure it sends initial key state as first frame */ 04929 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio)) 04930 { 04931 ZT_PARAMS ps; 04932 04933 ps.channo = p->channel; 04934 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 04935 ast_mutex_unlock(&p->lock); 04936 return NULL; 04937 } 04938 p->firstradio = 1; 04939 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04940 if (ps.rxisoffhook) 04941 { 04942 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04943 } 04944 else 04945 { 04946 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 04947 } 04948 ast_mutex_unlock(&p->lock); 04949 return &p->subs[index].f; 04950 } 04951 if (p->ringt == 1) { 04952 ast_mutex_unlock(&p->lock); 04953 return NULL; 04954 } 04955 else if (p->ringt > 0) 04956 p->ringt--; 04957 04958 if (p->subs[index].needringing) { 04959 /* Send ringing frame if requested */ 04960 p->subs[index].needringing = 0; 04961 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04962 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04963 ast_setstate(ast, AST_STATE_RINGING); 04964 ast_mutex_unlock(&p->lock); 04965 return &p->subs[index].f; 04966 } 04967 04968 if (p->subs[index].needbusy) { 04969 /* Send busy frame if requested */ 04970 p->subs[index].needbusy = 0; 04971 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04972 p->subs[index].f.subclass = AST_CONTROL_BUSY; 04973 ast_mutex_unlock(&p->lock); 04974 return &p->subs[index].f; 04975 } 04976 04977 if (p->subs[index].needcongestion) { 04978 /* Send congestion frame if requested */ 04979 p->subs[index].needcongestion = 0; 04980 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04981 p->subs[index].f.subclass = AST_CONTROL_CONGESTION; 04982 ast_mutex_unlock(&p->lock); 04983 return &p->subs[index].f; 04984 } 04985 04986 if (p->subs[index].needcallerid) { 04987 ast_set_callerid(ast, S_OR(p->lastcid_num, NULL), 04988 S_OR(p->lastcid_name, NULL), 04989 S_OR(p->lastcid_num, NULL) 04990 ); 04991 p->subs[index].needcallerid = 0; 04992 } 04993 04994 if (p->subs[index].needanswer) { 04995 /* Send answer frame if requested */ 04996 p->subs[index].needanswer = 0; 04997 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04998 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04999 ast_mutex_unlock(&p->lock); 05000 return &p->subs[index].f; 05001 } 05002 05003 if (p->subs[index].needflash) { 05004 /* Send answer frame if requested */ 05005 p->subs[index].needflash = 0; 05006 p->subs[index].f.frametype = AST_FRAME_CONTROL; 05007 p->subs[index].f.subclass = AST_CONTROL_FLASH; 05008 ast_mutex_unlock(&p->lock); 05009 return &p->subs[index].f; 05010 } 05011 05012 if (p->subs[index].needhold) { 05013 /* Send answer frame if requested */ 05014 p->subs[index].needhold = 0; 05015 p->subs[index].f.frametype = AST_FRAME_CONTROL; 05016 p->subs[index].f.subclass = AST_CONTROL_HOLD; 05017 ast_mutex_unlock(&p->lock); 05018 ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name); 05019 return &p->subs[index].f; 05020 } 05021 05022 if (p->subs[index].needunhold) { 05023 /* Send answer frame if requested */ 05024 p->subs[index].needunhold = 0; 05025 p->subs[index].f.frametype = AST_FRAME_CONTROL; 05026 p->subs[index].f.subclass = AST_CONTROL_UNHOLD; 05027 ast_mutex_unlock(&p->lock); 05028 ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name); 05029 return &p->subs[index].f; 05030 } 05031 05032 if (ast->rawreadformat == AST_FORMAT_SLINEAR) { 05033 if (!p->subs[index].linear) { 05034 p->subs[index].linear = 1; 05035 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05036 if (res) 05037 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index); 05038 } 05039 } else if ((ast->rawreadformat == AST_FORMAT_ULAW) || 05040 (ast->rawreadformat == AST_FORMAT_ALAW)) { 05041 if (p->subs[index].linear) { 05042 p->subs[index].linear = 0; 05043 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05044 if (res) 05045 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index); 05046 } 05047 } else { 05048 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat)); 05049 ast_mutex_unlock(&p->lock); 05050 return NULL; 05051 } 05052 readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET; 05053 CHECK_BLOCKING(ast); 05054 res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 05055 ast_clear_flag(ast, AST_FLAG_BLOCKING); 05056 /* Check for hangup */ 05057 if (res < 0) { 05058 f = NULL; 05059 if (res == -1) { 05060 if (errno == EAGAIN) { 05061 /* Return "NULL" frame if there is nobody there */ 05062 ast_mutex_unlock(&p->lock); 05063 return &p->subs[index].f; 05064 } else if (errno == ELAST) { 05065 f = __zt_exception(ast); 05066 } else 05067 ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno)); 05068 } 05069 ast_mutex_unlock(&p->lock); 05070 return f; 05071 } 05072 if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) { 05073 ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 05074 f = __zt_exception(ast); 05075 ast_mutex_unlock(&p->lock); 05076 return f; 05077 } 05078 if (p->tdd) { /* if in TDD mode, see if we receive that */ 05079 int c; 05080 05081 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 05082 if (c < 0) { 05083 ast_log(LOG_DEBUG,"tdd_feed failed\n"); 05084 ast_mutex_unlock(&p->lock); 05085 return NULL; 05086 } 05087 if (c) { /* if a char to return */ 05088 p->subs[index].f.subclass = 0; 05089 p->subs[index].f.frametype = AST_FRAME_TEXT; 05090 p->subs[index].f.mallocd = 0; 05091 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 05092 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET; 05093 p->subs[index].f.datalen = 1; 05094 *((char *) p->subs[index].f.data) = c; 05095 ast_mutex_unlock(&p->lock); 05096 return &p->subs[index].f; 05097 } 05098 } 05099 if (p->callwaitingrepeat) 05100 p->callwaitingrepeat--; 05101 if (p->cidcwexpire) 05102 p->cidcwexpire--; 05103 /* Repeat callwaiting */ 05104 if (p->callwaitingrepeat == 1) { 05105 p->callwaitrings++; 05106 zt_callwait(ast); 05107 } 05108 /* Expire CID/CW */ 05109 if (p->cidcwexpire == 1) { 05110 if (option_verbose > 2) 05111 ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n"); 05112 restore_conference(p); 05113 } 05114 if (p->subs[index].linear) { 05115 p->subs[index].f.datalen = READ_SIZE * 2; 05116 } else 05117 p->subs[index].f.datalen = READ_SIZE; 05118 05119 /* Handle CallerID Transmission */ 05120 if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) { 05121 send_callerid(p); 05122 } 05123 05124 p->subs[index].f.frametype = AST_FRAME_VOICE; 05125 p->subs[index].f.subclass = ast->rawreadformat; 05126 p->subs[index].f.samples = READ_SIZE; 05127 p->subs[index].f.mallocd = 0; 05128 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 05129 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]); 05130 #if 0 05131 ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name); 05132 #endif 05133 if (p->dialing || /* Transmitting something */ 05134 (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 05135 ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 05136 ) { 05137 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 05138 don't send anything */ 05139 p->subs[index].f.frametype = AST_FRAME_NULL; 05140 p->subs[index].f.subclass = 0; 05141 p->subs[index].f.samples = 0; 05142 p->subs[index].f.mallocd = 0; 05143 p->subs[index].f.offset = 0; 05144 p->subs[index].f.data = NULL; 05145 p->subs[index].f.datalen= 0; 05146 } 05147 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) { 05148 /* Perform busy detection. etc on the zap line */ 05149 f = ast_dsp_process(ast, p->dsp, &p->subs[index].f); 05150 if (f) { 05151 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) { 05152 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 05153 /* Treat this as a "hangup" instead of a "busy" on the assumption that 05154 a busy */ 05155 f = NULL; 05156 } 05157 } else if (f->frametype == AST_FRAME_DTMF) { 05158 #ifdef HAVE_PRI 05159 if (p->sig==SIG_PRI && p->pri && p->pri->overlapdial && p->ignoredtmf) { 05160 /* Don't accept in-band DTMF when in overlap dial mode 05161 or when in non-overlap overlapdialing mode ... */ 05162 f->frametype = AST_FRAME_NULL; 05163 f->subclass = 0; 05164 } 05165 #endif 05166 /* DSP clears us of being pulse */ 05167 p->pulsedial = 0; 05168 } 05169 } 05170 } else 05171 f = &p->subs[index].f; 05172 05173 if (f && (f->frametype == AST_FRAME_DTMF)) 05174 zt_handle_dtmfup(ast, index, &f); 05175 05176 /* If we have a fake_event, trigger exception to handle it */ 05177 if (p->fake_event) 05178 ast_set_flag(ast, AST_FLAG_EXCEPTION); 05179 05180 ast_mutex_unlock(&p->lock); 05181 return f; 05182 }
static struct ast_channel * zt_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
Definition at line 8122 of file chan_zap.c.
References alloc_sub(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CDR_CALLWAIT, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RESERVED, ast_strdupa, AST_TRANS_CAP_3_1K_AUDIO, AST_TRANS_CAP_DIGITAL, ast_verbose(), available(), busy, ast_channel::cdrflags, CHAN_PSEUDO, chandup(), zt_pvt::channel, zt_pvt::confirmanswer, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::faxhandled, iflist, zt_pvt::inalarm, lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, zt_pvt::next, option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::prev, restart_monitor(), s, zt_pvt::sig, SIG_FXSKS, strsep(), SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::transfercapability, zt_subchannel::zfd, and zt_new().
08123 { 08124 int groupmatch = 0; 08125 int channelmatch = -1; 08126 int roundrobin = 0; 08127 int callwait = 0; 08128 int busy = 0; 08129 struct zt_pvt *p; 08130 struct ast_channel *tmp = NULL; 08131 char *dest=NULL; 08132 int x; 08133 char *s; 08134 char opt=0; 08135 int res=0, y=0; 08136 int backwards = 0; 08137 #ifdef HAVE_PRI 08138 int crv; 08139 int bearer = -1; 08140 int trunkgroup; 08141 struct zt_pri *pri=NULL; 08142 #endif 08143 struct zt_pvt *exit, *start, *end; 08144 ast_mutex_t *lock; 08145 int channelmatched = 0; 08146 int groupmatched = 0; 08147 08148 /* Assume we're locking the iflock */ 08149 lock = &iflock; 08150 start = iflist; 08151 end = ifend; 08152 if (data) { 08153 dest = ast_strdupa((char *)data); 08154 } else { 08155 ast_log(LOG_WARNING, "Channel requested with no data\n"); 08156 return NULL; 08157 } 08158 if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') { 08159 /* Retrieve the group number */ 08160 char *stringp=NULL; 08161 stringp=dest + 1; 08162 s = strsep(&stringp, "/"); 08163 if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 08164 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data); 08165 return NULL; 08166 } 08167 groupmatch = 1 << x; 08168 if (toupper(dest[0]) == 'G') { 08169 if (dest[0] == 'G') { 08170 backwards = 1; 08171 p = ifend; 08172 } else 08173 p = iflist; 08174 } else { 08175 if (dest[0] == 'R') { 08176 backwards = 1; 08177 p = round_robin[x]?round_robin[x]->prev:ifend; 08178 if (!p) 08179 p = ifend; 08180 } else { 08181 p = round_robin[x]?round_robin[x]->next:iflist; 08182 if (!p) 08183 p = iflist; 08184 } 08185 roundrobin = 1; 08186 } 08187 } else { 08188 char *stringp=NULL; 08189 stringp=dest; 08190 s = strsep(&stringp, "/"); 08191 p = iflist; 08192 if (!strcasecmp(s, "pseudo")) { 08193 /* Special case for pseudo */ 08194 x = CHAN_PSEUDO; 08195 channelmatch = x; 08196 } 08197 #ifdef HAVE_PRI 08198 else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) { 08199 if ((trunkgroup < 1) || (crv < 1)) { 08200 ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data); 08201 return NULL; 08202 } 08203 res--; 08204 for (x = 0; x < NUM_SPANS; x++) { 08205 if (pris[x].trunkgroup == trunkgroup) { 08206 pri = pris + x; 08207 lock = &pri->lock; 08208 start = pri->crvs; 08209 end = pri->crvend; 08210 break; 08211 } 08212 } 08213 if (!pri) { 08214 ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup); 08215 return NULL; 08216 } 08217 channelmatch = crv; 08218 p = pris[x].crvs; 08219 } 08220 #endif 08221 else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 08222 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data); 08223 return NULL; 08224 } else { 08225 channelmatch = x; 08226 } 08227 } 08228 /* Search for an unowned channel */ 08229 ast_mutex_lock(lock); 08230 exit = p; 08231 while (p && !tmp) { 08232 if (roundrobin) 08233 round_robin[x] = p; 08234 #if 0 08235 ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch); 08236 #endif 08237 08238 if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) { 08239 if (option_debug) 08240 ast_log(LOG_DEBUG, "Using channel %d\n", p->channel); 08241 if (p->inalarm) 08242 goto next; 08243 08244 callwait = (p->owner != NULL); 08245 #ifdef HAVE_PRI 08246 if (pri && (p->subs[SUB_REAL].zfd < 0)) { 08247 if (p->sig != SIG_FXSKS) { 08248 /* Gotta find an actual channel to use for this 08249 CRV if this isn't a callwait */ 08250 bearer = pri_find_empty_chan(pri, 0); 08251 if (bearer < 0) { 08252 ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv); 08253 p = NULL; 08254 break; 08255 } 08256 pri_assign_bearer(p, pri, pri->pvts[bearer]); 08257 } else { 08258 if (alloc_sub(p, 0)) { 08259 ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n"); 08260 p = NULL; 08261 break; 08262 } else 08263 ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n"); 08264 p->pri = pri; 08265 } 08266 } 08267 #endif 08268 if (p->channel == CHAN_PSEUDO) { 08269 p = chandup(p); 08270 if (!p) { 08271 break; 08272 } 08273 } 08274 if (p->owner) { 08275 if (alloc_sub(p, SUB_CALLWAIT)) { 08276 p = NULL; 08277 break; 08278 } 08279 } 08280 p->outgoing = 1; 08281 tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0); 08282 #ifdef HAVE_PRI 08283 if (p->bearer) { 08284 /* Log owner to bearer channel, too */ 08285 p->bearer->owner = tmp; 08286 } 08287 #endif 08288 /* Make special notes */ 08289 if (res > 1) { 08290 if (opt == 'c') { 08291 /* Confirm answer */ 08292 p->confirmanswer = 1; 08293 } else if (opt == 'r') { 08294 /* Distinctive ring */ 08295 if (res < 3) 08296 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data); 08297 else 08298 p->distinctivering = y; 08299 } else if (opt == 'd') { 08300 /* If this is an ISDN call, make it digital */ 08301 p->digital = 1; 08302 if (tmp) 08303 tmp->transfercapability = AST_TRANS_CAP_DIGITAL; 08304 } else if (opt == 'm') { 08305 /* If this is a modem/fax call, pretend to have the fax handled and dont do EC */ 08306 p->faxhandled = 1; 08307 if (tmp) 08308 tmp->transfercapability = AST_TRANS_CAP_3_1K_AUDIO; 08309 } else { 08310 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data); 08311 } 08312 } 08313 /* Note if the call is a call waiting call */ 08314 if (tmp && callwait) 08315 tmp->cdrflags |= AST_CDR_CALLWAIT; 08316 break; 08317 } 08318 next: 08319 if (backwards) { 08320 p = p->prev; 08321 if (!p) 08322 p = end; 08323 } else { 08324 p = p->next; 08325 if (!p) 08326 p = start; 08327 } 08328 /* stop when you roll to the one that we started from */ 08329 if (p == exit) 08330 break; 08331 } 08332 ast_mutex_unlock(lock); 08333 restart_monitor(); 08334 if (callwait) 08335 *cause = AST_CAUSE_BUSY; 08336 else if (!tmp) { 08337 if (channelmatched) { 08338 if (busy) 08339 *cause = AST_CAUSE_BUSY; 08340 } else if (groupmatched) { 08341 *cause = AST_CAUSE_CONGESTION; 08342 } else { 08343 *cause = AST_CAUSE_CONGESTION; 08344 } 08345 } 08346 08347 return tmp; 08348 }
static int zt_ring_phone | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3743 of file chan_zap.c.
References ast_log(), errno, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), and zt_handle_event().
03744 { 03745 int x; 03746 int res; 03747 /* Make sure our transmit state is on hook */ 03748 x = 0; 03749 x = ZT_ONHOOK; 03750 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03751 do { 03752 x = ZT_RING; 03753 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03754 if (res) { 03755 switch (errno) { 03756 case EBUSY: 03757 case EINTR: 03758 /* Wait just in case */ 03759 usleep(10000); 03760 continue; 03761 case EINPROGRESS: 03762 res = 0; 03763 break; 03764 default: 03765 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 03766 res = 0; 03767 } 03768 } 03769 } while (res); 03770 return res; 03771 }
static int zt_sendtext | ( | struct ast_channel * | c, | |
const char * | dest, | |||
const char * | text, | |||
int | ispdu | |||
) | [static] |
Definition at line 13249 of file chan_zap.c.
References ast_log(), LOG_WARNING, zt_pvt::sig, SIG_GSM, SIG_PRI, ast_channel::tech_pvt, and zt_tdd_sendtext().
13249 { 13250 struct zt_pvt *p = c->tech_pvt; 13251 if (!p) return -1; 13252 if (p->sig == SIG_PRI) { 13253 #ifdef HAVE_PRI 13254 if (ispdu) { 13255 ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP ISDN channel\n"); 13256 return -1; 13257 } 13258 return zt_pri_sendtext(c, text); 13259 #endif 13260 } else if (p->sig == SIG_GSM) { 13261 #ifdef HAVE_GSMAT 13262 return zt_gsm_sendtext(c, dest, text, ispdu); 13263 #endif 13264 } else { 13265 return zt_tdd_sendtext(c, text); 13266 } 13267 return -1; 13268 }
static int zt_set_hook | ( | int | fd, | |
int | hs | |||
) | [inline, static] |
Definition at line 1799 of file chan_zap.c.
References ast_log(), errno, and LOG_WARNING.
Referenced by __zt_exception(), handle_init_event(), mkintf(), ss_thread(), zt_answer(), zt_handle_event(), zt_hangup(), zt_indicate(), and zt_wink().
01800 { 01801 int x, res; 01802 01803 x = hs; 01804 res = ioctl(fd, ZT_HOOK, &x); 01805 01806 if (res < 0) { 01807 if (errno == EINPROGRESS) 01808 return 0; 01809 ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno)); 01810 } 01811 01812 return res; 01813 }
static int zt_setlaw | ( | int | zfd, | |
int | law | |||
) | [static] |
Definition at line 2632 of file chan_zap.c.
02633 { 02634 int res; 02635 res = ioctl(zfd, ZT_SETLAW, &law); 02636 if (res) 02637 return res; 02638 return 0; 02639 }
static int zt_setlinear | ( | int | zfd, | |
int | linear | |||
) | [static] |
Definition at line 1103 of file chan_zap.c.
Referenced by send_callerid(), ss_thread(), zt_hangup(), zt_new(), zt_read(), and zt_write().
01104 { 01105 int res; 01106 res = ioctl(zfd, ZT_SETLINEAR, &linear); 01107 if (res) 01108 return res; 01109 return 0; 01110 }
static int zt_setoption | ( | struct ast_channel * | chan, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3093 of file chan_zap.c.
References ast_check_hangup(), ast_dsp_digitmode(), ast_log(), AST_OPTION_AUDIO_MODE, AST_OPTION_ECHOCAN, AST_OPTION_OPRMODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_tdd_gen_ecdisa(), zt_pvt::channel, zt_pvt::didtdd, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_DIGITMODE_RELAXDTMF, zt_pvt::dtmfrelax, errno, pollfd::events, pollfd::fd, zt_pvt::law, len, LOG_DEBUG, LOG_WARNING, zt_pvt::mate, oprmode::mode, zt_pvt::oprmode, zt_pvt::oprpeer, option_debug, oprmode::peer, poll(), POLLOUT, POLLPRI, READ_SIZE, pollfd::revents, zt_pvt::rxgain, set_actual_rxgain(), set_actual_txgain(), SUB_REAL, zt_pvt::subs, zt_pvt::tdd, tdd_free(), tdd_new(), ast_channel::tech_pvt, zt_pvt::txgain, zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), and zt_get_index().
03094 { 03095 char *cp; 03096 signed char *scp; 03097 int x; 03098 int index; 03099 struct zt_pvt *p = chan->tech_pvt, *pp; 03100 struct oprmode *oprmode; 03101 03102 03103 /* all supported options require data */ 03104 if (!data || (datalen < 1)) { 03105 errno = EINVAL; 03106 return -1; 03107 } 03108 03109 switch (option) { 03110 case AST_OPTION_TXGAIN: 03111 scp = (signed char *) data; 03112 index = zt_get_index(chan, p, 0); 03113 if (index < 0) { 03114 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 03115 return -1; 03116 } 03117 if (option_debug) 03118 ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp); 03119 return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law); 03120 case AST_OPTION_RXGAIN: 03121 scp = (signed char *) data; 03122 index = zt_get_index(chan, p, 0); 03123 if (index < 0) { 03124 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 03125 return -1; 03126 } 03127 if (option_debug) 03128 ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp); 03129 return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law); 03130 case AST_OPTION_TONE_VERIFY: 03131 if (!p->dsp) 03132 break; 03133 cp = (char *) data; 03134 switch (*cp) { 03135 case 1: 03136 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name); 03137 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 03138 break; 03139 case 2: 03140 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name); 03141 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 03142 break; 03143 default: 03144 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name); 03145 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 03146 break; 03147 } 03148 break; 03149 case AST_OPTION_TDD: 03150 /* turn on or off TDD */ 03151 cp = (char *) data; 03152 p->mate = 0; 03153 if (!*cp) { /* turn it off */ 03154 if (option_debug) 03155 ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name); 03156 if (p->tdd) 03157 tdd_free(p->tdd); 03158 p->tdd = 0; 03159 break; 03160 } 03161 ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n", 03162 (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name); 03163 zt_disable_ec(p); 03164 /* otherwise, turn it on */ 03165 if (!p->didtdd) { /* if havent done it yet */ 03166 unsigned char mybuf[41000], *buf; 03167 int size, res, fd, len; 03168 struct pollfd fds[1]; 03169 03170 buf = mybuf; 03171 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 03172 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 03173 len = 40000; 03174 index = zt_get_index(chan, p, 0); 03175 if (index < 0) { 03176 ast_log(LOG_WARNING, "No index in TDD?\n"); 03177 return -1; 03178 } 03179 fd = p->subs[index].zfd; 03180 while (len) { 03181 if (ast_check_hangup(chan)) 03182 return -1; 03183 size = len; 03184 if (size > READ_SIZE) 03185 size = READ_SIZE; 03186 fds[0].fd = fd; 03187 fds[0].events = POLLPRI | POLLOUT; 03188 fds[0].revents = 0; 03189 res = poll(fds, 1, -1); 03190 if (!res) { 03191 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 03192 continue; 03193 } 03194 /* if got exception */ 03195 if (fds[0].revents & POLLPRI) 03196 return -1; 03197 if (!(fds[0].revents & POLLOUT)) { 03198 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 03199 continue; 03200 } 03201 res = write(fd, buf, size); 03202 if (res != size) { 03203 if (res == -1) return -1; 03204 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 03205 break; 03206 } 03207 len -= size; 03208 buf += size; 03209 } 03210 p->didtdd = 1; /* set to have done it now */ 03211 } 03212 if (*cp == 2) { /* Mate mode */ 03213 if (p->tdd) 03214 tdd_free(p->tdd); 03215 p->tdd = 0; 03216 p->mate = 1; 03217 break; 03218 } 03219 if (!p->tdd) { /* if we dont have one yet */ 03220 p->tdd = tdd_new(); /* allocate one */ 03221 } 03222 break; 03223 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 03224 if (!p->dsp) 03225 break; 03226 cp = (char *) data; 03227 ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n", 03228 *cp ? "ON" : "OFF", (int) *cp, chan->name); 03229 p->dtmfrelax = 0; 03230 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 03231 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 03232 break; 03233 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 03234 cp = (char *) data; 03235 if (!*cp) { 03236 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name); 03237 x = 0; 03238 zt_disable_ec(p); 03239 } else { 03240 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name); 03241 x = 1; 03242 } 03243 if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1) 03244 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x); 03245 break; 03246 case AST_OPTION_OPRMODE: /* Operator services mode */ 03247 oprmode = (struct oprmode *) data; 03248 pp = oprmode->peer->tech_pvt; 03249 p->oprmode = pp->oprmode = 0; 03250 /* setup peers */ 03251 p->oprpeer = pp; 03252 pp->oprpeer = p; 03253 /* setup modes, if any */ 03254 if (oprmode->mode) 03255 { 03256 pp->oprmode = oprmode->mode; 03257 p->oprmode = -oprmode->mode; 03258 } 03259 ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n", 03260 oprmode->mode, chan->name,oprmode->peer->name);; 03261 break; 03262 case AST_OPTION_ECHOCAN: 03263 cp = (char *) data; 03264 if (*cp) { 03265 ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name); 03266 zt_enable_ec(p); 03267 } else { 03268 ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name); 03269 zt_disable_ec(p); 03270 } 03271 break; 03272 } 03273 errno = 0; 03274 03275 return 0; 03276 }
static int zt_tdd_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 13270 of file chan_zap.c.
References ASCII_BYTES_PER_CHAR, ast_check_hangup(), ast_free, AST_LAW, ast_log(), ast_malloc, zt_pvt::channel, END_SILENCE_LEN, errno, pollfd::events, pollfd::fd, free, HEADER_LEN, HEADER_MS, LOG_DEBUG, LOG_ERROR, LOG_WARNING, zt_pvt::mate, option_debug, poll(), POLLOUT, PUT_CLID, PUT_CLID_MARKMS, READ_SIZE, pollfd::revents, zt_pvt::subs, zt_pvt::tdd, TDD_BYTES_PER_CHAR, tdd_generate(), ast_channel::tech_pvt, TRAILER_MS, zt_subchannel::zfd, and zt_get_index().
Referenced by zt_sendtext().
13271 { 13272 #define END_SILENCE_LEN 400 13273 #define HEADER_MS 50 13274 #define TRAILER_MS 5 13275 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 13276 #define ASCII_BYTES_PER_CHAR 80 13277 13278 unsigned char *buf,*mybuf; 13279 struct zt_pvt *p = c->tech_pvt; 13280 struct pollfd fds[1]; 13281 int size,res,fd,len,x; 13282 int bytes=0; 13283 /* Initial carrier (imaginary) */ 13284 float cr = 1.0; 13285 float ci = 0.0; 13286 float scont = 0.0; 13287 int index; 13288 13289 13290 index = zt_get_index(c, p, 0); 13291 if (index < 0) { 13292 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 13293 return -1; 13294 } 13295 if (!text[0]) return(0); /* if nothing to send, dont */ 13296 if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ 13297 if (p->mate) 13298 buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 13299 else 13300 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 13301 if (!buf) 13302 return -1; 13303 mybuf = buf; 13304 if (p->mate) { 13305 int codec = AST_LAW(p); 13306 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */ 13307 PUT_CLID_MARKMS; 13308 } 13309 /* Put actual message */ 13310 for (x = 0; text[x]; x++) { 13311 PUT_CLID(text[x]); 13312 } 13313 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */ 13314 PUT_CLID_MARKMS; 13315 } 13316 len = bytes; 13317 buf = mybuf; 13318 } else { 13319 len = tdd_generate(p->tdd, buf, text); 13320 if (len < 1) { 13321 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text)); 13322 free(mybuf); 13323 return -1; 13324 } 13325 } 13326 memset(buf + len, 0x7f, END_SILENCE_LEN); 13327 len += END_SILENCE_LEN; 13328 fd = p->subs[index].zfd; 13329 while (len) { 13330 if (ast_check_hangup(c)) { 13331 free(mybuf); 13332 return -1; 13333 } 13334 size = len; 13335 if (size > READ_SIZE) 13336 size = READ_SIZE; 13337 fds[0].fd = fd; 13338 fds[0].events = POLLOUT | POLLPRI; 13339 fds[0].revents = 0; 13340 res = poll(fds, 1, -1); 13341 if (!res) { 13342 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 13343 continue; 13344 } 13345 /* if got exception */ 13346 if (fds[0].revents & POLLPRI) { 13347 ast_free(mybuf); 13348 return -1; 13349 } 13350 if (!(fds[0].revents & POLLOUT)) { 13351 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 13352 continue; 13353 } 13354 res = write(fd, buf, size); 13355 if (res != size) { 13356 if (res == -1) { 13357 free(mybuf); 13358 return -1; 13359 } 13360 if (option_debug) 13361 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 13362 break; 13363 } 13364 len -= size; 13365 buf += size; 13366 } 13367 free(mybuf); 13368 return(0); 13369 }
static void zt_train_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1631 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::digital, zt_pvt::echocancel, zt_pvt::echotraining, zt_pvt::faxhandled, LOG_DEBUG, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_answer(), and zt_handle_event().
01632 { 01633 int x; 01634 int res; 01635 if (p && p->echocancel && p->echotraining && (!p->digital) && (!p->faxhandled)) { 01636 x = p->echotraining; 01637 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x); 01638 if (res) 01639 ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel); 01640 else { 01641 ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel); 01642 } 01643 } else 01644 ast_log(LOG_DEBUG, "No echo training requested\n"); 01645 }
Definition at line 3297 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), zt_pvt::channel, conf_del(), zt_pvt::inconference, zt_pvt::lock, LOG_DEBUG, zt_pvt::master, MAX_SLAVES, zt_pvt::slaves, SUB_REAL, zt_pvt::subs, and update_conf().
Referenced by zt_bridge(), and zt_fixup().
03298 { 03299 /* Unlink a specific slave or all slaves/masters from a given master */ 03300 int x; 03301 int hasslaves; 03302 if (!master) 03303 return; 03304 if (needlock) { 03305 ast_mutex_lock(&master->lock); 03306 if (slave) { 03307 while (ast_mutex_trylock(&slave->lock)) { 03308 ast_mutex_unlock(&master->lock); 03309 usleep(1); 03310 ast_mutex_lock(&master->lock); 03311 } 03312 } 03313 } 03314 hasslaves = 0; 03315 for (x = 0; x < MAX_SLAVES; x++) { 03316 if (master->slaves[x]) { 03317 if (!slave || (master->slaves[x] == slave)) { 03318 /* Take slave out of the conference */ 03319 ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 03320 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 03321 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 03322 master->slaves[x]->master = NULL; 03323 master->slaves[x] = NULL; 03324 } else 03325 hasslaves = 1; 03326 } 03327 if (!hasslaves) 03328 master->inconference = 0; 03329 } 03330 if (!slave) { 03331 if (master->master) { 03332 /* Take master out of the conference */ 03333 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 03334 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 03335 hasslaves = 0; 03336 for (x = 0; x < MAX_SLAVES; x++) { 03337 if (master->master->slaves[x] == master) 03338 master->master->slaves[x] = NULL; 03339 else if (master->master->slaves[x]) 03340 hasslaves = 1; 03341 } 03342 if (!hasslaves) 03343 master->master->inconference = 0; 03344 } 03345 master->master = NULL; 03346 } 03347 update_conf(master); 03348 if (needlock) { 03349 if (slave) 03350 ast_mutex_unlock(&slave->lock); 03351 ast_mutex_unlock(&master->lock); 03352 } 03353 }
static int zt_wait_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_waitevent which ignores a bunch of events.
Definition at line 273 of file chan_zap.c.
Referenced by flash_exec(), and ss_thread().
00274 { 00275 int i, j = 0; 00276 i = ZT_IOMUX_SIGEVENT; 00277 if (ioctl(fd, ZT_IOMUX, &i) == -1) 00278 return -1; 00279 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00280 return -1; 00281 return j; 00282 }
static int zt_wink | ( | struct zt_pvt * | p, | |
int | index | |||
) | [static] |
Definition at line 5673 of file chan_zap.c.
References zt_pvt::subs, zt_subchannel::zfd, and zt_set_hook().
Referenced by ss_thread().
05674 { 05675 int j; 05676 zt_set_hook(p->subs[index].zfd, ZT_WINK); 05677 for (;;) 05678 { 05679 /* set bits of interest */ 05680 j = ZT_IOMUX_SIGEVENT; 05681 /* wait for some happening */ 05682 if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1); 05683 /* exit loop if we have it */ 05684 if (j & ZT_IOMUX_SIGEVENT) break; 05685 } 05686 /* get the event info */ 05687 if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1); 05688 return 0; 05689 }
static int zt_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 5207 of file chan_zap.c.
References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::channel, zt_pvt::cidspill, ast_frame::data, ast_frame::datalen, zt_pvt::dialing, zt_pvt::digital, errno, ast_frame::frametype, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, my_zt_write(), option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::sig, SIG_PRI, zt_pvt::span, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_setlinear().
05208 { 05209 struct zt_pvt *p = ast->tech_pvt; 05210 int res; 05211 int index; 05212 index = zt_get_index(ast, p, 0); 05213 if (index < 0) { 05214 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name); 05215 return -1; 05216 } 05217 05218 #if 0 05219 #ifdef HAVE_PRI 05220 ast_mutex_lock(&p->lock); 05221 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05222 if (p->pri->pri) { 05223 if (!pri_grab(p, p->pri)) { 05224 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05225 pri_rel(p->pri); 05226 } else 05227 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05228 } 05229 p->proceeding=1; 05230 } 05231 ast_mutex_unlock(&p->lock); 05232 #endif 05233 #endif 05234 /* Write a frame of (presumably voice) data */ 05235 if (frame->frametype != AST_FRAME_VOICE) { 05236 if (frame->frametype == AST_FRAME_TEXT) { 05237 ast_log(LOG_NOTICE, "text\n"); 05238 } else if (frame->frametype != AST_FRAME_IMAGE) 05239 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 05240 return 0; 05241 } 05242 if ((frame->subclass != AST_FORMAT_SLINEAR) && 05243 (frame->subclass != AST_FORMAT_ULAW) && 05244 (frame->subclass != AST_FORMAT_ALAW)) { 05245 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass); 05246 return -1; 05247 } 05248 if (p->dialing) { 05249 if (option_debug) 05250 ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name); 05251 return 0; 05252 } 05253 if (!p->owner) { 05254 if (option_debug) 05255 ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name); 05256 return 0; 05257 } 05258 if (p->cidspill) { 05259 if (option_debug) 05260 ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n"); 05261 return 0; 05262 } 05263 /* Return if it's not valid data */ 05264 if (!frame->data || !frame->datalen) 05265 return 0; 05266 05267 if (frame->subclass == AST_FORMAT_SLINEAR) { 05268 if (!p->subs[index].linear) { 05269 p->subs[index].linear = 1; 05270 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05271 if (res) 05272 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 05273 } 05274 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1); 05275 } else { 05276 /* x-law already */ 05277 if (p->subs[index].linear) { 05278 p->subs[index].linear = 0; 05279 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 05280 if (res) 05281 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 05282 } 05283 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0); 05284 } 05285 if (res < 0) { 05286 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 05287 return -1; 05288 } 05289 return 0; 05290 }
int alarm |
struct { ... } alarms[] [static] |
Referenced by alarm2str(), and zap_show_status().
struct zt_ring_cadence cadences[NUM_CADENCE_MAX] [static] |
Definition at line 812 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 823 of file chan_zap.c.
const char config[] = "zapata.conf" [static] |
Definition at line 175 of file chan_zap.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 119 of file chan_zap.c.
char defaultcic[64] = "" [static] |
Definition at line 215 of file chan_zap.c.
char defaultozz[64] = "" [static] |
Definition at line 216 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 11922 of file chan_zap.c.
int distinctiveringaftercid = 0 [static] |
Definition at line 220 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 126 of file chan_zap.c.
char gsm_modem_exten[AST_MAX_EXTENSION] [static] |
Definition at line 244 of file chan_zap.c.
char gsm_modem_pin[20] [static] |
Definition at line 243 of file chan_zap.c.
int ifcount = 0 [static] |
Definition at line 246 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 238 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 254 of file chan_zap.c.
char* name |
Definition at line 1304 of file chan_zap.c.
int num_cadence = 4 [static] |
Definition at line 809 of file chan_zap.c.
int numbufs = 4 [static] |
Definition at line 222 of file chan_zap.c.
char progzone[10] = "" [static] |
Definition at line 218 of file chan_zap.c.
int ringt_base = DEFAULT_RINGT [static] |
Definition at line 298 of file chan_zap.c.
struct zt_pvt* round_robin[32] |
Definition at line 779 of file chan_zap.c.
char show_channel_usage[] [static] |
Initial value:
"Usage: zap show channel <chan num>\n" " Detailed information about a given channel\n"
Definition at line 11914 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 11910 of file chan_zap.c.
char* subnames[] [static] |
const char tdesc[] = "Zapata Telephony Driver" [static] |
Definition at line 169 of file chan_zap.c.
int user_has_defined_cadences = 0 [static] |
Definition at line 810 of file chan_zap.c.
struct ast_cli_entry zap_cli[] [static] |
Definition at line 11933 of file chan_zap.c.
char zap_restart_usage[] [static] |
Definition at line 11926 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 11818 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 11918 of file chan_zap.c.
struct ast_channel_tech zap_tech [static] |
Definition at line 751 of file chan_zap.c.
char* zapEC_app = "zapEC" [static] |
Definition at line 11571 of file chan_zap.c.
char* zapEC_synopsis = "Enable/Disable Echo Cancelation on a Zap channel" [static] |
Definition at line 11572 of file chan_zap.c.
char* zapEC_tdesc = "Enable/disable Echo cancelation" [static] |
Definition at line 11570 of file chan_zap.c.