#include "asterisk.h"
#include <stdio.h>
#include <string.h>
#include <sys/signal.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <math.h>
#include <ctype.h>
#include <zaptel/zaptel.h>
#include <zaptel/tonezone.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/file.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/adsi.h"
#include "asterisk/cli.h"
#include "asterisk/cdr.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/tdd.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
#include "asterisk/causes.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/transcap.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj.h"
Include dependency graph for chan_zap.c:

Go to the source code of this file.
Data Structures | |
| struct | distRingData |
| struct | ringContextData |
| struct | zt_chan_conf |
| Channel configuration from zapata.conf . This struct is used for parsing the [channels] section of zapata.conf. Generally there is a field here for every possible configuration item. More... | |
| struct | zt_distRings |
| struct | zt_pvt |
| struct | zt_subchannel |
Defines | |
| #define | ASCII_BYTES_PER_CHAR 80 |
| #define | AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
| #define | CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
| #define | CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
| #define | CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
| #define | CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
| #define | CHAN_PSEUDO -2 |
| #define | CHANNEL_PSEUDO -12 |
| #define | CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
| #define | CONF_USER_REAL (1 << 0) |
| #define | CONF_USER_THIRDCALL (1 << 1) |
| #define | DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
| #define | DCHAN_NOTINALARM (1 << 1) |
| #define | DCHAN_PROVISIONED (1 << 0) |
| #define | DCHAN_UP (1 << 2) |
| #define | DEFAULT_CIDRINGS 1 |
| Typically, how many rings before we should send Caller*ID. | |
| #define | DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
| #define | END_SILENCE_LEN 400 |
| #define | FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" |
| #define | FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
| #define | FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" |
| #define | FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
| #define | GET_CHANNEL(p) ((p)->channel) |
| #define | HANGUP 1 |
| #define | HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
| #define | HEADER_MS 50 |
| #define | ISTRUNK(p) |
| #define | MASK_AVAIL (1 << 0) |
| #define | MASK_INUSE (1 << 1) |
| #define | MAX_CHANLIST_LEN 80 |
| #define | MAX_CHANNELS 672 |
| #define | MAX_SLAVES 4 |
| #define | MIN_MS_SINCE_FLASH ( (2000) ) |
| #define | NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) |
| Signaling types that need to use MF detection should be placed in this macro. | |
| #define | NUM_CADENCE_MAX 25 |
| #define | NUM_DCHANS 4 |
| #define | NUM_SPANS 32 |
| #define | POLARITY_IDLE 0 |
| #define | POLARITY_REV 1 |
| #define | READ_SIZE 160 |
| #define | sig2str zap_sig2str |
| #define | SIG_E911 (0x1000000 | ZT_SIG_EM) |
| #define | SIG_EM ZT_SIG_EM |
| #define | SIG_EM_E1 ZT_SIG_EM_E1 |
| #define | SIG_EMWINK (0x0100000 | ZT_SIG_EM) |
| #define | SIG_FEATB (0x0800000 | ZT_SIG_EM) |
| #define | SIG_FEATD (0x0200000 | ZT_SIG_EM) |
| #define | SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
| #define | SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM) |
| #define | SIG_FGC_CAMA (0x4000000 | ZT_SIG_EM) |
| #define | SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM) |
| #define | SIG_FXOGS ZT_SIG_FXOGS |
| #define | SIG_FXOKS ZT_SIG_FXOKS |
| #define | SIG_FXOLS ZT_SIG_FXOLS |
| #define | SIG_FXSGS ZT_SIG_FXSGS |
| #define | SIG_FXSKS ZT_SIG_FXSKS |
| #define | SIG_FXSLS ZT_SIG_FXSLS |
| #define | SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) |
| #define | SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS) |
| #define | SIG_PRI ZT_SIG_CLEAR |
| #define | SIG_SF ZT_SIG_SF |
| #define | SIG_SF_FEATB (0x0800000 | ZT_SIG_SF) |
| #define | SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) |
| #define | SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF) |
| #define | SIG_SFWINK (0x0100000 | ZT_SIG_SF) |
| #define | SMDI_MD_WAIT_TIMEOUT 1500 |
| #define | SUB_CALLWAIT 1 |
| #define | SUB_REAL 0 |
| #define | SUB_THREEWAY 2 |
| #define | tdesc "Zapata Telephony" |
| #define | TRAILER_MS 5 |
| #define | TRANSFER 0 |
| #define | ZT_EVENT_DTMFDOWN 0 |
| #define | ZT_EVENT_DTMFUP 0 |
Functions | |
| static int | __unload_module (void) |
| static struct ast_frame * | __zt_exception (struct ast_channel *ast) |
| static int | action_transfer (struct mansession *s, const struct message *m) |
| static int | action_transferhangup (struct mansession *s, const struct message *m) |
| static int | action_zapdialoffhook (struct mansession *s, const struct message *m) |
| static int | action_zapdndoff (struct mansession *s, const struct message *m) |
| static int | action_zapdndon (struct mansession *s, const struct message *m) |
| static int | action_zaprestart (struct mansession *s, const struct message *m) |
| static int | action_zapshowchannels (struct mansession *s, const struct message *m) |
| static char * | alarm2str (int alarm) |
| static int | alloc_sub (struct zt_pvt *p, int x) |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,.load=load_module,.unload=unload_module,.reload=reload,) | |
| AST_MUTEX_DEFINE_STATIC (monlock) | |
| Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
| AST_MUTEX_DEFINE_STATIC (iflock) | |
| Protect the interface list (of zt_pvt's). | |
| static int | attempt_transfer (struct zt_pvt *p) |
| static int | available (struct zt_pvt *p, int channelmatch, int groupmatch, int *busy, int *channelmatched, int *groupmatched) |
| static int | build_channels (struct zt_chan_conf conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo) |
| static int | bump_gains (struct zt_pvt *p) |
| static struct zt_pvt * | chandup (struct zt_pvt *src) |
| static int | check_for_conference (struct zt_pvt *p) |
| static int | conf_add (struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel) |
| static int | conf_del (struct zt_pvt *p, struct zt_subchannel *c, int index) |
| static int | destroy_channel (struct zt_pvt *prev, struct zt_pvt *cur, int now) |
| static void | destroy_zt_pvt (struct zt_pvt **pvt) |
| static int | digit_to_dtmfindex (char digit) |
| static void | disable_dtmf_detect (struct zt_pvt *p) |
| static void * | do_monitor (void *data) |
| static void | enable_dtmf_detect (struct zt_pvt *p) |
| static char * | event2str (int event) |
| static void | fill_rxgain (struct zt_gains *g, float gain, int law) |
| static void | fill_txgain (struct zt_gains *g, float gain, int law) |
| static struct zt_pvt * | find_channel (int channel) |
| static int | get_alarms (struct zt_pvt *p) |
| static int | handle_init_event (struct zt_pvt *i, int event) |
| static int | handle_zap_show_cadences (int fd, int argc, char *argv[]) |
| static int | has_voicemail (struct zt_pvt *p) |
| static int | isourconf (struct zt_pvt *p, struct zt_subchannel *c) |
| static int | isslavenative (struct zt_pvt *p, struct zt_pvt **out) |
| static int | load_module (void) |
| static struct zt_pvt * | mkintf (int channel, struct zt_chan_conf conf, struct zt_pri *pri, int reloading) |
| static int | my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms) |
| static int | my_zt_write (struct zt_pvt *p, unsigned char *buf, int len, int index, int linear) |
| static int | process_zap (struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels) |
| static int | reload (void) |
| static int | reset_conf (struct zt_pvt *p) |
| static int | restart_monitor (void) |
| static int | restore_conference (struct zt_pvt *p) |
| static int | restore_gains (struct zt_pvt *p) |
| static int | save_conference (struct zt_pvt *p) |
| static int | send_callerid (struct zt_pvt *p) |
| static int | send_cwcidspill (struct zt_pvt *p) |
| static int | set_actual_gain (int fd, int chan, float rxgain, float txgain, int law) |
| static int | set_actual_rxgain (int fd, int chan, float gain, int law) |
| static int | set_actual_txgain (int fd, int chan, float gain, int law) |
| static int | setup_zap (int reload) |
| static void * | ss_thread (void *data) |
| static void | swap_subs (struct zt_pvt *p, int a, int b) |
| static int | unalloc_sub (struct zt_pvt *p, int x) |
| static int | unload_module (void) |
| static int | update_conf (struct zt_pvt *p) |
| static void | wakeup_sub (struct zt_pvt *p, int a, void *pri) |
| static int | zap_destroy_channel (int fd, int argc, char **argv) |
| static int | zap_destroy_channel_bynum (int channel) |
| static int | zap_fake_event (struct zt_pvt *p, int mode) |
| static void | zap_queue_frame (struct zt_pvt *p, struct ast_frame *f, void *pri) |
| static int | zap_restart (void) |
| static int | zap_restart_cmd (int fd, int argc, char **argv) |
| static int | zap_show_channel (int fd, int argc, char **argv) |
| static int | zap_show_channels (int fd, int argc, char **argv) |
| static int | zap_show_status (int fd, int argc, char *argv[]) |
| static char * | zap_sig2str (int sig) |
| static int | zt_answer (struct ast_channel *ast) |
| static enum ast_bridge_result | zt_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
| static int | zt_call (struct ast_channel *ast, char *rdest, int timeout) |
| static int | zt_callwait (struct ast_channel *ast) |
| static struct zt_chan_conf | zt_chan_conf_default (void) |
| static void | zt_close (int fd) |
| static int | zt_confmute (struct zt_pvt *p, int muted) |
| static int | zt_digit_begin (struct ast_channel *ast, char digit) |
| static int | zt_digit_end (struct ast_channel *ast, char digit, unsigned int duration) |
| static void | zt_disable_ec (struct zt_pvt *p) |
| static void | zt_enable_ec (struct zt_pvt *p) |
| static struct ast_frame * | zt_exception (struct ast_channel *ast) |
| static int | zt_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
| static int | zt_func_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len) |
| static int | zt_get_event (int fd) |
| Avoid the silly zt_getevent which ignores a bunch of events. | |
| static int | zt_get_index (struct ast_channel *ast, struct zt_pvt *p, int nullok) |
| static void | zt_handle_dtmfup (struct ast_channel *ast, int index, struct ast_frame **dest) |
| static struct ast_frame * | zt_handle_event (struct ast_channel *ast) |
| static int | zt_hangup (struct ast_channel *ast) |
| static int | zt_indicate (struct ast_channel *chan, int condition, const void *data, size_t datalen) |
| static void | zt_link (struct zt_pvt *slave, struct zt_pvt *master) |
| static struct ast_channel * | zt_new (struct zt_pvt *, int, int, int, int, int) |
| static int | zt_open (char *fn) |
| static struct ast_frame * | zt_read (struct ast_channel *ast) |
| static struct ast_channel * | zt_request (const char *type, int format, void *data, int *cause) |
| static int | zt_ring_phone (struct zt_pvt *p) |
| static int | zt_sendtext (struct ast_channel *c, const char *text) |
| static int | zt_set_hook (int fd, int hs) |
| static int | zt_setlinear (int zfd, int linear) |
| static int | zt_setoption (struct ast_channel *chan, int option, void *data, int datalen) |
| static void | zt_train_ec (struct zt_pvt *p) |
| static void | zt_unlink (struct zt_pvt *slave, struct zt_pvt *master, int needlock) |
| static int | zt_wait_event (int fd) |
| Avoid the silly zt_waitevent which ignores a bunch of events. | |
| static int | zt_wink (struct zt_pvt *p, int index) |
| static int | zt_write (struct ast_channel *ast, struct ast_frame *frame) |
Variables | |
| struct { | |
| int alarm | |
| char * name | |
| } | alarms [] |
| static struct zt_ring_cadence | cadences [NUM_CADENCE_MAX] |
| static int | cidrings [NUM_CADENCE_MAX] |
| cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on. | |
| static const char | config [] = "zapata.conf" |
| static struct ast_jb_conf | default_jbconf |
| static char | defaultcic [64] = "" |
| static char | defaultozz [64] = "" |
| static char | destroy_channel_usage [] |
| static int | distinctiveringaftercid = 0 |
| static struct zt_distRings | drings |
| static char * | events [] |
| static int | firstdigittimeout = 16000 |
| Wait up to 16 seconds for first digit (FXO logic). | |
| static int | gendigittimeout = 8000 |
| How long to wait for following digits (FXO logic). | |
| static struct ast_jb_conf | global_jbconf |
| static int | ifcount = 0 |
| static struct zt_pvt * | ifend |
| static struct zt_pvt * | iflist |
| static int | matchdigittimeout = 3000 |
| How long to wait for an extra digit, if there is an ambiguous match. | |
| static pthread_t | monitor_thread = AST_PTHREADT_NULL |
| This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
| static int | num_cadence = 4 |
| static int | numbufs = 4 |
| static char | progzone [10] = "" |
| static int | ringt_base = DEFAULT_RINGT |
| zt_pvt * | round_robin [32] |
| static char | show_channel_usage [] |
| static char | show_channels_usage [] |
| static char * | subnames [] |
| static const char | tdesc [] = "Zapata Telephony Driver" |
| static int | usedistinctiveringdetection = 0 |
| static int | user_has_defined_cadences = 0 |
| static struct ast_cli_entry | zap_cli [] |
| static char | zap_restart_usage [] |
| static char | zap_show_cadences_help [] |
| static char | zap_show_status_usage [] |
| static struct ast_channel_tech | zap_tech |
Connects to the zaptel telephony library as well as libpri. Libpri is optional and needed only if you are going to use ISDN connections.
You need to install libraries before you attempt to compile and install the zaptel channel.
Definition in file chan_zap.c.
| #define ASCII_BYTES_PER_CHAR 80 |
Referenced by zt_sendtext().
| #define AST_LAW | ( | p | ) | (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
Definition at line 153 of file chan_zap.c.
Referenced by send_cwcidspill(), ss_thread(), zt_call(), zt_callwait(), and zt_sendtext().
| #define CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) |
| #define CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) |
300 ms
Definition at line 282 of file chan_zap.c.
| #define CANBUSYDETECT | ( | p | ) | (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
| #define CANPROGRESSDETECT | ( | p | ) | (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */) |
| #define CHAN_PSEUDO -2 |
Definition at line 195 of file chan_zap.c.
Referenced by build_channels(), enable_dtmf_detect(), mkintf(), zt_new(), and zt_request().
| #define CHANNEL_PSEUDO -12 |
Definition at line 151 of file chan_zap.c.
| #define CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) |
| #define CONF_USER_REAL (1 << 0) |
Definition at line 406 of file chan_zap.c.
| #define CONF_USER_THIRDCALL (1 << 1) |
Definition at line 407 of file chan_zap.c.
| #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP) |
Definition at line 201 of file chan_zap.c.
| #define DCHAN_NOTINALARM (1 << 1) |
Definition at line 198 of file chan_zap.c.
| #define DCHAN_PROVISIONED (1 << 0) |
Definition at line 197 of file chan_zap.c.
| #define DCHAN_UP (1 << 2) |
Definition at line 199 of file chan_zap.c.
| #define DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID.
Definition at line 149 of file chan_zap.c.
Referenced by zt_chan_conf_default().
| #define DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) |
Definition at line 286 of file chan_zap.c.
| #define END_SILENCE_LEN 400 |
Referenced by zt_sendtext().
| #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" |
| #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
| #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" |
| #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" |
| #define GET_CHANNEL | ( | p | ) | ((p)->channel) |
Definition at line 710 of file chan_zap.c.
| #define HANGUP 1 |
Definition at line 10099 of file chan_zap.c.
Referenced by action_transferhangup(), and zap_fake_event().
| #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
Referenced by build_alerting(), build_connect(), build_connect_acknowledge(), build_disconnect(), build_facility(), build_hold(), build_hold_acknowledge(), build_hold_reject(), build_information(), build_notify(), build_proceeding(), build_progress(), build_release(), build_release_complete(), build_restart(), build_resume(), build_resume_acknowledge(), build_resume_reject(), build_retrieve(), build_retrieve_acknowledge(), build_retrieve_reject(), build_setup(), build_setup_acknowledge(), build_status(), build_status_enquiry(), build_suspend(), build_suspend_acknowledge(), build_suspend_reject(), build_timeout(), build_user_information(), parse_alerting(), parse_connect(), parse_disconnect(), parse_facility(), parse_information(), parse_proceeding(), parse_progress(), parse_release(), parse_release_complete(), parse_restart(), parse_setup(), parse_setup_acknowledge(), parse_status(), and zt_sendtext().
| #define HEADER_MS 50 |
Referenced by zt_sendtext().
| #define ISTRUNK | ( | p | ) |
| #define MASK_AVAIL (1 << 0) |
Channel available for PRI use
Definition at line 279 of file chan_zap.c.
| #define MASK_INUSE (1 << 1) |
Channel currently in use
Definition at line 280 of file chan_zap.c.
| #define MAX_CHANLIST_LEN 80 |
The length of the parameters list of 'zapchan'.
Definition at line 10453 of file chan_zap.c.
Referenced by process_zap().
| #define MAX_CHANNELS 672 |
No more than a DS3 per trunk group
Definition at line 193 of file chan_zap.c.
Referenced by mkintf().
| #define MAX_SLAVES 4 |
| #define MIN_MS_SINCE_FLASH ( (2000) ) |
| #define NEED_MFDETECT | ( | p | ) | (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) |
Signaling types that need to use MF detection should be placed in this macro.
Definition at line 156 of file chan_zap.c.
Referenced by ss_thread(), and zt_new().
| #define NUM_CADENCE_MAX 25 |
Definition at line 735 of file chan_zap.c.
| #define NUM_DCHANS 4 |
No more than 4 d-channels
Definition at line 192 of file chan_zap.c.
| #define NUM_SPANS 32 |
Definition at line 191 of file chan_zap.c.
| #define POLARITY_IDLE 0 |
Definition at line 364 of file chan_zap.c.
Referenced by unalloc_sub(), zt_handle_event(), and zt_hangup().
| #define POLARITY_REV 1 |
Definition at line 365 of file chan_zap.c.
Referenced by handle_init_event(), and zt_handle_event().
| #define READ_SIZE 160 |
Chunk size to read -- we use 20ms chunks to make things happy.
Definition at line 277 of file chan_zap.c.
Referenced by my_zt_write(), process_zap(), send_cwcidspill(), zt_callwait(), zt_open(), zt_read(), zt_sendtext(), and zt_setoption().
| #define sig2str zap_sig2str |
Definition at line 1219 of file chan_zap.c.
Referenced by action_zapshowchannels(), build_channels(), handle_init_event(), mkintf(), zap_show_channel(), and zt_handle_event().
| #define SIG_E911 (0x1000000 | ZT_SIG_EM) |
Definition at line 171 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_EM ZT_SIG_EM |
Definition at line 166 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_EM_E1 ZT_SIG_EM_E1 |
Definition at line 187 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_EMWINK (0x0100000 | ZT_SIG_EM) |
Definition at line 167 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_FEATB (0x0800000 | ZT_SIG_EM) |
Definition at line 170 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_FEATD (0x0200000 | ZT_SIG_EM) |
Definition at line 168 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_FEATDMF (0x0400000 | ZT_SIG_EM) |
Definition at line 169 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM) |
Definition at line 172 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_FGC_CAMA (0x4000000 | ZT_SIG_EM) |
Definition at line 173 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM) |
Definition at line 174 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_FXOGS ZT_SIG_FXOGS |
Definition at line 179 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
| #define SIG_FXOKS ZT_SIG_FXOKS |
Definition at line 180 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
| #define SIG_FXOLS ZT_SIG_FXOLS |
Definition at line 178 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_new().
| #define SIG_FXSGS ZT_SIG_FXSGS |
Definition at line 176 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_indicate().
| #define SIG_FXSKS ZT_SIG_FXSKS |
Definition at line 177 of file chan_zap.c.
Referenced by available(), handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), and zt_request().
| #define SIG_FXSLS ZT_SIG_FXSLS |
Definition at line 175 of file chan_zap.c.
Referenced by available(), handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_handle_event(), zt_hangup(), and zt_indicate().
| #define SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS) |
Definition at line 188 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), and zap_sig2str().
| #define SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS) |
Definition at line 189 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), and zap_sig2str().
| #define SIG_PRI ZT_SIG_CLEAR |
Definition at line 181 of file chan_zap.c.
Referenced by handle_init_event(), mkintf(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), zt_confmute(), zt_digit_begin(), zt_digit_end(), zt_enable_ec(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), zt_read(), and zt_write().
| #define SIG_SF ZT_SIG_SF |
Definition at line 182 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_SF_FEATB (0x0800000 | ZT_SIG_SF) |
Definition at line 186 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF) |
Definition at line 184 of file chan_zap.c.
Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF) |
Definition at line 185 of file chan_zap.c.
Referenced by handle_init_event(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SIG_SFWINK (0x0100000 | ZT_SIG_SF) |
Definition at line 183 of file chan_zap.c.
Referenced by handle_init_event(), process_zap(), ss_thread(), zap_sig2str(), zt_answer(), zt_call(), and zt_handle_event().
| #define SMDI_MD_WAIT_TIMEOUT 1500 |
| #define SUB_CALLWAIT 1 |
Call-Waiting call on hold
Definition at line 360 of file chan_zap.c.
| #define SUB_REAL 0 |
Active call
Definition at line 359 of file chan_zap.c.
| #define SUB_THREEWAY 2 |
Three-way call
Definition at line 361 of file chan_zap.c.
| #define tdesc "Zapata Telephony" |
| #define TRAILER_MS 5 |
Referenced by zt_sendtext().
| #define TRANSFER 0 |
| #define ZT_EVENT_DTMFDOWN 0 |
| #define ZT_EVENT_DTMFUP 0 |
| static int __unload_module | ( | void | ) | [static] |
Definition at line 10280 of file chan_zap.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_unregister_application(), ast_verbose(), zt_pvt::cidspill, destroy_zt_pvt(), free, iflist, master, zt_pvt::next, zt_pvt::owner, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, zap_cli, zap_tech, zt_subchannel::zfd, and zt_close().
10281 { 10282 int x = 0; 10283 struct zt_pvt *p, *pl; 10284 #ifdef HAVE_PRI 10285 int i; 10286 for (i = 0; i < NUM_SPANS; i++) { 10287 if (pris[i].master != AST_PTHREADT_NULL) 10288 pthread_cancel(pris[i].master); 10289 } 10290 ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 10291 ast_unregister_application(zap_send_keypad_facility_app); 10292 #endif 10293 ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 10294 ast_manager_unregister( "ZapDialOffhook" ); 10295 ast_manager_unregister( "ZapHangup" ); 10296 ast_manager_unregister( "ZapTransfer" ); 10297 ast_manager_unregister( "ZapDNDoff" ); 10298 ast_manager_unregister( "ZapDNDon" ); 10299 ast_manager_unregister("ZapShowChannels"); 10300 ast_manager_unregister("ZapRestart"); 10301 ast_channel_unregister(&zap_tech); 10302 ast_mutex_lock(&iflock); 10303 /* Hangup all interfaces if they have an owner */ 10304 p = iflist; 10305 while (p) { 10306 if (p->owner) 10307 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 10308 p = p->next; 10309 } 10310 ast_mutex_unlock(&iflock); 10311 ast_mutex_lock(&monlock); 10312 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 10313 pthread_cancel(monitor_thread); 10314 pthread_kill(monitor_thread, SIGURG); 10315 pthread_join(monitor_thread, NULL); 10316 } 10317 monitor_thread = AST_PTHREADT_STOP; 10318 ast_mutex_unlock(&monlock); 10319 10320 ast_mutex_lock(&iflock); 10321 /* Destroy all the interfaces and free their memory */ 10322 p = iflist; 10323 while (p) { 10324 /* Free any callerid */ 10325 if (p->cidspill) 10326 free(p->cidspill); 10327 /* Close the zapata thingy */ 10328 if (p->subs[SUB_REAL].zfd > -1) 10329 zt_close(p->subs[SUB_REAL].zfd); 10330 pl = p; 10331 p = p->next; 10332 x++; 10333 /* Free associated memory */ 10334 if (pl) 10335 destroy_zt_pvt(&pl); 10336 ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x); 10337 } 10338 iflist = NULL; 10339 ifcount = 0; 10340 ast_mutex_unlock(&iflock); 10341 #ifdef HAVE_PRI 10342 for (i = 0; i < NUM_SPANS; i++) { 10343 if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) 10344 pthread_join(pris[i].master, NULL); 10345 zt_close(pris[i].fds[i]); 10346 } 10347 #endif 10348 return 0; 10349 }
| static struct ast_frame* __zt_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4471 of file chan_zap.c.
References ast_bridged_channel(), AST_CONTROL_UNHOLD, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_pvt::channel, ast_frame::data, ast_frame::datalen, ast_frame::delivery, event2str(), zt_subchannel::f, f, zt_pvt::fake_event, ast_channel::fds, ast_frame::frametype, LOG_DEBUG, ast_frame::mallocd, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::oprmode, option_verbose, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, ast_frame::samples, ast_frame::src, SUB_REAL, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_disable_ec(), zt_get_event(), zt_get_index(), zt_handle_event(), zt_ring_phone(), and zt_set_hook().
Referenced by zt_exception(), and zt_read().
04472 { 04473 struct zt_pvt *p = ast->tech_pvt; 04474 int res; 04475 int usedindex=-1; 04476 int index; 04477 struct ast_frame *f; 04478 04479 04480 index = zt_get_index(ast, p, 1); 04481 04482 p->subs[index].f.frametype = AST_FRAME_NULL; 04483 p->subs[index].f.datalen = 0; 04484 p->subs[index].f.samples = 0; 04485 p->subs[index].f.mallocd = 0; 04486 p->subs[index].f.offset = 0; 04487 p->subs[index].f.subclass = 0; 04488 p->subs[index].f.delivery = ast_tv(0,0); 04489 p->subs[index].f.src = "zt_exception"; 04490 p->subs[index].f.data = NULL; 04491 04492 04493 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) { 04494 /* If nobody owns us, absorb the event appropriately, otherwise 04495 we loop indefinitely. This occurs when, during call waiting, the 04496 other end hangs up our channel so that it no longer exists, but we 04497 have neither FLASH'd nor ONHOOK'd to signify our desire to 04498 change to the other channel. */ 04499 if (p->fake_event) { 04500 res = p->fake_event; 04501 p->fake_event = 0; 04502 } else 04503 res = zt_get_event(p->subs[SUB_REAL].zfd); 04504 /* Switch to real if there is one and this isn't something really silly... */ 04505 if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) && 04506 (res != ZT_EVENT_HOOKCOMPLETE)) { 04507 ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res); 04508 p->owner = p->subs[SUB_REAL].owner; 04509 if (p->owner && ast_bridged_channel(p->owner)) 04510 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04511 p->subs[SUB_REAL].needunhold = 1; 04512 } 04513 switch (res) { 04514 case ZT_EVENT_ONHOOK: 04515 zt_disable_ec(p); 04516 if (p->owner) { 04517 if (option_verbose > 2) 04518 ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name); 04519 zt_ring_phone(p); 04520 p->callwaitingrepeat = 0; 04521 p->cidcwexpire = 0; 04522 } else 04523 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04524 update_conf(p); 04525 break; 04526 case ZT_EVENT_RINGOFFHOOK: 04527 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 04528 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 04529 p->subs[SUB_REAL].needanswer = 1; 04530 p->dialing = 0; 04531 } 04532 break; 04533 case ZT_EVENT_HOOKCOMPLETE: 04534 case ZT_EVENT_RINGERON: 04535 case ZT_EVENT_RINGEROFF: 04536 /* Do nothing */ 04537 break; 04538 case ZT_EVENT_WINKFLASH: 04539 gettimeofday(&p->flashtime, NULL); 04540 if (p->owner) { 04541 if (option_verbose > 2) 04542 ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 04543 if (p->owner->_state != AST_STATE_UP) { 04544 /* Answer if necessary */ 04545 usedindex = zt_get_index(p->owner, p, 0); 04546 if (usedindex > -1) { 04547 p->subs[usedindex].needanswer = 1; 04548 } 04549 ast_setstate(p->owner, AST_STATE_UP); 04550 } 04551 p->callwaitingrepeat = 0; 04552 p->cidcwexpire = 0; 04553 if (ast_bridged_channel(p->owner)) 04554 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04555 p->subs[SUB_REAL].needunhold = 1; 04556 } else 04557 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 04558 update_conf(p); 04559 break; 04560 default: 04561 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 04562 } 04563 f = &p->subs[index].f; 04564 return f; 04565 } 04566 if (!(p->radio || (p->oprmode < 0))) ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 04567 /* If it's not us, return NULL immediately */ 04568 if (ast != p->owner) { 04569 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 04570 f = &p->subs[index].f; 04571 return f; 04572 } 04573 f = zt_handle_event(ast); 04574 return f; 04575 }
| static int action_transfer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 10167 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), s, TRANSFER, and zap_fake_event().
Referenced by load_module().
10168 { 10169 struct zt_pvt *p = NULL; 10170 const char *channel = astman_get_header(m, "ZapChannel"); 10171 10172 if (ast_strlen_zero(channel)) { 10173 astman_send_error(s, m, "No channel specified"); 10174 return 0; 10175 } 10176 p = find_channel(atoi(channel)); 10177 if (!p) { 10178 astman_send_error(s, m, "No such channel"); 10179 return 0; 10180 } 10181 zap_fake_event(p,TRANSFER); 10182 astman_send_ack(s, m, "ZapTransfer"); 10183 return 0; 10184 }
| static int action_transferhangup | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 10186 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), find_channel(), HANGUP, s, and zap_fake_event().
Referenced by load_module().
10187 { 10188 struct zt_pvt *p = NULL; 10189 const char *channel = astman_get_header(m, "ZapChannel"); 10190 10191 if (ast_strlen_zero(channel)) { 10192 astman_send_error(s, m, "No channel specified"); 10193 return 0; 10194 } 10195 p = find_channel(atoi(channel)); 10196 if (!p) { 10197 astman_send_error(s, m, "No such channel"); 10198 return 0; 10199 } 10200 zap_fake_event(p,HANGUP); 10201 astman_send_ack(s, m, "ZapHangup"); 10202 return 0; 10203 }
| static int action_zapdialoffhook | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 10205 of file chan_zap.c.
References AST_FRAME_DTMF, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), f, find_channel(), zt_pvt::owner, s, and zap_queue_frame().
Referenced by load_module().
10206 { 10207 struct zt_pvt *p = NULL; 10208 const char *channel = astman_get_header(m, "ZapChannel"); 10209 const char *number = astman_get_header(m, "Number"); 10210 int i; 10211 10212 if (ast_strlen_zero(channel)) { 10213 astman_send_error(s, m, "No channel specified"); 10214 return 0; 10215 } 10216 if (ast_strlen_zero(number)) { 10217 astman_send_error(s, m, "No number specified"); 10218 return 0; 10219 } 10220 p = find_channel(atoi(channel)); 10221 if (!p) { 10222 astman_send_error(s, m, "No such channel"); 10223 return 0; 10224 } 10225 if (!p->owner) { 10226 astman_send_error(s, m, "Channel does not have it's owner"); 10227 return 0; 10228 } 10229 for (i = 0; i < strlen(number); i++) { 10230 struct ast_frame f = { AST_FRAME_DTMF, number[i] }; 10231 zap_queue_frame(p, &f, NULL); 10232 } 10233 astman_send_ack(s, m, "ZapDialOffhook"); 10234 return 0; 10235 }
| static int action_zapdndoff | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 10148 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, find_channel(), and s.
Referenced by load_module().
10149 { 10150 struct zt_pvt *p = NULL; 10151 const char *channel = astman_get_header(m, "ZapChannel"); 10152 10153 if (ast_strlen_zero(channel)) { 10154 astman_send_error(s, m, "No channel specified"); 10155 return 0; 10156 } 10157 p = find_channel(atoi(channel)); 10158 if (!p) { 10159 astman_send_error(s, m, "No such channel"); 10160 return 0; 10161 } 10162 p->dnd = 0; 10163 astman_send_ack(s, m, "DND Disabled"); 10164 return 0; 10165 }
| static int action_zapdndon | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 10129 of file chan_zap.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), zt_pvt::dnd, find_channel(), and s.
Referenced by load_module().
10130 { 10131 struct zt_pvt *p = NULL; 10132 const char *channel = astman_get_header(m, "ZapChannel"); 10133 10134 if (ast_strlen_zero(channel)) { 10135 astman_send_error(s, m, "No channel specified"); 10136 return 0; 10137 } 10138 p = find_channel(atoi(channel)); 10139 if (!p) { 10140 astman_send_error(s, m, "No such channel"); 10141 return 0; 10142 } 10143 p->dnd = 1; 10144 astman_send_ack(s, m, "DND Enabled"); 10145 return 0; 10146 }
| static int action_zaprestart | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 9756 of file chan_zap.c.
References astman_send_ack(), astman_send_error(), s, and zap_restart().
Referenced by load_module().
09757 { 09758 if (zap_restart() != 0) { 09759 astman_send_error(s, m, "Failed rereading zaptel configuration"); 09760 return 1; 09761 } 09762 astman_send_ack(s, m, "ZapRestart: Success"); 09763 return 0; 09764 }
| static int action_zapshowchannels | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 10237 of file chan_zap.c.
References alarm, alarm2str(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), zt_pvt::channel, zt_pvt::context, zt_pvt::dnd, get_alarms(), iflist, zt_pvt::next, s, zt_pvt::sig, and sig2str.
Referenced by load_module().
10238 { 10239 struct zt_pvt *tmp = NULL; 10240 const char *id = astman_get_header(m, "ActionID"); 10241 char idText[256] = ""; 10242 10243 astman_send_ack(s, m, "Zapata channel status will follow"); 10244 if (!ast_strlen_zero(id)) 10245 snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id); 10246 10247 ast_mutex_lock(&iflock); 10248 10249 tmp = iflist; 10250 while (tmp) { 10251 if (tmp->channel > 0) { 10252 int alarm = get_alarms(tmp); 10253 astman_append(s, 10254 "Event: ZapShowChannels\r\n" 10255 "Channel: %d\r\n" 10256 "Signalling: %s\r\n" 10257 "Context: %s\r\n" 10258 "DND: %s\r\n" 10259 "Alarm: %s\r\n" 10260 "%s" 10261 "\r\n", 10262 tmp->channel, sig2str(tmp->sig), tmp->context, 10263 tmp->dnd ? "Enabled" : "Disabled", 10264 alarm2str(alarm), idText); 10265 } 10266 10267 tmp = tmp->next; 10268 } 10269 10270 ast_mutex_unlock(&iflock); 10271 10272 astman_append(s, 10273 "Event: ZapShowChannelsComplete\r\n" 10274 "%s" 10275 "\r\n", 10276 idText); 10277 return 0; 10278 }
| static char* alarm2str | ( | int | alarm | ) | [static] |
Definition at line 1130 of file chan_zap.c.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
01131 { 01132 int x; 01133 for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) { 01134 if (alarms[x].alarm & alarm) 01135 return alarms[x].name; 01136 } 01137 return alarm ? "Unknown Alarm" : "No Alarm"; 01138 }
| static int alloc_sub | ( | struct zt_pvt * | p, | |
| int | x | |||
| ) | [static] |
Definition at line 928 of file chan_zap.c.
References ast_log(), zt_subchannel::chan, zt_pvt::channel, LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::subs, zt_subchannel::zfd, zt_close(), and zt_open().
Referenced by ss_thread(), zt_handle_event(), and zt_request().
00929 { 00930 ZT_BUFFERINFO bi; 00931 int res; 00932 if (p->subs[x].zfd < 0) { 00933 p->subs[x].zfd = zt_open("/dev/zap/pseudo"); 00934 if (p->subs[x].zfd > -1) { 00935 res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi); 00936 if (!res) { 00937 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 00938 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 00939 bi.numbufs = numbufs; 00940 res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi); 00941 if (res < 0) { 00942 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x); 00943 } 00944 } else 00945 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x); 00946 if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) { 00947 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd); 00948 zt_close(p->subs[x].zfd); 00949 p->subs[x].zfd = -1; 00950 return -1; 00951 } 00952 if (option_debug) 00953 ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan); 00954 return 0; 00955 } else 00956 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 00957 return -1; 00958 } 00959 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel); 00960 return -1; 00961 }
| AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
| AST_MODFLAG_DEFAULT | , | |||
| tdesc | , | |||
| . | load = load_module, |
|||
| . | unload = unload_module, |
|||
| . | reload = reload | |||
| ) |
| AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
| AST_MUTEX_DEFINE_STATIC | ( | iflock | ) |
Protect the interface list (of zt_pvt's).
| static int attempt_transfer | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3475 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, ast_bridged_channel(), ast_cdr_append(), ast_channel_masquerade(), AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_indicate(), ast_log(), ast_mutex_unlock(), ast_queue_control(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_RINGING, ast_channel::cdr, ast_channel::lock, LOG_DEBUG, zt_subchannel::owner, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), unalloc_sub(), and zt_subchannel::zfd.
03476 { 03477 /* In order to transfer, we need at least one of the channels to 03478 actually be in a call bridge. We can't conference two applications 03479 together (but then, why would we want to?) */ 03480 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 03481 /* The three-way person we're about to transfer to could still be in MOH, so 03482 stop if now if appropriate */ 03483 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 03484 ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 03485 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 03486 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 03487 } 03488 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) { 03489 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 03490 } 03491 if (p->subs[SUB_REAL].owner->cdr) { 03492 /* Move CDR from second channel to current one */ 03493 p->subs[SUB_THREEWAY].owner->cdr = 03494 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr); 03495 p->subs[SUB_REAL].owner->cdr = NULL; 03496 } 03497 if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) { 03498 /* Move CDR from second channel's bridge to current one */ 03499 p->subs[SUB_THREEWAY].owner->cdr = 03500 ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr); 03501 ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL; 03502 } 03503 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 03504 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03505 ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name); 03506 return -1; 03507 } 03508 /* Orphan the channel after releasing the lock */ 03509 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03510 unalloc_sub(p, SUB_THREEWAY); 03511 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 03512 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 03513 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 03514 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 03515 } 03516 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) { 03517 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 03518 } 03519 if (p->subs[SUB_THREEWAY].owner->cdr) { 03520 /* Move CDR from second channel to current one */ 03521 p->subs[SUB_REAL].owner->cdr = 03522 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr); 03523 p->subs[SUB_THREEWAY].owner->cdr = NULL; 03524 } 03525 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) { 03526 /* Move CDR from second channel's bridge to current one */ 03527 p->subs[SUB_REAL].owner->cdr = 03528 ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr); 03529 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL; 03530 } 03531 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 03532 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 03533 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name); 03534 return -1; 03535 } 03536 /* Three-way is now the REAL */ 03537 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03538 ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock); 03539 unalloc_sub(p, SUB_THREEWAY); 03540 /* Tell the caller not to hangup */ 03541 return 1; 03542 } else { 03543 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 03544 p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name); 03545 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03546 return -1; 03547 } 03548 return 0; 03549 }
| static int available | ( | struct zt_pvt * | p, | |
| int | channelmatch, | |||
| int | groupmatch, | |||
| int * | busy, | |||
| int * | channelmatched, | |||
| int * | groupmatched | |||
| ) | [inline, static] |
Definition at line 7532 of file chan_zap.c.
References ast_channel::_state, ast_log(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::callwaiting, zt_pvt::channel, zt_pvt::dnd, zt_pvt::group, zt_pvt::guardtime, zt_subchannel::inthreeway, LOG_DEBUG, zt_pvt::oprmode, zt_pvt::outgoing, zt_subchannel::owner, zt_pvt::owner, zt_pvt::radio, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_request().
07533 { 07534 int res; 07535 ZT_PARAMS par; 07536 07537 /* First, check group matching */ 07538 if (groupmatch) { 07539 if ((p->group & groupmatch) != groupmatch) 07540 return 0; 07541 *groupmatched = 1; 07542 } 07543 /* Check to see if we have a channel match */ 07544 if (channelmatch != -1) { 07545 if (p->channel != channelmatch) 07546 return 0; 07547 *channelmatched = 1; 07548 } 07549 /* We're at least busy at this point */ 07550 if (busy) { 07551 if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS)) 07552 *busy = 1; 07553 } 07554 /* If do not disturb, definitely not */ 07555 if (p->dnd) 07556 return 0; 07557 /* If guard time, definitely not */ 07558 if (p->guardtime && (time(NULL) < p->guardtime)) 07559 return 0; 07560 07561 /* If no owner definitely available */ 07562 if (!p->owner) { 07563 #ifdef HAVE_PRI 07564 /* Trust PRI */ 07565 if (p->pri) { 07566 if (p->resetting || p->call) 07567 return 0; 07568 else 07569 return 1; 07570 } 07571 #endif 07572 if (!(p->radio || (p->oprmode < 0))) 07573 { 07574 if (!p->sig || (p->sig == SIG_FXSLS)) 07575 return 1; 07576 /* Check hook state */ 07577 if (p->subs[SUB_REAL].zfd > -1) 07578 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 07579 else { 07580 /* Assume not off hook on CVRS */ 07581 res = 0; 07582 par.rxisoffhook = 0; 07583 } 07584 if (res) { 07585 ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel); 07586 } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 07587 /* When "onhook" that means no battery on the line, and thus 07588 it is out of service..., if it's on a TDM card... If it's a channel 07589 bank, there is no telling... */ 07590 if (par.rxbits > -1) 07591 return 1; 07592 if (par.rxisoffhook) 07593 return 1; 07594 else 07595 #ifdef ZAP_CHECK_HOOKSTATE 07596 return 0; 07597 #else 07598 return 1; 07599 #endif 07600 } else if (par.rxisoffhook) { 07601 ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel); 07602 /* Not available when the other end is off hook */ 07603 return 0; 07604 } 07605 } 07606 return 1; 07607 } 07608 07609 /* If it's not an FXO, forget about call wait */ 07610 if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 07611 return 0; 07612 07613 if (!p->callwaiting) { 07614 /* If they don't have call waiting enabled, then for sure they're unavailable at this point */ 07615 return 0; 07616 } 07617 07618 if (p->subs[SUB_CALLWAIT].zfd > -1) { 07619 /* If there is already a call waiting call, then we can't take a second one */ 07620 return 0; 07621 } 07622 07623 if ((p->owner->_state != AST_STATE_UP) && 07624 ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) { 07625 /* If the current call is not up, then don't allow the call */ 07626 return 0; 07627 } 07628 if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) { 07629 /* Can't take a call wait when the three way calling hasn't been merged yet. */ 07630 return 0; 07631 } 07632 /* We're cool */ 07633 return 1; 07634 }
| 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 10361 of file chan_zap.c.
References ast_log(), ast_strdupa, ast_verbose(), zt_chan_conf::chan, CHAN_PSEUDO, LOG_ERROR, mkintf(), option_verbose, zt_pvt::sig, sig2str, strsep(), and VERBOSE_PREFIX_3.
Referenced by process_zap().
10362 { 10363 char *c, *chan; 10364 int x, start, finish; 10365 struct zt_pvt *tmp; 10366 #ifdef HAVE_PRI 10367 struct zt_pri *pri; 10368 int trunkgroup, y; 10369 #endif 10370 10371 if ((reload == 0) && (conf.chan.sig < 0)) { 10372 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 10373 return -1; 10374 } 10375 10376 c = ast_strdupa(value); 10377 10378 #ifdef HAVE_PRI 10379 pri = NULL; 10380 if (iscrv) { 10381 if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) { 10382 ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno); 10383 return -1; 10384 } 10385 if (trunkgroup < 1) { 10386 ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno); 10387 return -1; 10388 } 10389 c += y; 10390 for (y = 0; y < NUM_SPANS; y++) { 10391 if (pris[y].trunkgroup == trunkgroup) { 10392 pri = pris + y; 10393 break; 10394 } 10395 } 10396 if (!pri) { 10397 ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno); 10398 return -1; 10399 } 10400 } 10401 #endif 10402 10403 while ((chan = strsep(&c, ","))) { 10404 if (sscanf(chan, "%d-%d", &start, &finish) == 2) { 10405 /* Range */ 10406 } else if (sscanf(chan, "%d", &start)) { 10407 /* Just one */ 10408 finish = start; 10409 } else if (!strcasecmp(chan, "pseudo")) { 10410 finish = start = CHAN_PSEUDO; 10411 if (found_pseudo) 10412 *found_pseudo = 1; 10413 } else { 10414 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan); 10415 return -1; 10416 } 10417 if (finish < start) { 10418 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 10419 x = finish; 10420 finish = start; 10421 start = x; 10422 } 10423 10424 for (x = start; x <= finish; x++) { 10425 #ifdef HAVE_PRI 10426 tmp = mkintf(x, conf, pri, reload); 10427 #else 10428 tmp = mkintf(x, conf, NULL, reload); 10429 #endif 10430 10431 if (tmp) { 10432 if (option_verbose > 2) { 10433 #ifdef HAVE_PRI 10434 if (pri) 10435 ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig)); 10436 else 10437 #endif 10438 ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig)); 10439 } 10440 } else { 10441 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n", 10442 (reload == 1) ? "reconfigure" : "register", value); 10443 return -1; 10444 } 10445 } 10446 } 10447 10448 return 0; 10449 }
| static int bump_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1580 of file chan_zap.c.
References ast_log(), zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, zt_pvt::txgain, and zt_subchannel::zfd.
Referenced by ss_thread().
01581 { 01582 int res; 01583 01584 /* Bump receive gain by 5.0db */ 01585 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law); 01586 if (res) { 01587 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno)); 01588 return -1; 01589 } 01590 01591 return 0; 01592 }
Definition at line 7636 of file chan_zap.c.
References ast_log(), ast_malloc, ast_mutex_init(), destroy_zt_pvt(), iflist, LOG_ERROR, SUB_REAL, and zt_open().
Referenced by zt_request().
07637 { 07638 struct zt_pvt *p; 07639 ZT_BUFFERINFO bi; 07640 int res; 07641 07642 if ((p = ast_malloc(sizeof(*p)))) { 07643 memcpy(p, src, sizeof(struct zt_pvt)); 07644 ast_mutex_init(&p->lock); 07645 p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo"); 07646 /* Allocate a zapata structure */ 07647 if (p->subs[SUB_REAL].zfd < 0) { 07648 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 07649 destroy_zt_pvt(&p); 07650 return NULL; 07651 } 07652 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07653 if (!res) { 07654 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07655 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07656 bi.numbufs = numbufs; 07657 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07658 if (res < 0) { 07659 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n"); 07660 } 07661 } else 07662 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n"); 07663 } 07664 p->destroy = 1; 07665 p->next = iflist; 07666 iflist = p; 07667 return p; 07668 }
| static int check_for_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3551 of file chan_zap.c.
References ast_log(), ast_verbose(), zt_pvt::channel, zt_pvt::confno, zt_subchannel::curconf, zt_pvt::master, option_verbose, SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_3, and zt_subchannel::zfd.
Referenced by zt_handle_event().
03552 { 03553 ZT_CONFINFO ci; 03554 /* Fine if we already have a master, etc */ 03555 if (p->master || (p->confno > -1)) 03556 return 0; 03557 memset(&ci, 0, sizeof(ci)); 03558 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 03559 ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel); 03560 return 0; 03561 } 03562 /* If we have no master and don't have a confno, then 03563 if we're in a conference, it's probably a MeetMe room or 03564 some such, so don't let us 3-way out! */ 03565 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 03566 if (option_verbose > 2) 03567 ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n"); 03568 return 1; 03569 } 03570 return 0; 03571 }
| static int conf_add | ( | struct zt_pvt * | p, | |
| struct zt_subchannel * | c, | |||
| int | index, | |||
| int | slavechannel | |||
| ) | [static] |
Definition at line 1221 of file chan_zap.c.
References ast_log(), zt_pvt::confno, zt_subchannel::curconf, LOG_DEBUG, LOG_WARNING, and zt_subchannel::zfd.
Referenced by update_conf().
01222 { 01223 /* If the conference already exists, and we're already in it 01224 don't bother doing anything */ 01225 ZT_CONFINFO zi; 01226 01227 memset(&zi, 0, sizeof(zi)); 01228 zi.chan = 0; 01229 01230 if (slavechannel > 0) { 01231 /* If we have only one slave, do a digital mon */ 01232 zi.confmode = ZT_CONF_DIGITALMON; 01233 zi.confno = slavechannel; 01234 } else { 01235 if (!index) { 01236 /* Real-side and pseudo-side both participate in conference */ 01237 zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER | 01238 ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 01239 } else 01240 zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER; 01241 zi.confno = p->confno; 01242 } 01243 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode)) 01244 return 0; 01245 if (c->zfd < 0) 01246 return 0; 01247 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01248 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno); 01249 return -1; 01250 } 01251 if (slavechannel < 1) { 01252 p->confno = zi.confno; 01253 } 01254 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01255 ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01256 return 0; 01257 }
| static int conf_del | ( | struct zt_pvt * | p, | |
| struct zt_subchannel * | c, | |||
| int | index | |||
| ) | [static] |
Definition at line 1270 of file chan_zap.c.
References ast_log(), zt_subchannel::curconf, isourconf(), LOG_DEBUG, LOG_WARNING, and zt_subchannel::zfd.
Referenced by update_conf(), and zt_unlink().
01271 { 01272 ZT_CONFINFO zi; 01273 if (/* Can't delete if there's no zfd */ 01274 (c->zfd < 0) || 01275 /* Don't delete from the conference if it's not our conference */ 01276 !isourconf(p, c) 01277 /* Don't delete if we don't think it's conferenced at all (implied) */ 01278 ) return 0; 01279 memset(&zi, 0, sizeof(zi)); 01280 zi.chan = 0; 01281 zi.confno = 0; 01282 zi.confmode = 0; 01283 if (ioctl(c->zfd, ZT_SETCONF, &zi)) { 01284 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01285 return -1; 01286 } 01287 ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno); 01288 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 01289 return 0; 01290 }
Definition at line 2216 of file chan_zap.c.
References destroy_zt_pvt(), iflist, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::prev, SUB_REAL, zt_pvt::subs, zt_subchannel::zfd, and zt_close().
Referenced by zap_destroy_channel_bynum(), zap_restart(), and zt_hangup().
02217 { 02218 int owned = 0; 02219 int i = 0; 02220 02221 if (!now) { 02222 if (cur->owner) { 02223 owned = 1; 02224 } 02225 02226 for (i = 0; i < 3; i++) { 02227 if (cur->subs[i].owner) { 02228 owned = 1; 02229 } 02230 } 02231 if (!owned) { 02232 if (prev) { 02233 prev->next = cur->next; 02234 if (prev->next) 02235 prev->next->prev = prev; 02236 else 02237 ifend = prev; 02238 } else { 02239 iflist = cur->next; 02240 if (iflist) 02241 iflist->prev = NULL; 02242 else 02243 ifend = NULL; 02244 } 02245 if (cur->subs[SUB_REAL].zfd > -1) { 02246 zt_close(cur->subs[SUB_REAL].zfd); 02247 } 02248 destroy_zt_pvt(&cur); 02249 } 02250 } else { 02251 if (prev) { 02252 prev->next = cur->next; 02253 if (prev->next) 02254 prev->next->prev = prev; 02255 else 02256 ifend = prev; 02257 } else { 02258 iflist = cur->next; 02259 if (iflist) 02260 iflist->prev = NULL; 02261 else 02262 ifend = NULL; 02263 } 02264 if (cur->subs[SUB_REAL].zfd > -1) { 02265 zt_close(cur->subs[SUB_REAL].zfd); 02266 } 02267 destroy_zt_pvt(&cur); 02268 } 02269 return 0; 02270 }
| static void destroy_zt_pvt | ( | struct zt_pvt ** | pvt | ) | [static] |
Definition at line 2201 of file chan_zap.c.
References ast_mutex_destroy(), ast_smdi_interface_destroy(), ASTOBJ_UNREF, free, zt_pvt::lock, zt_pvt::next, zt_pvt::prev, zt_pvt::smdi_iface, and zt_pvt::use_smdi.
Referenced by __unload_module(), chandup(), destroy_channel(), and mkintf().
02202 { 02203 struct zt_pvt *p = *pvt; 02204 /* Remove channel from the list */ 02205 if (p->prev) 02206 p->prev->next = p->next; 02207 if (p->next) 02208 p->next->prev = p->prev; 02209 if (p->use_smdi) 02210 ASTOBJ_UNREF(p->smdi_iface, ast_smdi_interface_destroy); 02211 ast_mutex_destroy(&p->lock); 02212 free(p); 02213 *pvt = NULL; 02214 }
| static int digit_to_dtmfindex | ( | char | digit | ) | [static] |
Definition at line 983 of file chan_zap.c.
Referenced by zt_digit_begin().
00984 { 00985 if (isdigit(digit)) 00986 return ZT_TONE_DTMF_BASE + (digit - '0'); 00987 else if (digit >= 'A' && digit <= 'D') 00988 return ZT_TONE_DTMF_A + (digit - 'A'); 00989 else if (digit >= 'a' && digit <= 'd') 00990 return ZT_TONE_DTMF_A + (digit - 'a'); 00991 else if (digit == '*') 00992 return ZT_TONE_DTMF_s; 00993 else if (digit == '#') 00994 return ZT_TONE_DTMF_p; 00995 else 00996 return -1; 00997 }
| static void disable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3094 of file chan_zap.c.
References ast_dsp_set_features(), zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_bridge().
03095 { 03096 #ifdef ZT_TONEDETECT 03097 int val; 03098 #endif 03099 03100 p->ignoredtmf = 1; 03101 03102 #ifdef ZT_TONEDETECT 03103 val = 0; 03104 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03105 #endif 03106 if (!p->hardwaredtmf && p->dsp) { 03107 p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT; 03108 ast_dsp_set_features(p->dsp, p->dsp_features); 03109 } 03110 }
| static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 6741 of file chan_zap.c.
References ast_calloc, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::cidspill, pollfd::events, pollfd::fd, free, iflist, last, LOG_DEBUG, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, POLLIN, POLLPRI, zt_pvt::radio, pollfd::revents, zt_pvt::sig, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
06742 { 06743 int count, res, res2, spoint, pollres=0; 06744 struct zt_pvt *i; 06745 struct zt_pvt *last = NULL; 06746 time_t thispass = 0, lastpass = 0; 06747 int found; 06748 char buf[1024]; 06749 struct pollfd *pfds=NULL; 06750 int lastalloc = -1; 06751 /* This thread monitors all the frame relay interfaces which are not yet in use 06752 (and thus do not have a separate thread) indefinitely */ 06753 /* From here on out, we die whenever asked */ 06754 #if 0 06755 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 06756 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 06757 return NULL; 06758 } 06759 ast_log(LOG_DEBUG, "Monitor starting...\n"); 06760 #endif 06761 for (;;) { 06762 /* Lock the interface list */ 06763 ast_mutex_lock(&iflock); 06764 if (!pfds || (lastalloc != ifcount)) { 06765 if (pfds) 06766 free(pfds); 06767 if (ifcount) { 06768 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) { 06769 ast_mutex_unlock(&iflock); 06770 return NULL; 06771 } 06772 } 06773 lastalloc = ifcount; 06774 } 06775 /* Build the stuff we're going to poll on, that is the socket of every 06776 zt_pvt that does not have an associated owner channel */ 06777 count = 0; 06778 i = iflist; 06779 while (i) { 06780 if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) { 06781 if (!i->owner && !i->subs[SUB_REAL].owner) { 06782 /* This needs to be watched, as it lacks an owner */ 06783 pfds[count].fd = i->subs[SUB_REAL].zfd; 06784 pfds[count].events = POLLPRI; 06785 pfds[count].revents = 0; 06786 /* Message waiting or r2 channels also get watched for reading */ 06787 if (i->cidspill) 06788 pfds[count].events |= POLLIN; 06789 count++; 06790 } 06791 } 06792 i = i->next; 06793 } 06794 /* Okay, now that we know what to do, release the interface lock */ 06795 ast_mutex_unlock(&iflock); 06796 06797 pthread_testcancel(); 06798 /* Wait at least a second for something to happen */ 06799 res = poll(pfds, count, 1000); 06800 pthread_testcancel(); 06801 /* Okay, poll has finished. Let's see what happened. */ 06802 if (res < 0) { 06803 if ((errno != EAGAIN) && (errno != EINTR)) 06804 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 06805 continue; 06806 } 06807 /* Alright, lock the interface list again, and let's look and see what has 06808 happened */ 06809 ast_mutex_lock(&iflock); 06810 found = 0; 06811 spoint = 0; 06812 lastpass = thispass; 06813 thispass = time(NULL); 06814 i = iflist; 06815 while (i) { 06816 if (thispass != lastpass) { 06817 if (!found && ((i == last) || ((i == iflist) && !last))) { 06818 last = i; 06819 if (last) { 06820 if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) && 06821 (last->sig & __ZT_SIG_FXO)) { 06822 res = ast_app_has_voicemail(last->mailbox, NULL); 06823 if (last->msgstate != res) { 06824 int x; 06825 ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel); 06826 x = ZT_FLUSH_BOTH; 06827 res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 06828 if (res2) 06829 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel); 06830 if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) { 06831 /* Turn on on hook transfer for 4 seconds */ 06832 x = 4000; 06833 ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x); 06834 last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last)); 06835 last->cidpos = 0; 06836 last->msgstate = res; 06837 last->onhooktime = thispass; 06838 } 06839 found ++; 06840 } 06841 } 06842 last = last->next; 06843 } 06844 } 06845 } 06846 if ((i->subs[SUB_REAL].zfd > -1) && i->sig) { 06847 if (i->radio && !i->owner) 06848 { 06849 res = zt_get_event(i->subs[SUB_REAL].zfd); 06850 if (res) 06851 { 06852 if (option_debug) 06853 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 06854 /* Don't hold iflock while handling init events */ 06855 ast_mutex_unlock(&iflock); 06856 handle_init_event(i, res); 06857 ast_mutex_lock(&iflock); 06858 } 06859 i = i->next; 06860 continue; 06861 } 06862 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint); 06863 if (pollres & POLLIN) { 06864 if (i->owner || i->subs[SUB_REAL].owner) { 06865 #ifdef HAVE_PRI 06866 if (!i->pri) 06867 #endif 06868 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd); 06869 i = i->next; 06870 continue; 06871 } 06872 if (!i->cidspill) { 06873 ast_log(LOG_WARNING, "Whoa.... I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd); 06874 i = i->next; 06875 continue; 06876 } 06877 res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf)); 06878 if (res > 0) { 06879 /* We read some number of bytes. Write an equal amount of data */ 06880 if (res > i->cidlen - i->cidpos) 06881 res = i->cidlen - i->cidpos; 06882 res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res); 06883 if (res2 > 0) { 06884 i->cidpos += res2; 06885 if (i->cidpos >= i->cidlen) { 06886 free(i->cidspill); 06887 i->cidspill = 0; 06888 i->cidpos = 0; 06889 i->cidlen = 0; 06890 } 06891 } else { 06892 ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno)); 06893 i->msgstate = -1; 06894 } 06895 } else { 06896 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 06897 } 06898 if (option_debug) 06899 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 06900 /* Don't hold iflock while handling init events -- race with chlock */ 06901 ast_mutex_unlock(&iflock); 06902 handle_init_event(i, res); 06903 ast_mutex_lock(&iflock); 06904 } 06905 if (pollres & POLLPRI) { 06906 if (i->owner || i->subs[SUB_REAL].owner) { 06907 #ifdef HAVE_PRI 06908 if (!i->pri) 06909 #endif 06910 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd); 06911 i = i->next; 06912 continue; 06913 } 06914 res = zt_get_event(i->subs[SUB_REAL].zfd); 06915 if (option_debug) 06916 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 06917 /* Don't hold iflock while handling init events */ 06918 ast_mutex_unlock(&iflock); 06919 handle_init_event(i, res); 06920 ast_mutex_lock(&iflock); 06921 } 06922 } 06923 i=i->next; 06924 } 06925 ast_mutex_unlock(&iflock); 06926 } 06927 /* Never reached */ 06928 return NULL; 06929 06930 }
| static void enable_dtmf_detect | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3112 of file chan_zap.c.
References ast_dsp_set_features(), CHAN_PSEUDO, zt_pvt::channel, zt_pvt::dsp, DSP_FEATURE_DTMF_DETECT, zt_pvt::dsp_features, zt_pvt::hardwaredtmf, zt_pvt::ignoredtmf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_bridge().
03113 { 03114 #ifdef ZT_TONEDETECT 03115 int val; 03116 #endif 03117 03118 if (p->channel == CHAN_PSEUDO) 03119 return; 03120 03121 p->ignoredtmf = 0; 03122 03123 #ifdef ZT_TONEDETECT 03124 val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 03125 ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val); 03126 #endif 03127 if (!p->hardwaredtmf && p->dsp) { 03128 p->dsp_features |= DSP_FEATURE_DTMF_DETECT; 03129 ast_dsp_set_features(p->dsp, p->dsp_features); 03130 } 03131 }
| static char* event2str | ( | int | event | ) | [static] |
Definition at line 1140 of file chan_zap.c.
Referenced by __zt_exception(), ss_thread(), and zt_handle_event().
01141 { 01142 static char buf[256]; 01143 if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1)) 01144 return events[event]; 01145 sprintf(buf, "Event %d", event); /* safe */ 01146 return buf; 01147 }
| static void fill_rxgain | ( | struct zt_gains * | g, | |
| float | gain, | |||
| int | law | |||
| ) | [static] |
Definition at line 1504 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_rxgain().
01505 { 01506 int j; 01507 int k; 01508 float linear_gain = pow(10.0, gain / 20.0); 01509 01510 switch (law) { 01511 case ZT_LAW_ALAW: 01512 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01513 if (gain) { 01514 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01515 if (k > 32767) k = 32767; 01516 if (k < -32767) k = -32767; 01517 g->rxgain[j] = AST_LIN2A(k); 01518 } else { 01519 g->rxgain[j] = j; 01520 } 01521 } 01522 break; 01523 case ZT_LAW_MULAW: 01524 for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) { 01525 if (gain) { 01526 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01527 if (k > 32767) k = 32767; 01528 if (k < -32767) k = -32767; 01529 g->rxgain[j] = AST_LIN2MU(k); 01530 } else { 01531 g->rxgain[j] = j; 01532 } 01533 } 01534 break; 01535 } 01536 }
| static void fill_txgain | ( | struct zt_gains * | g, | |
| float | gain, | |||
| int | law | |||
| ) | [static] |
Definition at line 1470 of file chan_zap.c.
References AST_ALAW, AST_LIN2A, AST_LIN2MU, and AST_MULAW.
Referenced by set_actual_txgain().
01471 { 01472 int j; 01473 int k; 01474 float linear_gain = pow(10.0, gain / 20.0); 01475 01476 switch (law) { 01477 case ZT_LAW_ALAW: 01478 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01479 if (gain) { 01480 k = (int) (((float) AST_ALAW(j)) * linear_gain); 01481 if (k > 32767) k = 32767; 01482 if (k < -32767) k = -32767; 01483 g->txgain[j] = AST_LIN2A(k); 01484 } else { 01485 g->txgain[j] = j; 01486 } 01487 } 01488 break; 01489 case ZT_LAW_MULAW: 01490 for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) { 01491 if (gain) { 01492 k = (int) (((float) AST_MULAW(j)) * linear_gain); 01493 if (k > 32767) k = 32767; 01494 if (k < -32767) k = -32767; 01495 g->txgain[j] = AST_LIN2MU(k); 01496 } else { 01497 g->txgain[j] = j; 01498 } 01499 } 01500 break; 01501 } 01502 }
| static struct zt_pvt* find_channel | ( | int | channel | ) | [static] |
Definition at line 10117 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().
10118 { 10119 struct zt_pvt *p = iflist; 10120 while (p) { 10121 if (p->channel == channel) { 10122 break; 10123 } 10124 p = p->next; 10125 } 10126 return p; 10127 }
| static int get_alarms | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3573 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::span, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by action_zapshowchannels(), handle_init_event(), and zt_handle_event().
03574 { 03575 int res; 03576 ZT_SPANINFO zi; 03577 memset(&zi, 0, sizeof(zi)); 03578 zi.spanno = p->span; 03579 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi); 03580 if (res < 0) { 03581 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 03582 return 0; 03583 } 03584 return zi.alarms; 03585 }
| static int handle_init_event | ( | struct zt_pvt * | i, | |
| int | event | |||
| ) | [static] |
Definition at line 6540 of file chan_zap.c.
References alarm2str(), ast_hangup(), ast_log(), ast_pthread_create, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verbose(), zt_pvt::channel, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::cidspill, EVENT_FLAG_SYSTEM, free, get_alarms(), has_voicemail(), zt_pvt::immediate, zt_pvt::inalarm, LOG_NOTICE, manager_event(), zt_pvt::polarity, POLARITY_REV, zt_pvt::radio, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ss_thread(), SUB_REAL, zt_pvt::subs, VERBOSE_PREFIX_2, zap_destroy_channel_bynum(), zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_new(), and zt_set_hook().
06541 { 06542 int res; 06543 pthread_t threadid; 06544 pthread_attr_t attr; 06545 struct ast_channel *chan; 06546 pthread_attr_init(&attr); 06547 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06548 /* Handle an event on a given channel for the monitor thread. */ 06549 switch (event) { 06550 case ZT_EVENT_NONE: 06551 case ZT_EVENT_BITSCHANGED: 06552 break; 06553 case ZT_EVENT_WINKFLASH: 06554 case ZT_EVENT_RINGOFFHOOK: 06555 if (i->inalarm) break; 06556 if (i->radio) break; 06557 /* Got a ring/answer. What kind of channel are we? */ 06558 switch (i->sig) { 06559 case SIG_FXOLS: 06560 case SIG_FXOGS: 06561 case SIG_FXOKS: 06562 res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06563 if (res && (errno == EBUSY)) 06564 break; 06565 if (i->cidspill) { 06566 /* Cancel VMWI spill */ 06567 free(i->cidspill); 06568 i->cidspill = NULL; 06569 } 06570 if (i->immediate) { 06571 zt_enable_ec(i); 06572 /* The channel is immediately up. Start right away */ 06573 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 06574 chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0); 06575 if (!chan) { 06576 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 06577 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06578 if (res < 0) 06579 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06580 } 06581 } else { 06582 /* Check for callerid, digits, etc */ 06583 chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0); 06584 if (chan) { 06585 if (has_voicemail(i)) 06586 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 06587 else 06588 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 06589 if (res < 0) 06590 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d\n", i->channel); 06591 if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06592 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06593 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06594 if (res < 0) 06595 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06596 ast_hangup(chan); 06597 } 06598 } else 06599 ast_log(LOG_WARNING, "Unable to create channel\n"); 06600 } 06601 break; 06602 case SIG_FXSLS: 06603 case SIG_FXSGS: 06604 case SIG_FXSKS: 06605 i->ringt = i->ringt_base; 06606 /* Fall through */ 06607 case SIG_EMWINK: 06608 case SIG_FEATD: 06609 case SIG_FEATDMF: 06610 case SIG_FEATDMF_TA: 06611 case SIG_E911: 06612 case SIG_FGC_CAMA: 06613 case SIG_FGC_CAMAMF: 06614 case SIG_FEATB: 06615 case SIG_EM: 06616 case SIG_EM_E1: 06617 case SIG_SFWINK: 06618 case SIG_SF_FEATD: 06619 case SIG_SF_FEATDMF: 06620 case SIG_SF_FEATB: 06621 case SIG_SF: 06622 /* Check for callerid, digits, etc */ 06623 chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0); 06624 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06625 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06626 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06627 if (res < 0) 06628 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06629 ast_hangup(chan); 06630 } else if (!chan) { 06631 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 06632 } 06633 break; 06634 default: 06635 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06636 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 06637 if (res < 0) 06638 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 06639 return -1; 06640 } 06641 break; 06642 case ZT_EVENT_NOALARM: 06643 i->inalarm = 0; 06644 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel); 06645 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 06646 "Channel: %d\r\n", i->channel); 06647 break; 06648 case ZT_EVENT_ALARM: 06649 i->inalarm = 1; 06650 res = get_alarms(i); 06651 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res)); 06652 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 06653 "Alarm: %s\r\n" 06654 "Channel: %d\r\n", 06655 alarm2str(res), i->channel); 06656 /* fall thru intentionally */ 06657 case ZT_EVENT_ONHOOK: 06658 if (i->radio) 06659 break; 06660 /* Back on hook. Hang up. */ 06661 switch (i->sig) { 06662 case SIG_FXOLS: 06663 case SIG_FXOGS: 06664 case SIG_FEATD: 06665 case SIG_FEATDMF: 06666 case SIG_FEATDMF_TA: 06667 case SIG_E911: 06668 case SIG_FGC_CAMA: 06669 case SIG_FGC_CAMAMF: 06670 case SIG_FEATB: 06671 case SIG_EM: 06672 case SIG_EM_E1: 06673 case SIG_EMWINK: 06674 case SIG_SF_FEATD: 06675 case SIG_SF_FEATDMF: 06676 case SIG_SF_FEATB: 06677 case SIG_SF: 06678 case SIG_SFWINK: 06679 case SIG_FXSLS: 06680 case SIG_FXSGS: 06681 case SIG_FXSKS: 06682 case SIG_GR303FXSKS: 06683 zt_disable_ec(i); 06684 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06685 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06686 break; 06687 case SIG_GR303FXOKS: 06688 case SIG_FXOKS: 06689 zt_disable_ec(i); 06690 /* Diddle the battery for the zhone */ 06691 #ifdef ZHONE_HACK 06692 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06693 usleep(1); 06694 #endif 06695 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06696 zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); 06697 break; 06698 case SIG_PRI: 06699 zt_disable_ec(i); 06700 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06701 break; 06702 default: 06703 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 06704 res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); 06705 return -1; 06706 } 06707 break; 06708 case ZT_EVENT_POLARITY: 06709 switch (i->sig) { 06710 case SIG_FXSLS: 06711 case SIG_FXSKS: 06712 case SIG_FXSGS: 06713 if (i->cid_start == CID_START_POLARITY) { 06714 i->polarity = POLARITY_REV; 06715 ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity " 06716 "CID detection on channel %d\n", 06717 i->channel); 06718 chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0); 06719 if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 06720 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 06721 } 06722 } 06723 break; 06724 default: 06725 ast_log(LOG_WARNING, "handle_init_event detected " 06726 "polarity reversal on non-FXO (SIG_FXS) " 06727 "interface %d\n", i->channel); 06728 } 06729 break; 06730 case ZT_EVENT_REMOVED: /* destroy channel */ 06731 ast_log(LOG_NOTICE, 06732 "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 06733 i->channel); 06734 zap_destroy_channel_bynum(i->channel); 06735 break; 06736 } 06737 pthread_attr_destroy(&attr); 06738 return 0; 06739 }
| static int handle_zap_show_cadences | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 9961 of file chan_zap.c.
References ast_cli(), COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, and term_color().
09962 { 09963 int i, j; 09964 for (i = 0; i < num_cadence; i++) { 09965 char output[1024]; 09966 char tmp[16], tmp2[64]; 09967 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 09968 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 09969 09970 for (j = 0; j < 16; j++) { 09971 if (cadences[i].ringcadence[j] == 0) 09972 break; 09973 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 09974 if (cidrings[i] * 2 - 1 == j) 09975 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 09976 else 09977 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 09978 if (j != 0) 09979 strncat(output, ",", sizeof(output) - strlen(output) - 1); 09980 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 09981 } 09982 ast_cli(fd,"%s\n",output); 09983 } 09984 return 0; 09985 }
| static int has_voicemail | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1698 of file chan_zap.c.
References ast_app_has_voicemail(), and zt_pvt::mailbox.
01699 { 01700 01701 return ast_app_has_voicemail(p->mailbox, NULL); 01702 }
| static int isourconf | ( | struct zt_pvt * | p, | |
| struct zt_subchannel * | c | |||
| ) | [static] |
Definition at line 1259 of file chan_zap.c.
References zt_pvt::channel, zt_pvt::confno, and zt_subchannel::curconf.
Referenced by conf_del().
01260 { 01261 /* If they're listening to our channel, they're ours */ 01262 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON)) 01263 return 1; 01264 /* If they're a talker on our (allocated) conference, they're ours */ 01265 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER)) 01266 return 1; 01267 return 0; 01268 }
Definition at line 1292 of file chan_zap.c.
References zt_subchannel::inthreeway, MAX_SLAVES, zt_pvt::slaves, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by update_conf().
01293 { 01294 int x; 01295 int useslavenative; 01296 struct zt_pvt *slave = NULL; 01297 /* Start out optimistic */ 01298 useslavenative = 1; 01299 /* Update conference state in a stateless fashion */ 01300 for (x = 0; x < 3; x++) { 01301 /* Any three-way calling makes slave native mode *definitely* out 01302 of the question */ 01303 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) 01304 useslavenative = 0; 01305 } 01306 /* If we don't have any 3-way calls, check to see if we have 01307 precisely one slave */ 01308 if (useslavenative) { 01309 for (x = 0; x < MAX_SLAVES; x++) { 01310 if (p->slaves[x]) { 01311 if (slave) { 01312 /* Whoops already have a slave! No 01313 slave native and stop right away */ 01314 slave = NULL; 01315 useslavenative = 0; 01316 break; 01317 } else { 01318 /* We have one slave so far */ 01319 slave = p->slaves[x]; 01320 } 01321 } 01322 } 01323 } 01324 /* If no slave, slave native definitely out */ 01325 if (!slave) 01326 useslavenative = 0; 01327 else if (slave->law != p->law) { 01328 useslavenative = 0; 01329 slave = NULL; 01330 } 01331 if (out) 01332 *out = slave; 01333 return useslavenative; 01334 }
| static int load_module | ( | void | ) | [static] |
Definition at line 11253 of file chan_zap.c.
References __unload_module(), action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), action_zapshowchannels(), ast_channel_register(), ast_cli_register_multiple(), ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, ast_mutex_init(), AST_PTHREADT_NULL, ast_register_application(), ast_string_field_init, ast_string_field_set, inuse, lock, LOG_ERROR, name, round_robin, setup_zap(), zap_cli, and zap_tech.
11254 { 11255 int res; 11256 11257 #ifdef HAVE_PRI 11258 int y,i; 11259 memset(pris, 0, sizeof(pris)); 11260 for (y = 0; y < NUM_SPANS; y++) { 11261 ast_mutex_init(&pris[y].lock); 11262 pris[y].offset = -1; 11263 pris[y].master = AST_PTHREADT_NULL; 11264 for (i = 0; i < NUM_DCHANS; i++) 11265 pris[y].fds[i] = -1; 11266 } 11267 pri_set_error(zt_pri_error); 11268 pri_set_message(zt_pri_message); 11269 ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec, 11270 zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip); 11271 #endif 11272 res = setup_zap(0); 11273 /* Make sure we can register our Zap channel type */ 11274 if (res) 11275 return AST_MODULE_LOAD_DECLINE; 11276 if (ast_channel_register(&zap_tech)) { 11277 ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n"); 11278 __unload_module(); 11279 return -1; 11280 } 11281 #ifdef HAVE_PRI 11282 ast_string_field_init(&inuse, 16); 11283 ast_string_field_set(&inuse, name, "GR-303InUse"); 11284 ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry)); 11285 #endif 11286 ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry)); 11287 11288 memset(round_robin, 0, sizeof(round_robin)); 11289 ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" ); 11290 ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" ); 11291 ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" ); 11292 ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" ); 11293 ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" ); 11294 ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels"); 11295 ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)"); 11296 11297 return res; 11298 }
| static struct zt_pvt* mkintf | ( | int | channel, | |
| struct zt_chan_conf | conf, | |||
| struct zt_pri * | pri, | |||
| int | reloading | |||
| ) | [static] |
Definition at line 7077 of file chan_zap.c.
References ast_calloc, ast_log(), ast_mutex_init(), ast_strlen_zero(), zt_chan_conf::chan, CHAN_PSEUDO, destroy_zt_pvt(), iflist, LOG_ERROR, MAX_CHANNELS, zt_pvt::next, zt_pvt::prev, zt_pvt::sig, sig2str, SIG_FXOKS, SIG_FXSKS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SUB_REAL, and zt_open().
Referenced by build_channels().
07078 { 07079 /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */ 07080 struct zt_pvt *tmp = NULL, *tmp2, *prev = NULL; 07081 char fn[80]; 07082 #if 1 07083 struct zt_bufferinfo bi; 07084 #endif 07085 struct zt_spaninfo si; 07086 int res; 07087 int span=0; 07088 int here = 0; 07089 int x; 07090 struct zt_pvt **wlist; 07091 struct zt_pvt **wend; 07092 ZT_PARAMS p; 07093 07094 wlist = &iflist; 07095 wend = &ifend; 07096 07097 #ifdef HAVE_PRI 07098 if (pri) { 07099 wlist = &pri->crvs; 07100 wend = &pri->crvend; 07101 } 07102 #endif 07103 07104 tmp2 = *wlist; 07105 prev = NULL; 07106 07107 while (tmp2) { 07108 if (!tmp2->destroy) { 07109 if (tmp2->channel == channel) { 07110 tmp = tmp2; 07111 here = 1; 07112 break; 07113 } 07114 if (tmp2->channel > channel) { 07115 break; 07116 } 07117 } 07118 prev = tmp2; 07119 tmp2 = tmp2->next; 07120 } 07121 07122 if (!here && !reloading) { 07123 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 07124 destroy_zt_pvt(&tmp); 07125 return NULL; 07126 } 07127 ast_mutex_init(&tmp->lock); 07128 ifcount++; 07129 for (x = 0; x < 3; x++) 07130 tmp->subs[x].zfd = -1; 07131 tmp->channel = channel; 07132 } 07133 07134 if (tmp) { 07135 if (!here) { 07136 if ((channel != CHAN_PSEUDO) && !pri) { 07137 snprintf(fn, sizeof(fn), "%d", channel); 07138 /* Open non-blocking */ 07139 if (!here) 07140 tmp->subs[SUB_REAL].zfd = zt_open(fn); 07141 /* Allocate a zapata structure */ 07142 if (tmp->subs[SUB_REAL].zfd < 0) { 07143 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); 07144 destroy_zt_pvt(&tmp); 07145 return NULL; 07146 } 07147 memset(&p, 0, sizeof(p)); 07148 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07149 if (res < 0) { 07150 ast_log(LOG_ERROR, "Unable to get parameters\n"); 07151 destroy_zt_pvt(&tmp); 07152 return NULL; 07153 } 07154 if (p.sigtype != (conf.chan.sig & 0x3ffff)) { 07155 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)); 07156 destroy_zt_pvt(&tmp); 07157 return NULL; 07158 } 07159 tmp->law = p.curlaw; 07160 tmp->span = p.spanno; 07161 span = p.spanno - 1; 07162 } else { 07163 if (channel == CHAN_PSEUDO) 07164 conf.chan.sig = 0; 07165 else if ((conf.chan.sig != SIG_FXOKS) && (conf.chan.sig != SIG_FXSKS)) { 07166 ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n"); 07167 return NULL; 07168 } 07169 } 07170 #ifdef HAVE_PRI 07171 if ((conf.chan.sig == SIG_PRI) || (conf.chan.sig == SIG_GR303FXOKS) || (conf.chan.sig == SIG_GR303FXSKS)) { 07172 int offset; 07173 int myswitchtype; 07174 int matchesdchan; 07175 int x,y; 07176 offset = 0; 07177 if ((conf.chan.sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) { 07178 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 07179 destroy_zt_pvt(&tmp); 07180 return NULL; 07181 } 07182 if (span >= NUM_SPANS) { 07183 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 07184 destroy_zt_pvt(&tmp); 07185 return NULL; 07186 } else { 07187 si.spanno = 0; 07188 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07189 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07190 destroy_zt_pvt(&tmp); 07191 return NULL; 07192 } 07193 /* Store the logical span first based upon the real span */ 07194 tmp->logicalspan = pris[span].prilogicalspan; 07195 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 07196 if (span < 0) { 07197 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 07198 destroy_zt_pvt(&tmp); 07199 return NULL; 07200 } 07201 if (conf.chan.sig == SIG_PRI) 07202 myswitchtype = conf.pri.switchtype; 07203 else 07204 myswitchtype = PRI_SWITCH_GR303_TMC; 07205 /* Make sure this isn't a d-channel */ 07206 matchesdchan=0; 07207 for (x = 0; x < NUM_SPANS; x++) { 07208 for (y = 0; y < NUM_DCHANS; y++) { 07209 if (pris[x].dchannels[y] == tmp->channel) { 07210 matchesdchan = 1; 07211 break; 07212 } 07213 } 07214 } 07215 offset = p.chanpos; 07216 if (!matchesdchan) { 07217 if (pris[span].nodetype && (pris[span].nodetype != conf.pri.nodetype)) { 07218 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype)); 07219 destroy_zt_pvt(&tmp); 07220 return NULL; 07221 } 07222 if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) { 07223 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype)); 07224 destroy_zt_pvt(&tmp); 07225 return NULL; 07226 } 07227 if ((pris[span].dialplan) && (pris[span].dialplan != conf.pri.dialplan)) { 07228 ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan)); 07229 destroy_zt_pvt(&tmp); 07230 return NULL; 07231 } 07232 if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf.pri.idledial)) { 07233 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf.pri.idledial); 07234 destroy_zt_pvt(&tmp); 07235 return NULL; 07236 } 07237 if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf.pri.idleext)) { 07238 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf.pri.idleext); 07239 destroy_zt_pvt(&tmp); 07240 return NULL; 07241 } 07242 if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) { 07243 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused); 07244 destroy_zt_pvt(&tmp); 07245 return NULL; 07246 } 07247 if (pris[span].minidle && (pris[span].minidle != conf.pri.minidle)) { 07248 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf.pri.minidle); 07249 destroy_zt_pvt(&tmp); 07250 return NULL; 07251 } 07252 if (pris[span].numchans >= MAX_CHANNELS) { 07253 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 07254 pris[span].trunkgroup); 07255 destroy_zt_pvt(&tmp); 07256 return NULL; 07257 } 07258 pris[span].nodetype = conf.pri.nodetype; 07259 pris[span].switchtype = myswitchtype; 07260 pris[span].nsf = conf.pri.nsf; 07261 pris[span].dialplan = conf.pri.dialplan; 07262 pris[span].localdialplan = conf.pri.localdialplan; 07263 pris[span].pvts[pris[span].numchans++] = tmp; 07264 pris[span].minunused = conf.pri.minunused; 07265 pris[span].minidle = conf.pri.minidle; 07266 pris[span].overlapdial = conf.pri.overlapdial; 07267 pris[span].facilityenable = conf.pri.facilityenable; 07268 ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial)); 07269 ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext)); 07270 ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix)); 07271 ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix)); 07272 ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix)); 07273 ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix)); 07274 ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix)); 07275 pris[span].resetinterval = conf.pri.resetinterval; 07276 07277 tmp->pri = &pris[span]; 07278 tmp->prioffset = offset; 07279 tmp->call = NULL; 07280 } else { 07281 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset); 07282 destroy_zt_pvt(&tmp); 07283 return NULL; 07284 } 07285 } 07286 } else { 07287 tmp->prioffset = 0; 07288 } 07289 #endif 07290 } else { 07291 conf.chan.sig = tmp->sig; 07292 conf.chan.radio = tmp->radio; 07293 memset(&p, 0, sizeof(p)); 07294 if (tmp->subs[SUB_REAL].zfd > -1) 07295 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p); 07296 } 07297 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 07298 if ((conf.chan.sig == SIG_FXSKS) || (conf.chan.sig == SIG_FXSLS) || 07299 (conf.chan.sig == SIG_EM) || (conf.chan.sig == SIG_EM_E1) || (conf.chan.sig == SIG_EMWINK) || 07300 (conf.chan.sig == SIG_FEATD) || (conf.chan.sig == SIG_FEATDMF) || (conf.chan.sig == SIG_FEATDMF_TA) || 07301 (conf.chan.sig == SIG_FEATB) || (conf.chan.sig == SIG_E911) || 07302 (conf.chan.sig == SIG_SF) || (conf.chan.sig == SIG_SFWINK) || (conf.chan.sig == SIG_FGC_CAMA) || (conf.chan.sig == SIG_FGC_CAMAMF) || 07303 (conf.chan.sig == SIG_SF_FEATD) || (conf.chan.sig == SIG_SF_FEATDMF) || 07304 (conf.chan.sig == SIG_SF_FEATB)) { 07305 p.starttime = 250; 07306 } 07307 if (conf.chan.radio) { 07308 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 07309 p.channo = channel; 07310 p.rxwinktime = 1; 07311 p.rxflashtime = 1; 07312 p.starttime = 1; 07313 p.debouncetime = 5; 07314 } 07315 if (!conf.chan.radio) { 07316 p.channo = channel; 07317 /* Override timing settings based on config file */ 07318 if (conf.timing.prewinktime >= 0) 07319 p.prewinktime = conf.timing.prewinktime; 07320 if (conf.timing.preflashtime >= 0) 07321 p.preflashtime = conf.timing.preflashtime; 07322 if (conf.timing.winktime >= 0) 07323 p.winktime = conf.timing.winktime; 07324 if (conf.timing.flashtime >= 0) 07325 p.flashtime = conf.timing.flashtime; 07326 if (conf.timing.starttime >= 0) 07327 p.starttime = conf.timing.starttime; 07328 if (conf.timing.rxwinktime >= 0) 07329 p.rxwinktime = conf.timing.rxwinktime; 07330 if (conf.timing.rxflashtime >= 0) 07331 p.rxflashtime = conf.timing.rxflashtime; 07332 if (conf.timing.debouncetime >= 0) 07333 p.debouncetime = conf.timing.debouncetime; 07334 } 07335 07336 /* dont set parms on a pseudo-channel (or CRV) */ 07337 if (tmp->subs[SUB_REAL].zfd >= 0) 07338 { 07339 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p); 07340 if (res < 0) { 07341 ast_log(LOG_ERROR, "Unable to set parameters\n"); 07342 destroy_zt_pvt(&tmp); 07343 return NULL; 07344 } 07345 } 07346 #if 1 07347 if (!here && (tmp->subs[SUB_REAL].zfd > -1)) { 07348 memset(&bi, 0, sizeof(bi)); 07349 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi); 07350 if (!res) { 07351 bi.txbufpolicy = ZT_POLICY_IMMEDIATE; 07352 bi.rxbufpolicy = ZT_POLICY_IMMEDIATE; 07353 bi.numbufs = numbufs; 07354 res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi); 07355 if (res < 0) { 07356 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel); 07357 } 07358 } else 07359 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel); 07360 } 07361 #endif 07362 tmp->immediate = conf.chan.immediate; 07363 tmp->transfertobusy = conf.chan.transfertobusy; 07364 tmp->sig = conf.chan.sig; 07365 tmp->outsigmod = conf.chan.outsigmod; 07366 tmp->radio = conf.chan.radio; 07367 tmp->ringt_base = ringt_base; 07368 tmp->firstradio = 0; 07369 if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS)) 07370 tmp->permcallwaiting = conf.chan.callwaiting; 07371 else 07372 tmp->permcallwaiting = 0; 07373 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 07374 tmp->destroy = 0; 07375 tmp->drings = drings; 07376 tmp->usedistinctiveringdetection = usedistinctiveringdetection; 07377 tmp->callwaitingcallerid = conf.chan.callwaitingcallerid; 07378 tmp->threewaycalling = conf.chan.threewaycalling; 07379 tmp->adsi = conf.chan.adsi; 07380 tmp->use_smdi = conf.chan.use_smdi; 07381 tmp->permhidecallerid = conf.chan.hidecallerid; 07382 tmp->callreturn = conf.chan.callreturn; 07383 tmp->echocancel = conf.chan.echocancel; 07384 tmp->echotraining = conf.chan.echotraining; 07385 tmp->pulse = conf.chan.pulse; 07386 tmp->echocanbridged = conf.chan.echocanbridged; 07387 tmp->busydetect = conf.chan.busydetect; 07388 tmp->busycount = conf.chan.busycount; 07389 tmp->busy_tonelength = conf.chan.busy_tonelength; 07390 tmp->busy_quietlength = conf.chan.busy_quietlength; 07391 tmp->callprogress = conf.chan.callprogress; 07392 tmp->cancallforward = conf.chan.cancallforward; 07393 tmp->dtmfrelax = conf.chan.dtmfrelax; 07394 tmp->callwaiting = tmp->permcallwaiting; 07395 tmp->hidecallerid = tmp->permhidecallerid; 07396 tmp->channel = channel; 07397 tmp->stripmsd = conf.chan.stripmsd; 07398 tmp->use_callerid = conf.chan.use_callerid; 07399 tmp->cid_signalling = conf.chan.cid_signalling; 07400 tmp->cid_start = conf.chan.cid_start; 07401 tmp->zaptrcallerid = conf.chan.zaptrcallerid; 07402 tmp->restrictcid = conf.chan.restrictcid; 07403 tmp->use_callingpres = conf.chan.use_callingpres; 07404 tmp->priindication_oob = conf.chan.priindication_oob; 07405 tmp->priexclusive = conf.chan.priexclusive; 07406 if (tmp->usedistinctiveringdetection) { 07407 if (!tmp->use_callerid) { 07408 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 07409 tmp->use_callerid = 1; 07410 } 07411 } 07412 07413 if (tmp->cid_signalling == CID_SIG_SMDI) { 07414 if (!tmp->use_smdi) { 07415 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n"); 07416 tmp->use_smdi = 1; 07417 } 07418 } 07419 if (tmp->use_smdi) { 07420 tmp->smdi_iface = ast_smdi_interface_find(conf.smdi_port); 07421 if (!(tmp->smdi_iface)) { 07422 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n"); 07423 tmp->use_smdi = 0; 07424 } 07425 } 07426 07427 ast_copy_string(tmp->accountcode, conf.chan.accountcode, sizeof(tmp->accountcode)); 07428 tmp->amaflags = conf.chan.amaflags; 07429 if (!here) { 07430 tmp->confno = -1; 07431 tmp->propconfno = -1; 07432 } 07433 tmp->canpark = conf.chan.canpark; 07434 tmp->transfer = conf.chan.transfer; 07435 ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext)); 07436 ast_copy_string(tmp->language, conf.chan.language, sizeof(tmp->language)); 07437 ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret)); 07438 ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest)); 07439 ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context)); 07440 ast_copy_string(tmp->cid_num, conf.chan.cid_num, sizeof(tmp->cid_num)); 07441 tmp->cid_ton = 0; 07442 ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name)); 07443 ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox)); 07444 tmp->msgstate = -1; 07445 tmp->group = conf.chan.group; 07446 tmp->callgroup = conf.chan.callgroup; 07447 tmp->pickupgroup= conf.chan.pickupgroup; 07448 tmp->rxgain = conf.chan.rxgain; 07449 tmp->txgain = conf.chan.txgain; 07450 tmp->tonezone = conf.chan.tonezone; 07451 tmp->onhooktime = time(NULL); 07452 if (tmp->subs[SUB_REAL].zfd > -1) { 07453 set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law); 07454 if (tmp->dsp) 07455 ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 07456 update_conf(tmp); 07457 if (!here) { 07458 if (conf.chan.sig != SIG_PRI) 07459 /* Hang it up to be sure it's good */ 07460 zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK); 07461 } 07462 ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone); 07463 #ifdef HAVE_PRI 07464 /* the dchannel is down so put the channel in alarm */ 07465 if (tmp->pri && !pri_is_up(tmp->pri)) 07466 tmp->inalarm = 1; 07467 else 07468 tmp->inalarm = 0; 07469 #endif 07470 memset(&si, 0, sizeof(si)); 07471 if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) { 07472 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 07473 destroy_zt_pvt(&tmp); 07474 return NULL; 07475 } 07476 if (si.alarms) tmp->inalarm = 1; 07477 } 07478 07479 tmp->polarityonanswerdelay = conf.chan.polarityonanswerdelay; 07480 tmp->answeronpolarityswitch = conf.chan.answeronpolarityswitch; 07481 tmp->hanguponpolarityswitch = conf.chan.hanguponpolarityswitch; 07482 tmp->sendcalleridafter = conf.chan.sendcalleridafter; 07483 07484 } 07485 if (tmp && !here) { 07486 /* nothing on the iflist */ 07487 if (!*wlist) { 07488 *wlist = tmp; 07489 tmp->prev = NULL; 07490 tmp->next = NULL; 07491 *wend = tmp; 07492 } else { 07493 /* at least one member on the iflist */ 07494 struct zt_pvt *working = *wlist; 07495 07496 /* check if we maybe have to put it on the begining */ 07497 if (working->channel > tmp->channel) { 07498 tmp->next = *wlist; 07499 tmp->prev = NULL; 07500 (*wlist)->prev = tmp; 07501 *wlist = tmp; 07502 } else { 07503 /* go through all the members and put the member in the right place */ 07504 while (working) { 07505 /* in the middle */ 07506 if (working->next) { 07507 if (working->channel < tmp->channel && working->next->channel > tmp->channel) { 07508 tmp->next = working->next; 07509 tmp->prev = working; 07510 working->next->prev = tmp; 07511 working->next = tmp; 07512 break; 07513 } 07514 } else { 07515 /* the last */ 07516 if (working->channel < tmp->channel) { 07517 working->next = tmp; 07518 tmp->next = NULL; 07519 tmp->prev = working; 07520 *wend = tmp; 07521 break; 07522 } 07523 } 07524 working = working->next; 07525 } 07526 } 07527 } 07528 } 07529 return tmp; 07530 }
| static int my_getsigstr | ( | struct ast_channel * | chan, | |
| char * | str, | |||
| const char * | term, | |||
| int | ms | |||
| ) | [static] |
Definition at line 5344 of file chan_zap.c.
References ast_waitfordigit().
Referenced by ss_thread().
05345 { 05346 char c; 05347 05348 *str = 0; /* start with empty output buffer */ 05349 for (;;) 05350 { 05351 /* Wait for the first digit (up to specified ms). */ 05352 c = ast_waitfordigit(chan, ms); 05353 /* if timeout, hangup or error, return as such */ 05354 if (c < 1) 05355 return c; 05356 *str++ = c; 05357 *str = 0; 05358 if (strchr(term, c)) 05359 return 1; 05360 } 05361 }
| static int my_zt_write | ( | struct zt_pvt * | p, | |
| unsigned char * | buf, | |||
| int | len, | |||
| int | index, | |||
| int | linear | |||
| ) | [static] |
Definition at line 4874 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_DEBUG, option_debug, READ_SIZE, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_write().
04875 { 04876 int sent=0; 04877 int size; 04878 int res; 04879 int fd; 04880 fd = p->subs[index].zfd; 04881 while (len) { 04882 size = len; 04883 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 04884 size = (linear ? READ_SIZE * 2 : READ_SIZE); 04885 res = write(fd, buf, size); 04886 if (res != size) { 04887 if (option_debug) 04888 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 04889 return sent; 04890 } 04891 len -= size; 04892 buf += size; 04893 } 04894 return sent; 04895 }
| static int process_zap | ( | struct zt_chan_conf * | confp, | |
| struct ast_variable * | v, | |||
| int | reload, | |||
| int | skipchannels | |||
| ) | [static] |
Definition at line 10454 of file chan_zap.c.
References zt_pvt::accountcode, zt_pvt::adsi, zt_pvt::amaflags, ast_callerid_split(), ast_cdr_amaflags2int(), ast_get_group(), ast_jb_read_conf(), ast_log(), ast_strlen_zero(), ast_true(), ast_verbose(), build_channels(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::callgroup, zt_pvt::callprogress, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::callwaitingcallerid, zt_pvt::cancallforward, zt_pvt::canpark, zt_chan_conf::chan, zt_pvt::cid_name, zt_pvt::cid_num, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, CID_START_RING, zt_pvt::context, ringContextData::contextData, drings, zt_pvt::drings, DSP_DIGITMODE_RELAXDTMF, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echotraining, global_jbconf, zt_pvt::group, zt_pvt::hidecallerid, zt_pvt::hidecalleridname, zt_pvt::immediate, zt_pvt::language, ast_variable::lineno, LOG_ERROR, zt_pvt::mailbox, MAX_CHANLIST_LEN, zt_pvt::mohinterpret, zt_pvt::mohsuggest, ast_variable::name, ast_variable::next, option_verbose, zt_pvt::outsigmod, zt_pvt::pickupgroup, zt_pvt::priexclusive, zt_pvt::priindication_oob, zt_pvt::pulse, zt_pvt::radio, READ_SIZE, zt_pvt::restrictcid, distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::rxgain, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SFWINK, zt_chan_conf::smdi_port, zt_pvt::stripmsd, strsep(), zt_pvt::threewaycalling, zt_chan_conf::timing, zt_pvt::tonezone, zt_pvt::transfer, zt_pvt::transfertobusy, zt_pvt::txgain, zt_pvt::use_callerid, zt_pvt::use_callingpres, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, ast_variable::value, VERBOSE_PREFIX_3, and zt_pvt::zaptrcallerid.
Referenced by setup_zap().
10455 { 10456 struct zt_pvt *tmp; 10457 char *ringc; /* temporary string for parsing the dring number. */ 10458 int y; 10459 int found_pseudo = 0; 10460 char zapchan[MAX_CHANLIST_LEN] = {}; 10461 10462 for (; v; v = v->next) { 10463 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 10464 continue; 10465 10466 /* Create the interface list */ 10467 if (!strcasecmp(v->name, "channel") 10468 #ifdef HAVE_PRI 10469 || !strcasecmp(v->name, "crv") 10470 #endif 10471 ) { 10472 if (skipchannels) 10473 continue; 10474 int iscrv = !strcasecmp(v->name, "crv"); 10475 if (build_channels(*confp, iscrv, v->value, reload, v->lineno, &found_pseudo)) 10476 return -1; 10477 } else if (!strcasecmp(v->name, "zapchan")) { 10478 ast_copy_string(zapchan, v->value, sizeof(zapchan)); 10479 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 10480 if (ast_true(v->value)) 10481 confp->chan.usedistinctiveringdetection = 1; 10482 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) { 10483 if (ast_true(v->value)) 10484 distinctiveringaftercid = 1; 10485 } else if (!strcasecmp(v->name, "dring1context")) { 10486 ast_copy_string(confp->chan.drings.ringContext[0].contextData,v->value,sizeof(confp->chan.drings.ringContext[0].contextData)); 10487 } else if (!strcasecmp(v->name, "dring2context")) { 10488 ast_copy_string(confp->chan.drings.ringContext[1].contextData,v->value,sizeof(confp->chan.drings.ringContext[1].contextData)); 10489 } else if (!strcasecmp(v->name, "dring3context")) { 10490 ast_copy_string(confp->chan.drings.ringContext[2].contextData,v->value,sizeof(confp->chan.drings.ringContext[2].contextData)); 10491 } else if (!strcasecmp(v->name, "dring1")) { 10492 ringc = v->value; 10493 sscanf(ringc, "%d,%d,%d", &confp->chan.drings.ringnum[0].ring[0], &confp->chan.drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]); 10494 } else if (!strcasecmp(v->name, "dring2")) { 10495 ringc = v->value; 10496 sscanf(ringc,"%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]); 10497 } else if (!strcasecmp(v->name, "dring3")) { 10498 ringc = v->value; 10499 sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]); 10500 } else if (!strcasecmp(v->name, "usecallerid")) { 10501 confp->chan.use_callerid = ast_true(v->value); 10502 } else if (!strcasecmp(v->name, "cidsignalling")) { 10503 if (!strcasecmp(v->value, "bell")) 10504 confp->chan.cid_signalling = CID_SIG_BELL; 10505 else if (!strcasecmp(v->value, "v23")) 10506 confp->chan.cid_signalling = CID_SIG_V23; 10507 else if (!strcasecmp(v->value, "dtmf")) 10508 confp->chan.cid_signalling = CID_SIG_DTMF; 10509 else if (!strcasecmp(v->value, "smdi")) 10510 confp->chan.cid_signalling = CID_SIG_SMDI; 10511 else if (!strcasecmp(v->value, "v23_jp")) 10512 confp->chan.cid_signalling = CID_SIG_V23_JP; 10513 else if (ast_true(v->value)) 10514 confp->chan.cid_signalling = CID_SIG_BELL; 10515 } else if (!strcasecmp(v->name, "cidstart")) { 10516 if (!strcasecmp(v->value, "ring")) 10517 confp->chan.cid_start = CID_START_RING; 10518 else if (!strcasecmp(v->value, "polarity")) 10519 confp->chan.cid_start = CID_START_POLARITY; 10520 else if (ast_true(v->value)) 10521 confp->chan.cid_start = CID_START_RING; 10522 } else if (!strcasecmp(v->name, "threewaycalling")) { 10523 confp->chan.threewaycalling = ast_true(v->value); 10524 } else if (!strcasecmp(v->name, "cancallforward")) { 10525 confp->chan.cancallforward = ast_true(v->value); 10526 } else if (!strcasecmp(v->name, "relaxdtmf")) { 10527 if (ast_true(v->value)) 10528 confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 10529 else 10530 confp->chan.dtmfrelax = 0; 10531 } else if (!strcasecmp(v->name, "mailbox")) { 10532 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox)); 10533 } else if (!strcasecmp(v->name, "adsi")) { 10534 confp->chan.adsi = ast_true(v->value); 10535 } else if (!strcasecmp(v->name, "usesmdi")) { 10536 confp->chan.use_smdi = ast_true(v->value); 10537 } else if (!strcasecmp(v->name, "smdiport")) { 10538 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port)); 10539 } else if (!strcasecmp(v->name, "transfer")) { 10540 confp->chan.transfer = ast_true(v->value); 10541 } else if (!strcasecmp(v->name, "canpark")) { 10542 confp->chan.canpark = ast_true(v->value); 10543 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 10544 confp->chan.echocanbridged = ast_true(v->value); 10545 } else if (!strcasecmp(v->name, "busydetect")) { 10546 confp->chan.busydetect = ast_true(v->value); 10547 } else if (!strcasecmp(v->name, "busycount")) { 10548 confp->chan.busycount = atoi(v->value); 10549 } else if (!strcasecmp(v->name, "busypattern")) { 10550 if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) { 10551 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n"); 10552 } 10553 } else if (!strcasecmp(v->name, "callprogress")) { 10554 if (ast_true(v->value)) 10555 confp->chan.callprogress |= 1; 10556 else 10557 confp->chan.callprogress &= ~1; 10558 } else if (!strcasecmp(v->name, "faxdetect")) { 10559 if (!strcasecmp(v->value, "incoming")) { 10560 confp->chan.callprogress |= 4; 10561 confp->chan.callprogress &= ~2; 10562 } else if (!strcasecmp(v->value, "outgoing")) { 10563 confp->chan.callprogress &= ~4; 10564 confp->chan.callprogress |= 2; 10565 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 10566 confp->chan.callprogress |= 6; 10567 else 10568 confp->chan.callprogress &= ~6; 10569 } else if (!strcasecmp(v->name, "echocancel")) { 10570 if (!ast_strlen_zero(v->value)) { 10571 y = atoi(v->value); 10572 } else 10573 y = 0; 10574 if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024)) 10575 confp->chan.echocancel = y; 10576 else { 10577 confp->chan.echocancel = ast_true(v->value); 10578 if (confp->chan.echocancel) 10579 confp->chan.echocancel=128; 10580 } 10581 } else if (!strcasecmp(v->name, "echotraining")) { 10582 if (sscanf(v->value, "%d", &y) == 1) { 10583 if ((y < 10) || (y > 4000)) { 10584 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno); 10585 } else { 10586 confp->chan.echotraining = y; 10587 } 10588 } else if (ast_true(v->value)) { 10589 confp->chan.echotraining = 400; 10590 } else 10591 confp->chan.echotraining = 0; 10592 } else if (!strcasecmp(v->name, "hidecallerid")) { 10593 confp->chan.hidecallerid = ast_true(v->value); 10594 } else if (!strcasecmp(v->name, "hidecalleridname")) { 10595 confp->chan.hidecalleridname = ast_true(v->value); 10596 } else if (!strcasecmp(v->name, "pulsedial")) { 10597 confp->chan.pulse = ast_true(v->value); 10598 } else if (!strcasecmp(v->name, "callreturn")) { 10599 confp->chan.callreturn = ast_true(v->value); 10600 } else if (!strcasecmp(v->name, "callwaiting")) { 10601 confp->chan.callwaiting = ast_true(v->value); 10602 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 10603 confp->chan.callwaitingcallerid = ast_true(v->value); 10604 } else if (!strcasecmp(v->name, "context")) { 10605 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context)); 10606 } else if (!strcasecmp(v->name, "language")) { 10607 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language)); 10608 } else if (!strcasecmp(v->name, "progzone")) { 10609 ast_copy_string(progzone, v->value, sizeof(progzone)); 10610 } else if (!strcasecmp(v->name, "mohinterpret") 10611 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) { 10612 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret)); 10613 } else if (!strcasecmp(v->name, "mohsuggest")) { 10614 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest)); 10615 } else if (!strcasecmp(v->name, "stripmsd")) { 10616 confp->chan.stripmsd = atoi(v->value); 10617 } else if (!strcasecmp(v->name, "jitterbuffers")) { 10618 numbufs = atoi(v->value); 10619 } else if (!strcasecmp(v->name, "group")) { 10620 confp->chan.group = ast_get_group(v->value); 10621 } else if (!strcasecmp(v->name, "callgroup")) { 10622 confp->chan.callgroup = ast_get_group(v->value); 10623 } else if (!strcasecmp(v->name, "pickupgroup")) { 10624 confp->chan.pickupgroup = ast_get_group(v->value); 10625 } else if (!strcasecmp(v->name, "immediate")) { 10626 confp->chan.immediate = ast_true(v->value); 10627 } else if (!strcasecmp(v->name, "transfertobusy")) { 10628 confp->chan.transfertobusy = ast_true(v->value); 10629 } else if (!strcasecmp(v->name, "rxgain")) { 10630 if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) { 10631 ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value); 10632 } 10633 } else if (!strcasecmp(v->name, "txgain")) { 10634 if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) { 10635 ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value); 10636 } 10637 } else if (!strcasecmp(v->name, "tonezone")) { 10638 if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) { 10639 ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value); 10640 } 10641 } else if (!strcasecmp(v->name, "callerid")) { 10642 if (!strcasecmp(v->value, "asreceived")) { 10643 confp->chan.cid_num[0] = '\0'; 10644 confp->chan.cid_name[0] = '\0'; 10645 } else { 10646 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num)); 10647 } 10648 } else if (!strcasecmp(v->name, "fullname")) { 10649 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name)); 10650 } else if (!strcasecmp(v->name, "cid_number")) { 10651 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num)); 10652 } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) { 10653 confp->chan.zaptrcallerid = ast_true(v->value); 10654 } else if (!strcasecmp(v->name, "restrictcid")) { 10655 confp->chan.restrictcid = ast_true(v->value); 10656 } else if (!strcasecmp(v->name, "usecallingpres")) { 10657 confp->chan.use_callingpres = ast_true(v->value); 10658 } else if (!strcasecmp(v->name, "accountcode")) { 10659 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode)); 10660 } else if (!strcasecmp(v->name, "amaflags")) { 10661 y = ast_cdr_amaflags2int(v->value); 10662 if (y < 0) 10663 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 10664 else 10665 confp->chan.amaflags = y; 10666 } else if (!reload){ 10667 if (!strcasecmp(v->name, "signalling")) { 10668 confp->chan.outsigmod = -1; 10669 if (!strcasecmp(v->value, "em")) { 10670 confp->chan.sig = SIG_EM; 10671 } else if (!strcasecmp(v->value, "em_e1")) { 10672 confp->chan.sig = SIG_EM_E1; 10673 } else if (!strcasecmp(v->value, "em_w")) { 10674 confp->chan.sig = SIG_EMWINK; 10675 confp->chan.radio = 0; 10676 } else if (!strcasecmp(v->value, "fxs_ls")) { 10677 confp->chan.sig = SIG_FXSLS; 10678 confp->chan.radio = 0; 10679 } else if (!strcasecmp(v->value, "fxs_gs")) { 10680 confp->chan.sig = SIG_FXSGS; 10681 confp->chan.radio = 0; 10682 } else if (!strcasecmp(v->value, "fxs_ks")) { 10683 confp->chan.sig = SIG_FXSKS; 10684 confp->chan.radio = 0; 10685 } else if (!strcasecmp(v->value, "fxo_ls")) { 10686 confp->chan.sig = SIG_FXOLS; 10687 confp->chan.radio = 0; 10688 } else if (!strcasecmp(v->value, "fxo_gs")) { 10689 confp->chan.sig = SIG_FXOGS; 10690 confp->chan.radio = 0; 10691 } else if (!strcasecmp(v->value, "fxo_ks")) { 10692 confp->chan.sig = SIG_FXOKS; 10693 confp->chan.radio = 0; 10694 } else if (!strcasecmp(v->value, "fxs_rx")) { 10695 confp->chan.sig = SIG_FXSKS; 10696 confp->chan.radio = 1; 10697 } else if (!strcasecmp(v->value, "fxo_rx")) { 10698 confp->chan.sig = SIG_FXOLS; 10699 confp->chan.radio = 1; 10700 } else if (!strcasecmp(v->value, "fxs_tx")) { 10701 confp->chan.sig = SIG_FXSLS; 10702 confp->chan.radio = 1; 10703 } else if (!strcasecmp(v->value, "fxo_tx")) { 10704 confp->chan.sig = SIG_FXOGS; 10705 confp->chan.radio = 1; 10706 } else if (!strcasecmp(v->value, "em_rx")) { 10707 confp->chan.sig = SIG_EM; 10708 confp->chan.radio = 1; 10709 } else if (!strcasecmp(v->value, "em_tx")) { 10710 confp->chan.sig = SIG_EM; 10711 confp->chan.radio = 1; 10712 } else if (!strcasecmp(v->value, "em_rxtx")) { 10713 confp->chan.sig = SIG_EM; 10714 confp->chan.radio = 2; 10715 } else if (!strcasecmp(v->value, "em_txrx")) { 10716 confp->chan.sig = SIG_EM; 10717 confp->chan.radio = 2; 10718 } else if (!strcasecmp(v->value, "sf")) { 10719 confp->chan.sig = SIG_SF; 10720 confp->chan.radio = 0; 10721 } else if (!strcasecmp(v->value, "sf_w")) { 10722 confp->chan.sig = SIG_SFWINK; 10723 confp->chan.radio = 0; 10724 } else if (!strcasecmp(v->value, "sf_featd")) { 10725 confp->chan.sig = SIG_FEATD; 10726 confp->chan.radio = 0; 10727 } else if (!strcasecmp(v->value, "sf_featdmf")) { 10728 confp->chan.sig = SIG_FEATDMF; 10729 confp->chan.radio = 0; 10730 } else if (!strcasecmp(v->value, "sf_featb")) { 10731 confp->chan.sig = SIG_SF_FEATB; 10732 confp->chan.radio = 0; 10733 } else if (!strcasecmp(v->value, "sf")) { 10734 confp->chan.sig = SIG_SF; 10735 confp->chan.radio = 0; 10736 } else if (!strcasecmp(v->value, "sf_rx")) { 10737 confp->chan.sig = SIG_SF; 10738 confp->chan.radio = 1; 10739 } else if (!strcasecmp(v->value, "sf_tx")) { 10740 confp->chan.sig = SIG_SF; 10741 confp->chan.radio = 1; 10742 } else if (!strcasecmp(v->value, "sf_rxtx")) { 10743 confp->chan.sig = SIG_SF; 10744 confp->chan.radio = 2; 10745 } else if (!strcasecmp(v->value, "sf_txrx")) { 10746 confp->chan.sig = SIG_SF; 10747 confp->chan.radio = 2; 10748 } else if (!strcasecmp(v->value, "featd")) { 10749 confp->chan.sig = SIG_FEATD; 10750 confp->chan.radio = 0; 10751 } else if (!strcasecmp(v->value, "featdmf")) { 10752 confp->chan.sig = SIG_FEATDMF; 10753 confp->chan.radio = 0; 10754 } else if (!strcasecmp(v->value, "featdmf_ta")) { 10755 confp->chan.sig = SIG_FEATDMF_TA; 10756 confp->chan.radio = 0; 10757 } else if (!strcasecmp(v->value, "e911")) { 10758 confp->chan.sig = SIG_E911; 10759 confp->chan.radio = 0; 10760 } else if (!strcasecmp(v->value, "fgccama")) { 10761 confp->chan.sig = SIG_FGC_CAMA; 10762 confp->chan.radio = 0; 10763 } else if (!strcasecmp(v->value, "fgccamamf")) { 10764 confp->chan.sig = SIG_FGC_CAMAMF; 10765 confp->chan.radio = 0; 10766 } else if (!strcasecmp(v->value, "featb")) { 10767 confp->chan.sig = SIG_FEATB; 10768 confp->chan.radio = 0; 10769 #ifdef HAVE_PRI 10770 } else if (!strcasecmp(v->value, "pri_net")) { 10771 confp->chan.radio = 0; 10772 confp->chan.sig = SIG_PRI; 10773 confp->pri.nodetype = PRI_NETWORK; 10774 } else if (!strcasecmp(v->value, "pri_cpe")) { 10775 confp->chan.sig = SIG_PRI; 10776 confp->chan.radio = 0; 10777 confp->pri.nodetype = PRI_CPE; 10778 } else if (!strcasecmp(v->value, "gr303fxoks_net")) { 10779 confp->chan.sig = SIG_GR303FXOKS; 10780 confp->chan.radio = 0; 10781 confp->pri.nodetype = PRI_NETWORK; 10782 } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) { 10783 confp->chan.sig = SIG_GR303FXSKS; 10784 confp->chan.radio = 0; 10785 confp->pri.nodetype = PRI_CPE; 10786 #endif 10787 } else { 10788 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 10789 } 10790 } else if (!strcasecmp(v->name, "outsignalling")) { 10791 if (!strcasecmp(v->value, "em")) { 10792 confp->chan.outsigmod = SIG_EM; 10793 } else if (!strcasecmp(v->value, "em_e1")) { 10794 confp->chan.outsigmod = SIG_EM_E1; 10795 } else if (!strcasecmp(v->value, "em_w")) { 10796 confp->chan.outsigmod = SIG_EMWINK; 10797 } else if (!strcasecmp(v->value, "sf")) { 10798 confp->chan.outsigmod = SIG_SF; 10799 } else if (!strcasecmp(v->value, "sf_w")) { 10800 confp->chan.outsigmod = SIG_SFWINK; 10801 } else if (!strcasecmp(v->value, "sf_featd")) { 10802 confp->chan.outsigmod = SIG_FEATD; 10803 } else if (!strcasecmp(v->value, "sf_featdmf")) { 10804 confp->chan.outsigmod = SIG_FEATDMF; 10805 } else if (!strcasecmp(v->value, "sf_featb")) { 10806 confp->chan.outsigmod = SIG_SF_FEATB; 10807 } else if (!strcasecmp(v->value, "sf")) { 10808 confp->chan.outsigmod = SIG_SF; 10809 } else if (!strcasecmp(v->value, "featd")) { 10810 confp->chan.outsigmod = SIG_FEATD; 10811 } else if (!strcasecmp(v->value, "featdmf")) { 10812 confp->chan.outsigmod = SIG_FEATDMF; 10813 } else if (!strcasecmp(v->value, "featdmf_ta")) { 10814 confp->chan.outsigmod = SIG_FEATDMF_TA; 10815 } else if (!strcasecmp(v->value, "e911")) { 10816 confp->chan.outsigmod = SIG_E911; 10817 } else if (!strcasecmp(v->value, "fgccama")) { 10818 confp->chan.outsigmod = SIG_FGC_CAMA; 10819 } else if (!strcasecmp(v->value, "fgccamamf")) { 10820 confp->chan.outsigmod = SIG_FGC_CAMAMF; 10821 } else if (!strcasecmp(v->value, "featb")) { 10822 confp->chan.outsigmod = SIG_FEATB; 10823 } else { 10824 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value); 10825 } 10826 #ifdef HAVE_PRI 10827 } else if (!strcasecmp(v->name, "pridialplan")) { 10828 if (!strcasecmp(v->value, "national")) { 10829 confp->pri.dialplan = PRI_NATIONAL_ISDN + 1; 10830 } else if (!strcasecmp(v->value, "unknown")) { 10831 confp->pri.dialplan = PRI_UNKNOWN + 1; 10832 } else if (!strcasecmp(v->value, "private")) { 10833 confp->pri.dialplan = PRI_PRIVATE + 1; 10834 } else if (!strcasecmp(v->value, "international")) { 10835 confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1; 10836 } else if (!strcasecmp(v->value, "local")) { 10837 confp->pri.dialplan = PRI_LOCAL_ISDN + 1; 10838 } else if (!strcasecmp(v->value, "dynamic")) { 10839 confp->pri.dialplan = -1; 10840 } else { 10841 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 10842 } 10843 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 10844 if (!strcasecmp(v->value, "national")) { 10845 confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1; 10846 } else if (!strcasecmp(v->value, "unknown")) { 10847 confp->pri.localdialplan = PRI_UNKNOWN + 1; 10848 } else if (!strcasecmp(v->value, "private")) { 10849 confp->pri.localdialplan = PRI_PRIVATE + 1; 10850 } else if (!strcasecmp(v->value, "international")) { 10851 confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1; 10852 } else if (!strcasecmp(v->value, "local")) { 10853 confp->pri.localdialplan = PRI_LOCAL_ISDN + 1; 10854 } else if (!strcasecmp(v->value, "dynamic")) { 10855 confp->pri.localdialplan = -1; 10856 } else { 10857 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 10858 } 10859 } else if (!strcasecmp(v->name, "switchtype")) { 10860 if (!strcasecmp(v->value, "national")) 10861 confp->pri.switchtype = PRI_SWITCH_NI2; 10862 else if (!strcasecmp(v->value, "ni1")) 10863 confp->pri.switchtype = PRI_SWITCH_NI1; 10864 else if (!strcasecmp(v->value, "dms100")) 10865 confp->pri.switchtype = PRI_SWITCH_DMS100; 10866 else if (!strcasecmp(v->value, "4ess")) 10867 confp->pri.switchtype = PRI_SWITCH_ATT4ESS; 10868 else if (!strcasecmp(v->value, "5ess")) 10869 confp->pri.switchtype = PRI_SWITCH_LUCENT5E; 10870 else if (!strcasecmp(v->value, "euroisdn")) 10871 confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1; 10872 else if (!strcasecmp(v->value, "qsig")) 10873 confp->pri.switchtype = PRI_SWITCH_QSIG; 10874 else { 10875 ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value); 10876 return -1; 10877 } 10878 } else if (!strcasecmp(v->name, "nsf")) { 10879 if (!strcasecmp(v->value, "sdn")) 10880 confp->pri.nsf = PRI_NSF_SDN; 10881 else if (!strcasecmp(v->value, "megacom")) 10882 confp->pri.nsf = PRI_NSF_MEGACOM; 10883 else if (!strcasecmp(v->value, "tollfreemegacom")) 10884 confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM; 10885 else if (!strcasecmp(v->value, "accunet")) 10886 confp->pri.nsf = PRI_NSF_ACCUNET; 10887 else if (!strcasecmp(v->value, "none")) 10888 confp->pri.nsf = PRI_NSF_NONE; 10889 else { 10890 ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value); 10891 confp->pri.nsf = PRI_NSF_NONE; 10892 } 10893 } else if (!strcasecmp(v->name, "priindication")) { 10894 if (!strcasecmp(v->value, "outofband")) 10895 confp->chan.priindication_oob = 1; 10896 else if (!strcasecmp(v->value, "inband")) 10897 confp->chan.priindication_oob = 0; 10898 else 10899 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n", 10900 v->value, v->lineno); 10901 } else if (!strcasecmp(v->name, "priexclusive")) { 10902 confp->chan.priexclusive = ast_true(v->value); 10903 } else if (!strcasecmp(v->name, "internationalprefix")) { 10904 ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix)); 10905 } else if (!strcasecmp(v->name, "nationalprefix")) { 10906 ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix)); 10907 } else if (!strcasecmp(v->name, "localprefix")) { 10908 ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix)); 10909 } else if (!strcasecmp(v->name, "privateprefix")) { 10910 ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix)); 10911 } else if (!strcasecmp(v->name, "unknownprefix")) { 10912 ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix)); 10913 } else if (!strcasecmp(v->name, "resetinterval")) { 10914 if (!strcasecmp(v->value, "never")) 10915 confp->pri.resetinterval = -1; 10916 else if (atoi(v->value) >= 60) 10917 confp->pri.resetinterval = atoi(v->value); 10918 else 10919 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n", 10920 v->value, v->lineno); 10921 } else if (!strcasecmp(v->name, "minunused")) { 10922 confp->pri.minunused = atoi(v->value); 10923 } else if (!strcasecmp(v->name, "minidle")) { 10924 confp->pri.minidle = atoi(v->value); 10925 } else if (!strcasecmp(v->name, "idleext")) { 10926 ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext)); 10927 } else if (!strcasecmp(v->name, "idledial")) { 10928 ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial)); 10929 } else if (!strcasecmp(v->name, "overlapdial")) { 10930 confp->pri.overlapdial = ast_true(v->value); 10931 } else if (!strcasecmp(v->name, "pritimer")) { 10932 #ifdef PRI_GETSET_TIMERS 10933 char *timerc, *c; 10934 int timer, timeridx; 10935 c = v->value; 10936 timerc = strsep(&c, ","); 10937 if (timerc) { 10938 timer = atoi(c); 10939 if (!timer) 10940 ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc); 10941 else { 10942 if ((timeridx = pri_timer2idx(timerc)) >= 0) 10943 pritimers[timeridx] = timer; 10944 else 10945 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc); 10946 } 10947 } else 10948 ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value); 10949 10950 } else if (!strcasecmp(v->name, "facilityenable")) { 10951 confp->pri.facilityenable = ast_true(v->value); 10952 #endif /* PRI_GETSET_TIMERS */ 10953 #endif /* HAVE_PRI */ 10954 } else if (!strcasecmp(v->name, "cadence")) { 10955 /* setup to scan our argument */ 10956 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 10957 int i; 10958 struct zt_ring_cadence new_cadence; 10959 int cid_location = -1; 10960 int firstcadencepos = 0; 10961 char original_args[80]; 10962 int cadence_is_ok = 1; 10963 10964 ast_copy_string(original_args, v->value, sizeof(original_args)); 10965 /* 16 cadences allowed (8 pairs) */ 10966 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]); 10967 10968 /* Cadence must be even (on/off) */ 10969 if (element_count % 2 == 1) { 10970 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args); 10971 cadence_is_ok = 0; 10972 } 10973 10974 /* Ring cadences cannot be negative */ 10975 for (i = 0; i < element_count; i++) { 10976 if (c[i] == 0) { 10977 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args); 10978 cadence_is_ok = 0; 10979 break; 10980 } else if (c[i] < 0) { 10981 if (i % 2 == 1) { 10982 /* Silence duration, negative possibly okay */ 10983 if (cid_location == -1) { 10984 cid_location = i; 10985 c[i] *= -1; 10986 } else { 10987 ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args); 10988 cadence_is_ok = 0; 10989 break; 10990 } 10991 } else { 10992 if (firstcadencepos == 0) { 10993 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 10994 /* duration will be passed negative to the zaptel driver */ 10995 } else { 10996 ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args); 10997 cadence_is_ok = 0; 10998 break; 10999 } 11000 } 11001 } 11002 } 11003 11004 /* Substitute our scanned cadence */ 11005 for (i = 0; i < 16; i++) { 11006 new_cadence.ringcadence[i] = c[i]; 11007 } 11008 11009 if (cadence_is_ok) { 11010 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 11011 if (element_count < 2) { 11012 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args); 11013 } else { 11014 if (cid_location == -1) { 11015 /* user didn't say; default to first pause */ 11016 cid_location = 1; 11017 } else { 11018 /* convert element_index to cidrings value */ 11019 cid_location = (cid_location + 1) / 2; 11020 } 11021 /* ---we like their cadence; try to install it--- */ 11022 if (!user_has_defined_cadences++) 11023 /* this is the first user-defined cadence; clear the default user cadences */ 11024 num_cadence = 0; 11025 if ((num_cadence+1) >= NUM_CADENCE_MAX) 11026 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args); 11027 else { 11028 cadences[num_cadence] = new_cadence; 11029 cidrings[num_cadence++] = cid_location; 11030 if (option_verbose > 2) 11031 ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args); 11032 } 11033 } 11034 } 11035 } else if (!strcasecmp(v->name, "ringtimeout")) { 11036 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 11037 } else if (!strcasecmp(v->name, "prewink")) { 11038 confp->timing.prewinktime = atoi(v->value); 11039 } else if (!strcasecmp(v->name, "preflash")) { 11040 confp->timing.preflashtime = atoi(v->value); 11041 } else if (!strcasecmp(v->name, "wink")) { 11042 confp->timing.winktime = atoi(v->value); 11043 } else if (!strcasecmp(v->name, "flash")) { 11044 confp->timing.flashtime = atoi(v->value); 11045 } else if (!strcasecmp(v->name, "start")) { 11046 confp->timing.starttime = atoi(v->value); 11047 } else if (!strcasecmp(v->name, "rxwink")) { 11048 confp->timing.rxwinktime = atoi(v->value); 11049 } else if (!strcasecmp(v->name, "rxflash")) { 11050 confp->timing.rxflashtime = atoi(v->value); 11051 } else if (!strcasecmp(v->name, "debounce")) { 11052 confp->timing.debouncetime = atoi(v->value); 11053 } else if (!strcasecmp(v->name, "toneduration")) { 11054 int toneduration; 11055 int ctlfd; 11056 int res; 11057 struct zt_dialparams dps; 11058 11059 ctlfd = open("/dev/zap/ctl", O_RDWR); 11060 if (ctlfd == -1) { 11061 ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n"); 11062 return -1; 11063 } 11064 11065 toneduration = atoi(v->value); 11066 if (toneduration > -1) { 11067 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 11068 res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps); 11069 if (res < 0) { 11070 ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration); 11071 return -1; 11072 } 11073 } 11074 close(ctlfd); 11075 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 11076 confp->chan.polarityonanswerdelay = atoi(v->value); 11077 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 11078 confp->chan.answeronpolarityswitch = ast_true(v->value); 11079 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 11080 confp->chan.hanguponpolarityswitch = ast_true(v->value); 11081 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 11082 confp->chan.sendcalleridafter = atoi(v->value); 11083 } else if (!strcasecmp(v->name, "defaultcic")) { 11084 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 11085 } else if (!strcasecmp(v->name, "defaultozz")) { 11086 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 11087 } 11088 } else if (!skipchannels) 11089 ast_log(LOG_WARNING, "Ignoring %s\n", v->name); 11090 } 11091 if (zapchan[0]) { 11092 /* The user has set 'zapchan' */ 11093 /*< \todo pass proper line number instead of 0 */ 11094 if (build_channels(*confp, 0, zapchan, reload, 0, &found_pseudo)) { 11095 return -1; 11096 } 11097 } 11098 /*< \todo why check for the pseudo in the per-channel section. 11099 * Any actual use for manual setup of the pseudo channel? */ 11100 if (!found_pseudo && reload == 0) { 11101 /* Make sure pseudo isn't a member of any groups if 11102 we're automatically making it. */ 11103 11104 confp->chan.group = 0; 11105 confp->chan.callgroup = 0; 11106 confp->chan.pickupgroup = 0; 11107 11108 tmp = mkintf(CHAN_PSEUDO, *confp, NULL, reload); 11109 11110 if (tmp) { 11111 if (option_verbose > 2) 11112 ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n"); 11113 } else { 11114 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 11115 } 11116 } 11117 return 0; 11118 }
| static int reload | ( | void | ) | [static] |
Definition at line 11399 of file chan_zap.c.
References ast_log(), and setup_zap().
11400 { 11401 int res = 0; 11402 11403 res = setup_zap(1); 11404 if (res) { 11405 ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n"); 11406 return -1; 11407 } 11408 return 0; 11409 }
| static int reset_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1336 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::confno, zt_subchannel::curconf, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_hangup().
01337 { 01338 ZT_CONFINFO zi; 01339 memset(&zi, 0, sizeof(zi)); 01340 p->confno = -1; 01341 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf)); 01342 if (p->subs[SUB_REAL].zfd > -1) { 01343 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi)) 01344 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel); 01345 } 01346 return 0; 01347 }
| static int restart_monitor | ( | void | ) | [static] |
Definition at line 6932 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), and LOG_ERROR.
06933 { 06934 pthread_attr_t attr; 06935 pthread_attr_init(&attr); 06936 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06937 /* If we're supposed to be stopped -- stay stopped */ 06938 if (monitor_thread == AST_PTHREADT_STOP) 06939 return 0; 06940 ast_mutex_lock(&monlock); 06941 if (monitor_thread == pthread_self()) { 06942 ast_mutex_unlock(&monlock); 06943 ast_log(LOG_WARNING, "Cannot kill myself\n"); 06944 return -1; 06945 } 06946 if (monitor_thread != AST_PTHREADT_NULL) { 06947 /* Wake up the thread */ 06948 pthread_kill(monitor_thread, SIGURG); 06949 } else { 06950 /* Start a new monitor */ 06951 if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) { 06952 ast_mutex_unlock(&monlock); 06953 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 06954 pthread_attr_destroy(&attr); 06955 return -1; 06956 } 06957 } 06958 ast_mutex_unlock(&monlock); 06959 pthread_attr_destroy(&attr); 06960 return 0; 06961 }
| static int restore_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1664 of file chan_zap.c.
References ast_log(), LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by send_callerid(), zt_handle_event(), and zt_read().
01665 { 01666 int res; 01667 if (p->saveconf.confmode) { 01668 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf); 01669 p->saveconf.confmode = 0; 01670 if (res) { 01671 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno)); 01672 return -1; 01673 } 01674 } 01675 if (option_debug) 01676 ast_log(LOG_DEBUG, "Restored conferencing\n"); 01677 return 0; 01678 }
| static int restore_gains | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1594 of file chan_zap.c.
References ast_log(), zt_pvt::law, LOG_WARNING, zt_pvt::rxgain, set_actual_gain(), SUB_REAL, zt_pvt::subs, zt_pvt::txgain, and zt_subchannel::zfd.
Referenced by ss_thread(), and zt_hangup().
01595 { 01596 int res; 01597 01598 res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01599 if (res) { 01600 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno)); 01601 return -1; 01602 } 01603 01604 return 0; 01605 }
| static int save_conference | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1636 of file chan_zap.c.
References ast_log(), LOG_DEBUG, LOG_WARNING, option_debug, zt_pvt::saveconf, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_callwait(), and zt_handle_event().
01637 { 01638 struct zt_confinfo c; 01639 int res; 01640 if (p->saveconf.confmode) { 01641 ast_log(LOG_WARNING, "Can't save conference -- already in use\n"); 01642 return -1; 01643 } 01644 p->saveconf.chan = 0; 01645 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf); 01646 if (res) { 01647 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno)); 01648 p->saveconf.confmode = 0; 01649 return -1; 01650 } 01651 c.chan = 0; 01652 c.confno = 0; 01653 c.confmode = ZT_CONF_NORMAL; 01654 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c); 01655 if (res) { 01656 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno)); 01657 return -1; 01658 } 01659 if (option_debug) 01660 ast_log(LOG_DEBUG, "Disabled conferencing\n"); 01661 return 0; 01662 }
| static int send_callerid | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1704 of file chan_zap.c.
References ast_log(), zt_pvt::callwaitcas, CIDCW_EXPIRE_SAMPLES, zt_pvt::cidcwexpire, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, free, zt_subchannel::linear, LOG_WARNING, restore_conference(), SUB_REAL, zt_pvt::subs, zt_subchannel::zfd, and zt_setlinear().
Referenced by send_cwcidspill(), zt_call(), zt_callwait(), and zt_read().
01705 { 01706 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */ 01707 int res; 01708 /* Take out of linear mode if necessary */ 01709 if (p->subs[SUB_REAL].linear) { 01710 p->subs[SUB_REAL].linear = 0; 01711 zt_setlinear(p->subs[SUB_REAL].zfd, 0); 01712 } 01713 while (p->cidpos < p->cidlen) { 01714 res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos); 01715 if (res < 0) { 01716 if (errno == EAGAIN) 01717 return 0; 01718 else { 01719 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 01720 return -1; 01721 } 01722 } 01723 if (!res) 01724 return 0; 01725 p->cidpos += res; 01726 } 01727 free(p->cidspill); 01728 p->cidspill = NULL; 01729 if (p->callwaitcas) { 01730 /* Wait for CID/CW to expire */ 01731 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES; 01732 } else 01733 restore_conference(p); 01734 return 0; 01735 }
| static int send_cwcidspill | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1682 of file chan_zap.c.
References ast_callerid_callwaiting_generate(), AST_LAW, ast_malloc, ast_verbose(), zt_pvt::callwait_name, zt_pvt::callwait_num, zt_pvt::callwaitcas, zt_pvt::cidcwexpire, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, MAX_CALLERID_SIZE, option_verbose, READ_SIZE, send_callerid(), and VERBOSE_PREFIX_3.
Referenced by zt_handle_dtmfup().
01683 { 01684 p->callwaitcas = 0; 01685 p->cidcwexpire = 0; 01686 if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) 01687 return -1; 01688 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p)); 01689 /* Make sure we account for the end */ 01690 p->cidlen += READ_SIZE * 4; 01691 p->cidpos = 0; 01692 send_callerid(p); 01693 if (option_verbose > 2) 01694 ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num); 01695 return 0; 01696 }
| static int set_actual_gain | ( | int | fd, | |
| int | chan, | |||
| float | rxgain, | |||
| float | txgain, | |||
| int | law | |||
| ) | [static] |
Definition at line 1575 of file chan_zap.c.
References set_actual_rxgain(), and set_actual_txgain().
Referenced by bump_gains(), restore_gains(), and zt_call().
01576 { 01577 return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law); 01578 }
| static int set_actual_rxgain | ( | int | fd, | |
| int | chan, | |||
| float | gain, | |||
| int | law | |||
| ) | [static] |
Definition at line 1557 of file chan_zap.c.
References ast_log(), fill_rxgain(), and LOG_DEBUG.
Referenced by set_actual_gain(), and zt_setoption().
01558 { 01559 struct zt_gains g; 01560 int res; 01561 01562 memset(&g, 0, sizeof(g)); 01563 g.chan = chan; 01564 res = ioctl(fd, ZT_GETGAINS, &g); 01565 if (res) { 01566 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01567 return res; 01568 } 01569 01570 fill_rxgain(&g, gain, law); 01571 01572 return ioctl(fd, ZT_SETGAINS, &g); 01573 }
| static int set_actual_txgain | ( | int | fd, | |
| int | chan, | |||
| float | gain, | |||
| int | law | |||
| ) | [static] |
Definition at line 1538 of file chan_zap.c.
References ast_log(), fill_txgain(), LOG_DEBUG, and option_debug.
Referenced by set_actual_gain(), and zt_setoption().
01539 { 01540 struct zt_gains g; 01541 int res; 01542 01543 memset(&g, 0, sizeof(g)); 01544 g.chan = chan; 01545 res = ioctl(fd, ZT_GETGAINS, &g); 01546 if (res) { 01547 if (option_debug) 01548 ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno)); 01549 return res; 01550 } 01551 01552 fill_txgain(&g, gain, law); 01553 01554 return ioctl(fd, ZT_SETGAINS, &g); 01555 }
| static int setup_zap | ( | int | reload | ) | [static] |
Definition at line 11120 of file chan_zap.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), default_jbconf, global_jbconf, ast_variable::lineno, LOG_ERROR, ast_variable::name, ast_variable::next, option_verbose, process_zap(), restart_monitor(), ast_variable::value, VERBOSE_PREFIX_2, and zt_chan_conf_default().
Referenced by load_module(), reload(), and zap_restart().
11121 { 11122 struct ast_config *cfg; 11123 struct ast_variable *v; 11124 struct zt_chan_conf conf = zt_chan_conf_default(); 11125 int res; 11126 11127 #ifdef HAVE_PRI 11128 char *c; 11129 int spanno; 11130 int i, x; 11131 int logicalspan; 11132 int trunkgroup; 11133 int dchannels[NUM_DCHANS]; 11134 #endif 11135 11136 cfg = ast_config_load(config); 11137 11138 /* Error if we have no config file */ 11139 if (!cfg) { 11140 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 11141 return 0; 11142 } 11143 11144 /* It's a little silly to lock it, but we mind as well just to be sure */ 11145 ast_mutex_lock(&iflock); 11146 #ifdef HAVE_PRI 11147 if (!reload) { 11148 /* Process trunkgroups first */ 11149 v = ast_variable_browse(cfg, "trunkgroups"); 11150 while (v) { 11151 if (!strcasecmp(v->name, "trunkgroup")) { 11152 trunkgroup = atoi(v->value); 11153 if (trunkgroup > 0) { 11154 if ((c = strchr(v->value, ','))) { 11155 i = 0; 11156 memset(dchannels, 0, sizeof(dchannels)); 11157 while (c && (i < NUM_DCHANS)) { 11158 dchannels[i] = atoi(c + 1); 11159 if (dchannels[i] < 0) { 11160 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); 11161 } else 11162 i++; 11163 c = strchr(c + 1, ','); 11164 } 11165 if (i) { 11166 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 11167 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); 11168 } else if (option_verbose > 1) 11169 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"); 11170 } else 11171 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno); 11172 } else 11173 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno); 11174 } else 11175 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno); 11176 } else if (!strcasecmp(v->name, "spanmap")) { 11177 spanno = atoi(v->value); 11178 if (spanno > 0) { 11179 if ((c = strchr(v->value, ','))) { 11180 trunkgroup = atoi(c + 1); 11181 if (trunkgroup > 0) { 11182 if ((c = strchr(c + 1, ','))) 11183 logicalspan = atoi(c + 1); 11184 else 11185 logicalspan = 0; 11186 if (logicalspan >= 0) { 11187 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 11188 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 11189 } else if (option_verbose > 1) 11190 ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 11191 } else 11192 ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno); 11193 } else 11194 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno); 11195 } else 11196 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno); 11197 } else 11198 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno); 11199 } else { 11200 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 11201 } 11202 v = v->next; 11203 } 11204 } 11205 #endif 11206 11207 /* Copy the default jb config over global_jbconf */ 11208 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 11209 11210 v = ast_variable_browse(cfg, "channels"); 11211 res = process_zap(&conf, v, reload, 0); 11212 ast_mutex_unlock(&iflock); 11213 ast_config_destroy(cfg); 11214 if (res) 11215 return res; 11216 cfg = ast_config_load("users.conf"); 11217 if (cfg) { 11218 char *cat; 11219 const char *chans; 11220 process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1); 11221 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 11222 if (!strcasecmp(cat, "general")) 11223 continue; 11224 chans = ast_variable_retrieve(cfg, cat, "zapchan"); 11225 if (!ast_strlen_zero(chans)) { 11226 /** \todo At this point we should probably 11227 * duplicate conf, and pass a copy, to prevent 11228 * one section from affecting another 11229 */ 11230 process_zap(&conf, ast_variable_browse(cfg, cat), reload, 0); 11231 } 11232 } 11233 ast_config_destroy(cfg); 11234 } 11235 #ifdef HAVE_PRI 11236 if (!reload) { 11237 for (x = 0; x < NUM_SPANS; x++) { 11238 if (pris[x].pvts[0]) { 11239 if (start_pri(pris + x)) { 11240 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 11241 return -1; 11242 } else if (option_verbose > 1) 11243 ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1); 11244 } 11245 } 11246 } 11247 #endif 11248 /* And start the monitor for the first time */ 11249 restart_monitor(); 11250 return 0; 11251 }
| static void * ss_thread | ( | void * | data | ) | [static] |
Definition at line 5381 of file chan_zap.c.
References ast_channel::_state, alloc_sub(), ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_CONTROL_RING, AST_CONTROL_UNHOLD, ast_db_put(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_free(), ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_read(), ast_safe_sleep(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), ast_smdi_md_message_wait(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitfor(), ast_waitfordigit(), ast_waitstream(), bump_gains(), zt_pvt::call_forward, callerid_feed(), callerid_feed_jp(), callerid_free(), callerid_get(), callerid_get_dtmf(), callerid_new(), ast_smdi_md_message::calling_st, zt_pvt::callreturn, zt_pvt::callwaiting, zt_pvt::cancallforward, zt_pvt::canpark, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, zt_pvt::cid_name, ast_callerid::cid_num, zt_pvt::cid_num, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, zt_pvt::cid_signalling, zt_pvt::cid_start, CID_START_POLARITY, zt_pvt::context, ast_channel::context, ringContextData::contextData, zt_pvt::defcontext, zt_pvt::dnd, zt_pvt::dop, zt_pvt::drings, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, zt_pvt::dtmfrelax, event2str(), EVENT_FLAG_SYSTEM, ast_channel::exten, zt_pvt::exten, exten, f, free, func, ast_smdi_md_message::fwd_st, ast_channel::hangupcause, zt_pvt::hardwaredtmf, zt_pvt::hidecallerid, zt_pvt::immediate, ISTRUNK, zt_pvt::lastcid_num, len, zt_subchannel::linear, LOG_DEBUG, LOG_NOTICE, manager_event(), my_getsigstr(), name, NEED_MFDETECT, option_debug, option_verbose, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), restore_gains(), distRingData::ring, zt_distRings::ringContext, zt_distRings::ringnum, zt_pvt::ringt, zt_pvt::ringt_base, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::smdi_iface, SMDI_MD_WAIT_TIMEOUT, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech, ast_channel::tech_pvt, timeout, zt_pvt::transfer, ast_smdi_md_message::type, unalloc_sub(), zt_pvt::use_callerid, zt_pvt::use_smdi, zt_pvt::usedistinctiveringdetection, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, zap_tech, zt_subchannel::zfd, zt_enable_ec(), zt_get_event(), zt_get_index(), zt_set_hook(), zt_setlinear(), zt_wait_event(), and zt_wink().
Referenced by handle_init_event(), and zt_handle_event().
05382 { 05383 struct ast_channel *chan = data; 05384 struct zt_pvt *p = chan->tech_pvt; 05385 char exten[AST_MAX_EXTENSION] = ""; 05386 char exten2[AST_MAX_EXTENSION] = ""; 05387 unsigned char buf[256]; 05388 char dtmfcid[300]; 05389 char dtmfbuf[300]; 05390 struct callerid_state *cs = NULL; 05391 char *name = NULL, *number = NULL; 05392 int distMatches; 05393 int curRingData[3]; 05394 int receivedRingT; 05395 int counter1; 05396 int counter; 05397 int samples = 0; 05398 struct ast_smdi_md_message *smdi_msg = NULL; 05399 int flags; 05400 int i; 05401 int timeout; 05402 int getforward = 0; 05403 char *s1, *s2; 05404 int len = 0; 05405 int res; 05406 int index; 05407 05408 /* in the bizarre case where the channel has become a zombie before we 05409 even get started here, abort safely 05410 */ 05411 if (!p) { 05412 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 05413 ast_hangup(chan); 05414 return NULL; 05415 } 05416 05417 if (option_verbose > 2) 05418 ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name); 05419 index = zt_get_index(chan, p, 1); 05420 if (index < 0) { 05421 ast_log(LOG_WARNING, "Huh?\n"); 05422 ast_hangup(chan); 05423 return NULL; 05424 } 05425 if (p->dsp) 05426 ast_dsp_digitreset(p->dsp); 05427 switch (p->sig) { 05428 #ifdef HAVE_PRI 05429 case SIG_PRI: 05430 /* Now loop looking for an extension */ 05431 ast_copy_string(exten, p->exten, sizeof(exten)); 05432 len = strlen(exten); 05433 res = 0; 05434 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05435 if (len && !ast_ignore_pattern(chan->context, exten)) 05436 tone_zone_play_tone(p->subs[index].zfd, -1); 05437 else 05438 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05439 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) 05440 timeout = matchdigittimeout; 05441 else 05442 timeout = gendigittimeout; 05443 res = ast_waitfordigit(chan, timeout); 05444 if (res < 0) { 05445 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05446 ast_hangup(chan); 05447 return NULL; 05448 } else if (res) { 05449 exten[len++] = res; 05450 exten[len] = '\0'; 05451 } else 05452 break; 05453 } 05454 /* if no extension was received ('unspecified') on overlap call, use the 's' extension */ 05455 if (ast_strlen_zero(exten)) { 05456 if (option_verbose > 2) 05457 ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n"); 05458 exten[0] = 's'; 05459 exten[1] = '\0'; 05460 } 05461 tone_zone_play_tone(p->subs[index].zfd, -1); 05462 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 05463 /* Start the real PBX */ 05464 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05465 if (p->dsp) ast_dsp_digitreset(p->dsp); 05466 zt_enable_ec(p); 05467 ast_setstate(chan, AST_STATE_RING); 05468 res = ast_pbx_run(chan); 05469 if (res) { 05470 ast_log(LOG_WARNING, "PBX exited non-zero!\n"); 05471 } 05472 } else { 05473 ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context); 05474 chan->hangupcause = AST_CAUSE_UNALLOCATED; 05475 ast_hangup(chan); 05476 p->exten[0] = '\0'; 05477 /* Since we send release complete here, we won't get one */ 05478 p->call = NULL; 05479 } 05480 return NULL; 05481 break; 05482 #endif 05483 case SIG_FEATD: 05484 case SIG_FEATDMF: 05485 case SIG_FEATDMF_TA: 05486 case SIG_E911: 05487 case SIG_FGC_CAMAMF: 05488 case SIG_FEATB: 05489 case SIG_EMWINK: 05490 case SIG_SF_FEATD: 05491 case SIG_SF_FEATDMF: 05492 case SIG_SF_FEATB: 05493 case SIG_SFWINK: 05494 if (zt_wink(p, index)) 05495 return NULL; 05496 /* Fall through */ 05497 case SIG_EM: 05498 case SIG_EM_E1: 05499 case SIG_SF: 05500 case SIG_FGC_CAMA: 05501 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05502 if (p->dsp) 05503 ast_dsp_digitreset(p->dsp); 05504 /* set digit mode appropriately */ 05505 if (p->dsp) { 05506 if (NEED_MFDETECT(p)) 05507 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05508 else 05509 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05510 } 05511 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 05512 /* Wait for the first digit only if immediate=no */ 05513 if (!p->immediate) 05514 /* Wait for the first digit (up to 5 seconds). */ 05515 res = ast_waitfordigit(chan, 5000); 05516 else 05517 res = 0; 05518 if (res > 0) { 05519 /* save first char */ 05520 dtmfbuf[0] = res; 05521 switch (p->sig) { 05522 case SIG_FEATD: 05523 case SIG_SF_FEATD: 05524 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05525 if (res > 0) 05526 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05527 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05528 break; 05529 case SIG_FEATDMF_TA: 05530 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05531 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05532 if (zt_wink(p, index)) return NULL; 05533 dtmfbuf[0] = 0; 05534 /* Wait for the first digit (up to 5 seconds). */ 05535 res = ast_waitfordigit(chan, 5000); 05536 if (res <= 0) break; 05537 dtmfbuf[0] = res; 05538 /* fall through intentionally */ 05539 case SIG_FEATDMF: 05540 case SIG_E911: 05541 case SIG_FGC_CAMAMF: 05542 case SIG_SF_FEATDMF: 05543 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05544 /* if international caca, do it again to get real ANO */ 05545 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14)) 05546 { 05547 if (zt_wink(p, index)) return NULL; 05548 dtmfbuf[0] = 0; 05549 /* Wait for the first digit (up to 5 seconds). */ 05550 res = ast_waitfordigit(chan, 5000); 05551 if (res <= 0) break; 05552 dtmfbuf[0] = res; 05553 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05554 } 05555 if (res > 0) { 05556 /* if E911, take off hook */ 05557 if (p->sig == SIG_E911) 05558 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05559 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 05560 } 05561 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05562 break; 05563 case SIG_FEATB: 05564 case SIG_SF_FEATB: 05565 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 05566 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05567 break; 05568 case SIG_EMWINK: 05569 /* if we received a '*', we are actually receiving Feature Group D 05570 dial syntax, so use that mode; otherwise, fall through to normal 05571 mode 05572 */ 05573 if (res == '*') { 05574 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 05575 if (res > 0) 05576 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 05577 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 05578 break; 05579 } 05580 default: 05581 /* If we got the first digit, get the rest */ 05582 len = 1; 05583 dtmfbuf[len] = '\0'; 05584 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05585 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 05586 timeout = matchdigittimeout; 05587 } else { 05588 timeout = gendigittimeout; 05589 } 05590 res = ast_waitfordigit(chan, timeout); 05591 if (res < 0) { 05592 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05593 ast_hangup(chan); 05594 return NULL; 05595 } else if (res) { 05596 dtmfbuf[len++] = res; 05597 dtmfbuf[len] = '\0'; 05598 } else { 05599 break; 05600 } 05601 } 05602 break; 05603 } 05604 } 05605 if (res == -1) { 05606 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 05607 ast_hangup(chan); 05608 return NULL; 05609 } else if (res < 0) { 05610 ast_log(LOG_DEBUG, "Got hung up before digits finished\n"); 05611 ast_hangup(chan); 05612 return NULL; 05613 } 05614 05615 if (p->sig == SIG_FGC_CAMA) { 05616 char anibuf[100]; 05617 05618 if (ast_safe_sleep(chan,1000) == -1) { 05619 ast_hangup(chan); 05620 return NULL; 05621 } 05622 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 05623 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 05624 res = my_getsigstr(chan, anibuf, "#", 10000); 05625 if ((res > 0) && (strlen(anibuf) > 2)) { 05626 if (anibuf[strlen(anibuf) - 1] == '#') 05627 anibuf[strlen(anibuf) - 1] = 0; 05628 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 05629 } 05630 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05631 } 05632 05633 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 05634 if (ast_strlen_zero(exten)) 05635 ast_copy_string(exten, "s", sizeof(exten)); 05636 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 05637 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 05638 if (exten[0] == '*') { 05639 char *stringp=NULL; 05640 ast_copy_string(exten2, exten, sizeof(exten2)); 05641 /* Parse out extension and callerid */ 05642 stringp=exten2 +1; 05643 s1 = strsep(&stringp, "*"); 05644 s2 = strsep(&stringp, "*"); 05645 if (s2) { 05646 if (!ast_strlen_zero(p->cid_num)) 05647 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05648 else 05649 ast_set_callerid(chan, s1, NULL, s1); 05650 ast_copy_string(exten, s2, sizeof(exten)); 05651 } else 05652 ast_copy_string(exten, s1, sizeof(exten)); 05653 } else if (p->sig == SIG_FEATD) 05654 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05655 } 05656 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05657 if (exten[0] == '*') { 05658 char *stringp=NULL; 05659 ast_copy_string(exten2, exten, sizeof(exten2)); 05660 /* Parse out extension and callerid */ 05661 stringp=exten2 +1; 05662 s1 = strsep(&stringp, "#"); 05663 s2 = strsep(&stringp, "#"); 05664 if (s2) { 05665 if (!ast_strlen_zero(p->cid_num)) 05666 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05667 else 05668 if (*(s1 + 2)) 05669 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 05670 ast_copy_string(exten, s2 + 1, sizeof(exten)); 05671 } else 05672 ast_copy_string(exten, s1 + 2, sizeof(exten)); 05673 } else 05674 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 05675 } 05676 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) { 05677 if (exten[0] == '*') { 05678 char *stringp=NULL; 05679 ast_copy_string(exten2, exten, sizeof(exten2)); 05680 /* Parse out extension and callerid */ 05681 stringp=exten2 +1; 05682 s1 = strsep(&stringp, "#"); 05683 s2 = strsep(&stringp, "#"); 05684 if (s2 && (*(s2 + 1) == '0')) { 05685 if (*(s2 + 2)) 05686 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 05687 } 05688 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 05689 else ast_copy_string(exten, "911", sizeof(exten)); 05690 } else 05691 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 05692 } 05693 if (p->sig == SIG_FEATB) { 05694 if (exten[0] == '*') { 05695 char *stringp=NULL; 05696 ast_copy_string(exten2, exten, sizeof(exten2)); 05697 /* Parse out extension and callerid */ 05698 stringp=exten2 +1; 05699 s1 = strsep(&stringp, "#"); 05700 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 05701 } else 05702 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 05703 } 05704 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 05705 zt_wink(p, index); 05706 /* some switches require a minimum guard time between 05707 the last FGD wink and something that answers 05708 immediately. This ensures it */ 05709 if (ast_safe_sleep(chan,100)) return NULL; 05710 } 05711 zt_enable_ec(p); 05712 if (NEED_MFDETECT(p)) { 05713 if (p->dsp) { 05714 if (!p->hardwaredtmf) 05715 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 05716 else { 05717 ast_dsp_free(p->dsp); 05718 p->dsp = NULL; 05719 } 05720 } 05721 } 05722 05723 if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) { 05724 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05725 if (p->dsp) ast_dsp_digitreset(p->dsp); 05726 res = ast_pbx_run(chan); 05727 if (res) { 05728 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05729 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05730 } 05731 return NULL; 05732 } else { 05733 if (option_verbose > 2) 05734 ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 05735 sleep(2); 05736 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO); 05737 if (res < 0) 05738 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 05739 else 05740 sleep(1); 05741 res = ast_streamfile(chan, "ss-noservice", chan->language); 05742 if (res >= 0) 05743 ast_waitstream(chan, ""); 05744 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05745 ast_hangup(chan); 05746 return NULL; 05747 } 05748 break; 05749 case SIG_FXOLS: 05750 case SIG_FXOGS: 05751 case SIG_FXOKS: 05752 /* Read the first digit */ 05753 timeout = firstdigittimeout; 05754 /* If starting a threeway call, never timeout on the first digit so someone 05755 can use flash-hook as a "hold" feature */ 05756 if (p->subs[SUB_THREEWAY].owner) 05757 timeout = 999999; 05758 while (len < AST_MAX_EXTENSION-1) { 05759 /* Read digit unless it's supposed to be immediate, in which case the 05760 only answer is 's' */ 05761 if (p->immediate) 05762 res = 's'; 05763 else 05764 res = ast_waitfordigit(chan, timeout); 05765 timeout = 0; 05766 if (res < 0) { 05767 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 05768 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05769 ast_hangup(chan); 05770 return NULL; 05771 } else if (res) { 05772 exten[len++]=res; 05773 exten[len] = '\0'; 05774 } 05775 if (!ast_ignore_pattern(chan->context, exten)) 05776 tone_zone_play_tone(p->subs[index].zfd, -1); 05777 else 05778 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05779 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) { 05780 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 05781 if (getforward) { 05782 /* Record this as the forwarding extension */ 05783 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 05784 if (option_verbose > 2) 05785 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 05786 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05787 if (res) 05788 break; 05789 usleep(500000); 05790 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05791 sleep(1); 05792 memset(exten, 0, sizeof(exten)); 05793 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE); 05794 len = 0; 05795 getforward = 0; 05796 } else { 05797 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05798 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 05799 if (!ast_strlen_zero(p->cid_num)) { 05800 if (!p->hidecallerid) 05801 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 05802 else 05803 ast_set_callerid(chan, NULL, NULL, p->cid_num); 05804 } 05805 if (!ast_strlen_zero(p->cid_name)) { 05806 if (!p->hidecallerid) 05807 ast_set_callerid(chan, NULL, p->cid_name, NULL); 05808 } 05809 ast_setstate(chan, AST_STATE_RING); 05810 zt_enable_ec(p); 05811 res = ast_pbx_run(chan); 05812 if (res) { 05813 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 05814 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05815 } 05816 return NULL; 05817 } 05818 } else { 05819 /* It's a match, but they just typed a digit, and there is an ambiguous match, 05820 so just set the timeout to matchdigittimeout and wait some more */ 05821 timeout = matchdigittimeout; 05822 } 05823 } else if (res == 0) { 05824 ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n"); 05825 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05826 zt_wait_event(p->subs[index].zfd); 05827 ast_hangup(chan); 05828 return NULL; 05829 } else if (p->callwaiting && !strcmp(exten, "*70")) { 05830 if (option_verbose > 2) 05831 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 05832 /* Disable call waiting if enabled */ 05833 p->callwaiting = 0; 05834 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05835 if (res) { 05836 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05837 chan->name, strerror(errno)); 05838 } 05839 len = 0; 05840 ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len); 05841 memset(exten, 0, sizeof(exten)); 05842 timeout = firstdigittimeout; 05843 05844 } else if (!strcmp(exten,ast_pickup_ext())) { 05845 /* Scan all channels and see if any there 05846 * ringing channqels with that have call groups 05847 * that equal this channels pickup group 05848 */ 05849 if (index == SUB_REAL) { 05850 /* Switch us from Third call to Call Wait */ 05851 if (p->subs[SUB_THREEWAY].owner) { 05852 /* If you make a threeway call and the *8# a call, it should actually 05853 look like a callwait */ 05854 alloc_sub(p, SUB_CALLWAIT); 05855 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 05856 unalloc_sub(p, SUB_THREEWAY); 05857 } 05858 zt_enable_ec(p); 05859 if (ast_pickup_call(chan)) { 05860 ast_log(LOG_DEBUG, "No call pickup possible...\n"); 05861 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05862 zt_wait_event(p->subs[index].zfd); 05863 } 05864 ast_hangup(chan); 05865 return NULL; 05866 } else { 05867 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 05868 ast_hangup(chan); 05869 return NULL; 05870 } 05871 05872 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 05873 if (option_verbose > 2) 05874 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 05875 /* Disable Caller*ID if enabled */ 05876 p->hidecallerid = 1; 05877 if (chan->cid.cid_num) 05878 free(chan->cid.cid_num); 05879 chan->cid.cid_num = NULL; 05880 if (chan->cid.cid_name) 05881 free(chan->cid.cid_name); 05882 chan->cid.cid_name = NULL; 05883 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05884 if (res) { 05885 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05886 chan->name, strerror(errno)); 05887 } 05888 len = 0; 05889 memset(exten, 0, sizeof(exten)); 05890 timeout = firstdigittimeout; 05891 } else if (p->callreturn && !strcmp(exten, "*69")) { 05892 res = 0; 05893 if (!ast_strlen_zero(p->lastcid_num)) { 05894 res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language); 05895 } 05896 if (!res) 05897 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05898 break; 05899 } else if (!strcmp(exten, "*78")) { 05900 /* Do not disturb */ 05901 if (option_verbose > 2) 05902 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel); 05903 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 05904 "Channel: Zap/%d\r\n" 05905 "Status: enabled\r\n", p->channel); 05906 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05907 p->dnd = 1; 05908 getforward = 0; 05909 memset(exten, 0, sizeof(exten)); 05910 len = 0; 05911 } else if (!strcmp(exten, "*79")) { 05912 /* Do not disturb */ 05913 if (option_verbose > 2) 05914 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel); 05915 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 05916 "Channel: Zap/%d\r\n" 05917 "Status: disabled\r\n", p->channel); 05918 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05919 p->dnd = 0; 05920 getforward = 0; 05921 memset(exten, 0, sizeof(exten)); 05922 len = 0; 05923 } else if (p->cancallforward && !strcmp(exten, "*72")) { 05924 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05925 getforward = 1; 05926 memset(exten, 0, sizeof(exten)); 05927 len = 0; 05928 } else if (p->cancallforward && !strcmp(exten, "*73")) { 05929 if (option_verbose > 2) 05930 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel); 05931 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05932 memset(p->call_forward, 0, sizeof(p->call_forward)); 05933 getforward = 0; 05934 memset(exten, 0, sizeof(exten)); 05935 len = 0; 05936 } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 05937 p->subs[SUB_THREEWAY].owner && 05938 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 05939 /* This is a three way call, the main call being a real channel, 05940 and we're parking the first call. */ 05941 ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL); 05942 if (option_verbose > 2) 05943 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 05944 break; 05945 } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) { 05946 if (option_verbose > 2) 05947 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num); 05948 res = ast_db_put("blacklist", p->lastcid_num, "1"); 05949 if (!res) { 05950 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05951 memset(exten, 0, sizeof(exten)); 05952 len = 0; 05953 } 05954 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 05955 if (option_verbose > 2) 05956 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 05957 /* Enable Caller*ID if enabled */ 05958 p->hidecallerid = 0; 05959 if (chan->cid.cid_num) 05960 free(chan->cid.cid_num); 05961 chan->cid.cid_num = NULL; 05962 if (chan->cid.cid_name) 05963 free(chan->cid.cid_name); 05964 chan->cid.cid_name = NULL; 05965 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 05966 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL); 05967 if (res) { 05968 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 05969 chan->name, strerror(errno)); 05970 } 05971 len = 0; 05972 memset(exten, 0, sizeof(exten)); 05973 timeout = firstdigittimeout; 05974 } else if (!strcmp(exten, "*0")) { 05975 struct ast_channel *nbridge = 05976 p->subs[SUB_THREEWAY].owner; 05977 struct zt_pvt *pbridge = NULL; 05978 /* set up the private struct of the bridged one, if any */ 05979 if (nbridge && ast_bridged_channel(nbridge)) 05980 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 05981 if (nbridge && pbridge && 05982 (nbridge->tech == &zap_tech) && 05983 (ast_bridged_channel(nbridge)->tech == &zap_tech) && 05984 ISTRUNK(pbridge)) { 05985 int func = ZT_FLASH; 05986 /* Clear out the dial buffer */ 05987 p->dop.dialstr[0] = '\0'; 05988 /* flash hookswitch */ 05989 if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 05990 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 05991 nbridge->name, strerror(errno)); 05992 } 05993 swap_subs(p, SUB_REAL, SUB_THREEWAY); 05994 unalloc_sub(p, SUB_THREEWAY); 05995 p->owner = p->subs[SUB_REAL].owner; 05996 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 05997 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 05998 ast_hangup(chan); 05999 return NULL; 06000 } else { 06001 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06002 zt_wait_event(p->subs[index].zfd); 06003 tone_zone_play_tone(p->subs[index].zfd, -1); 06004 swap_subs(p, SUB_REAL, SUB_THREEWAY); 06005 unalloc_sub(p, SUB_THREEWAY); 06006 p->owner = p->subs[SUB_REAL].owner; 06007 ast_hangup(chan); 06008 return NULL; 06009 } 06010 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 06011 ((exten[0] != '*') || (strlen(exten) > 2))) { 06012 if (option_debug) 06013 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); 06014 break; 06015 } 06016 if (!timeout) 06017 timeout = gendigittimeout; 06018 if (len && !ast_ignore_pattern(chan->context, exten)) 06019 tone_zone_play_tone(p->subs[index].zfd, -1); 06020 } 06021 break; 06022 case SIG_FXSLS: 06023 case SIG_FXSGS: 06024 case SIG_FXSKS: 06025 #ifdef HAVE_PRI 06026 if (p->pri) { 06027 /* This is a GR-303 trunk actually. Wait for the first ring... */ 06028 struct ast_frame *f; 06029 int res; 06030 time_t start; 06031 06032 time(&start); 06033 ast_setstate(chan, AST_STATE_RING); 06034 while (time(NULL) < start + 3) { 06035 res = ast_waitfor(chan, 1000); 06036 if (res) { 06037 f = ast_read(chan); 06038 if (!f) { 06039 ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n"); 06040 ast_hangup(chan); 06041 return NULL; 06042 } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) { 06043 res = 1; 06044 } else 06045 res = 0; 06046 ast_frfree(f); 06047 if (res) { 06048 ast_log(LOG_DEBUG, "Got ring!\n"); 06049 res = 0; 06050 break; 06051 } 06052 } 06053 } 06054 } 06055 #endif 06056 /* check for SMDI messages */ 06057 if (p->use_smdi && p->smdi_iface) { 06058 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT); 06059 06060 if (smdi_msg != NULL) { 06061 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 06062 06063 if (smdi_msg->type == 'B') 06064 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 06065 else if (smdi_msg->type == 'N') 06066 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 06067 06068 ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name); 06069 } else { 06070 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 06071 } 06072 } 06073 06074 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 06075 number = smdi_msg->calling_st; 06076 06077 /* If we want caller id, we're in a prering state due to a polarity reversal 06078 * and we're set to use a polarity reversal to trigger the start of caller id, 06079 * grab the caller id and wait for ringing to start... */ 06080 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) { 06081 /* If set to use DTMF CID signalling, listen for DTMF */ 06082 if (p->cid_signalling == CID_SIG_DTMF) { 06083 int i = 0; 06084 cs = NULL; 06085 ast_log(LOG_DEBUG, "Receiving DTMF cid on " 06086 "channel %s\n", chan->name); 06087 zt_setlinear(p->subs[index].zfd, 0); 06088 res = 2000; 06089 for (;;) { 06090 struct ast_frame *f; 06091 res = ast_waitfor(chan, res); 06092 if (res <= 0) { 06093 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 06094 "Exiting simple switch\n"); 06095 ast_hangup(chan); 06096 return NULL; 06097 } 06098 f = ast_read(chan); 06099 if (f->frametype == AST_FRAME_DTMF) { 06100 dtmfbuf[i++] = f->subclass; 06101 ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass); 06102 res = 2000; 06103 } 06104 ast_frfree(f); 06105 if (chan->_state == AST_STATE_RING || 06106 chan->_state == AST_STATE_RINGING) 06107 break; /* Got ring */ 06108 } 06109 dtmfbuf[i] = '\0'; 06110 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06111 /* Got cid and ring. */ 06112 ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf); 06113 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 06114 ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 06115 dtmfcid, flags); 06116 /* If first byte is NULL, we have no cid */ 06117 if (!ast_strlen_zero(dtmfcid)) 06118 number = dtmfcid; 06119 else 06120 number = NULL; 06121 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 06122 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 06123 cs = callerid_new(p->cid_signalling); 06124 if (cs) { 06125 samples = 0; 06126 #if 1 06127 bump_gains(p); 06128 #endif 06129 /* Take out of linear mode for Caller*ID processing */ 06130 zt_setlinear(p->subs[index].zfd, 0); 06131 06132 /* First we wait and listen for the Caller*ID */ 06133 for (;;) { 06134 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06135 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06136 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06137 callerid_free(cs); 06138 ast_hangup(chan); 06139 return NULL; 06140 } 06141 if (i & ZT_IOMUX_SIGEVENT) { 06142 res = zt_get_event(p->subs[index].zfd); 06143 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06144 06145 if (p->cid_signalling == CID_SIG_V23_JP) { 06146 #ifdef ZT_EVENT_RINGBEGIN 06147 if (res == ZT_EVENT_RINGBEGIN) { 06148 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 06149 usleep(1); 06150 } 06151 #endif 06152 } else { 06153 res = 0; 06154 break; 06155 } 06156 } else if (i & ZT_IOMUX_READ) { 06157 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06158 if (res < 0) { 06159 if (errno != ELAST) { 06160 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06161 callerid_free(cs); 06162 ast_hangup(chan); 06163 return NULL; 06164 } 06165 break; 06166 } 06167 samples += res; 06168 06169 if (p->cid_signalling == CID_SIG_V23_JP) { 06170 res = callerid_feed_jp(cs, buf, res, AST_LAW(p)); 06171 } else { 06172 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06173 } 06174 06175 if (res < 0) { 06176 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06177 break; 06178 } else if (res) 06179 break; 06180 else if (samples > (8000 * 10)) 06181 break; 06182 } 06183 } 06184 if (res == 1) { 06185 callerid_get(cs, &name, &number, &flags); 06186 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06187 } 06188 if (res < 0) { 06189 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06190 } 06191 06192 if (p->cid_signalling == CID_SIG_V23_JP) { 06193 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 06194 usleep(1); 06195 res = 4000; 06196 } else { 06197 06198 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 06199 res = 2000; 06200 } 06201 06202 for (;;) { 06203 struct ast_frame *f; 06204 res = ast_waitfor(chan, res); 06205 if (res <= 0) { 06206 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 06207 "Exiting simple switch\n"); 06208 ast_hangup(chan); 06209 return NULL; 06210 } 06211 f = ast_read(chan); 06212 ast_frfree(f); 06213 if (chan->_state == AST_STATE_RING || 06214 chan->_state == AST_STATE_RINGING) 06215 break; /* Got ring */ 06216 } 06217 06218 /* We must have a ring by now, so, if configured, lets try to listen for 06219 * distinctive ringing */ 06220 if (p->usedistinctiveringdetection == 1) { 06221 len = 0; 06222 distMatches = 0; 06223 /* Clear the current ring data array so we dont have old data in it. */ 06224 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06225 curRingData[receivedRingT] = 0; 06226 receivedRingT = 0; 06227 counter = 0; 06228 counter1 = 0; 06229 /* Check to see if context is what it should be, if not set to be. */ 06230 if (strcmp(p->context,p->defcontext) != 0) { 06231 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06232 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06233 } 06234 06235 for (;;) { 06236 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06237 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06238 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06239 callerid_free(cs); 06240 ast_hangup(chan); 06241 return NULL; 06242 } 06243 if (i & ZT_IOMUX_SIGEVENT) { 06244 res = zt_get_event(p->subs[index].zfd); 06245 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06246 res = 0; 06247 /* Let us detect distinctive ring */ 06248 06249 curRingData[receivedRingT] = p->ringt; 06250 06251 if (p->ringt < p->ringt_base/2) 06252 break; 06253 /* Increment the ringT counter so we can match it against 06254 values in zapata.conf for distinctive ring */ 06255 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06256 break; 06257 } else if (i & ZT_IOMUX_READ) { 06258 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06259 if (res < 0) { 06260 if (errno != ELAST) { 06261 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06262 callerid_free(cs); 06263 ast_hangup(chan); 06264 return NULL; 06265 } 06266 break; 06267 } 06268 if (p->ringt) 06269 p->ringt--; 06270 if (p->ringt == 1) { 06271 res = -1; 06272 break; 06273 } 06274 } 06275 } 06276 if (option_verbose > 2) 06277 /* this only shows up if you have n of the dring patterns filled in */ 06278 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06279 06280 for (counter = 0; counter < 3; counter++) { 06281 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06282 channel */ 06283 distMatches = 0; 06284 for (counter1 = 0; counter1 < 3; counter1++) { 06285 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06286 (p->drings.ringnum[counter].ring[counter1]-10)) { 06287 distMatches++; 06288 } 06289 } 06290 if (distMatches == 3) { 06291 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06292 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06293 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06294 if (option_verbose > 2) 06295 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06296 break; 06297 } 06298 } 06299 } 06300 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06301 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06302 #if 1 06303 restore_gains(p); 06304 #endif 06305 } else 06306 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06307 } else { 06308 ast_log(LOG_WARNING, "Channel %s in prering " 06309 "state, but I have nothing to do. " 06310 "Terminating simple switch, should be " 06311 "restarted by the actual ring.\n", 06312 chan->name); 06313 ast_hangup(chan); 06314 return NULL; 06315 } 06316 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 06317 /* FSK Bell202 callerID */ 06318 cs = callerid_new(p->cid_signalling); 06319 if (cs) { 06320 #if 1 06321 bump_gains(p); 06322 #endif 06323 samples = 0; 06324 len = 0; 06325 distMatches = 0; 06326 /* Clear the current ring data array so we dont have old data in it. */ 06327 for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++) 06328 curRingData[receivedRingT] = 0; 06329 receivedRingT = 0; 06330 counter = 0; 06331 counter1 = 0; 06332 /* Check to see if context is what it should be, if not set to be. */ 06333 if (strcmp(p->context,p->defcontext) != 0) { 06334 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 06335 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 06336 } 06337 06338 /* Take out of linear mode for Caller*ID processing */ 06339 zt_setlinear(p->subs[index].zfd, 0); 06340 for (;;) { 06341 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06342 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06343 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06344 callerid_free(cs); 06345 ast_hangup(chan); 06346 return NULL; 06347 } 06348 if (i & ZT_IOMUX_SIGEVENT) { 06349 res = zt_get_event(p->subs[index].zfd); 06350 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06351 res = 0; 06352 /* Let us detect callerid when the telco uses distinctive ring */ 06353 06354 curRingData[receivedRingT] = p->ringt; 06355 06356 if (p->ringt < p->ringt_base/2) 06357 break; 06358 /* Increment the ringT counter so we can match it against 06359 values in zapata.conf for distinctive ring */ 06360 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06361 break; 06362 } else if (i & ZT_IOMUX_READ) { 06363 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06364 if (res < 0) { 06365 if (errno != ELAST) { 06366 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06367 callerid_free(cs); 06368 ast_hangup(chan); 06369 return NULL; 06370 } 06371 break; 06372 } 06373 if (p->ringt) 06374 p->ringt--; 06375 if (p->ringt == 1) { 06376 res = -1; 06377 break; 06378 } 06379 samples += res; 06380 res = callerid_feed(cs, buf, res, AST_LAW(p)); 06381 if (res < 0) { 06382 ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno)); 06383 break; 06384 } else if (res) 06385 break; 06386 else if (samples > (8000 * 10)) 06387 break; 06388 } 06389 } 06390 if (res == 1) { 06391 callerid_get(cs, &name, &number, &flags); 06392 if (option_debug) 06393 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 06394 } 06395 if (distinctiveringaftercid == 1) { 06396 /* Clear the current ring data array so we dont have old data in it. */ 06397 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) { 06398 curRingData[receivedRingT] = 0; 06399 } 06400 receivedRingT = 0; 06401 if (option_verbose > 2) 06402 ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n"); 06403 for (;;) { 06404 i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT; 06405 if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i))) { 06406 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 06407 callerid_free(cs); 06408 ast_hangup(chan); 06409 return NULL; 06410 } 06411 if (i & ZT_IOMUX_SIGEVENT) { 06412 res = zt_get_event(p->subs[index].zfd); 06413 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 06414 res = 0; 06415 /* Let us detect callerid when the telco uses distinctive ring */ 06416 06417 curRingData[receivedRingT] = p->ringt; 06418 06419 if (p->ringt < p->ringt_base/2) 06420 break; 06421 /* Increment the ringT counter so we can match it against 06422 values in zapata.conf for distinctive ring */ 06423 if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0]))) 06424 break; 06425 } else if (i & ZT_IOMUX_READ) { 06426 res = read(p->subs[index].zfd, buf, sizeof(buf)); 06427 if (res < 0) { 06428 if (errno != ELAST) { 06429 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 06430 callerid_free(cs); 06431 ast_hangup(chan); 06432 return NULL; 06433 } 06434 break; 06435 } 06436 if (p->ringt) 06437 p->ringt--; 06438 if (p->ringt == 1) { 06439 res = -1; 06440 break; 06441 } 06442 } 06443 } 06444 } 06445 if (p->usedistinctiveringdetection == 1) { 06446 if (option_verbose > 2) 06447 /* this only shows up if you have n of the dring patterns filled in */ 06448 ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 06449 06450 for (counter = 0; counter < 3; counter++) { 06451 /* Check to see if the rings we received match any of the ones in zapata.conf for this 06452 channel */ 06453 if (option_verbose > 2) 06454 /* this only shows up if you have n of the dring patterns filled in */ 06455 ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n", 06456 p->drings.ringnum[counter].ring[0], 06457 p->drings.ringnum[counter].ring[1], 06458 p->drings.ringnum[counter].ring[2]); 06459 distMatches = 0; 06460 for (counter1 = 0; counter1 < 3; counter1++) { 06461 if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >= 06462 (p->drings.ringnum[counter].ring[counter1]-10)) { 06463 distMatches++; 06464 } 06465 } 06466 if (distMatches == 3) { 06467 /* The ring matches, set the context to whatever is for distinctive ring.. */ 06468 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context)); 06469 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context)); 06470 if (option_verbose > 2) 06471 ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context); 06472 break; 06473 } 06474 } 06475 } 06476 /* Restore linear mode (if appropriate) for Caller*ID processing */ 06477 zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 06478 #if 1 06479 restore_gains(p); 06480 #endif 06481 if (res < 0) { 06482 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 06483 } 06484 } else 06485 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 06486 } 06487 else 06488 cs = NULL; 06489 06490 if (number) 06491 ast_shrink_phone_number(number); 06492 ast_set_callerid(chan, number, name, number); 06493 06494 if (smdi_msg) 06495 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 06496 06497 if (cs) 06498 callerid_free(cs); 06499 06500 ast_setstate(chan, AST_STATE_RING); 06501 chan->rings = 1; 06502 p->ringt = p->ringt_base; 06503 res = ast_pbx_run(chan); 06504 if (res) { 06505 ast_hangup(chan); 06506 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 06507 } 06508 return NULL; 06509 default: 06510 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 06511 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06512 if (res < 0) 06513 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06514 } 06515 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 06516 if (res < 0) 06517 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 06518 ast_hangup(chan); 06519 return NULL; 06520 }
| static void swap_subs | ( | struct zt_pvt * | p, | |
| int | a, | |||
| int | b | |||
| ) | [static] |
Definition at line 843 of file chan_zap.c.
References ast_log(), zt_subchannel::chan, ast_channel::fds, zt_subchannel::inthreeway, LOG_DEBUG, zt_subchannel::owner, zt_pvt::subs, wakeup_sub(), and zt_subchannel::zfd.
Referenced by attempt_transfer(), ss_thread(), zt_answer(), zt_handle_event(), and zt_hangup().
00844 { 00845 int tchan; 00846 int tinthreeway; 00847 struct ast_channel *towner; 00848 00849 ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b); 00850 00851 tchan = p->subs[a].chan; 00852 towner = p->subs[a].owner; 00853 tinthreeway = p->subs[a].inthreeway; 00854 00855 p->subs[a].chan = p->subs[b].chan; 00856 p->subs[a].owner = p->subs[b].owner; 00857 p->subs[a].inthreeway = p->subs[b].inthreeway; 00858 00859 p->subs[b].chan = tchan; 00860 p->subs[b].owner = towner; 00861 p->subs[b].inthreeway = tinthreeway; 00862 00863 if (p->subs[a].owner) 00864 p->subs[a].owner->fds[0] = p->subs[a].zfd; 00865 if (p->subs[b].owner) 00866 p->subs[b].owner->fds[0] = p->subs[b].zfd; 00867 wakeup_sub(p, a, NULL); 00868 wakeup_sub(p, b, NULL); 00869 }
| static int unalloc_sub | ( | struct zt_pvt * | p, | |
| int | x | |||
| ) | [static] |
Definition at line 963 of file chan_zap.c.
References ast_log(), zt_subchannel::chan, zt_pvt::channel, zt_subchannel::curconf, zt_subchannel::inthreeway, zt_subchannel::linear, LOG_DEBUG, LOG_WARNING, zt_subchannel::owner, zt_pvt::polarity, POLARITY_IDLE, zt_pvt::subs, zt_subchannel::zfd, and zt_close().
00964 { 00965 if (!x) { 00966 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel); 00967 return -1; 00968 } 00969 ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel); 00970 if (p->subs[x].zfd > -1) { 00971 zt_close(p->subs[x].zfd); 00972 } 00973 p->subs[x].zfd = -1; 00974 p->subs[x].linear = 0; 00975 p->subs[x].chan = 0; 00976 p->subs[x].owner = NULL; 00977 p->subs[x].inthreeway = 0; 00978 p->polarity = POLARITY_IDLE; 00979 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf)); 00980 return 0; 00981 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 10351 of file chan_zap.c.
References __unload_module(), ast_mutex_destroy(), and lock.
10352 { 10353 #ifdef HAVE_PRI 10354 int y; 10355 for (y = 0; y < NUM_SPANS; y++) 10356 ast_mutex_destroy(&pris[y].lock); 10357 #endif 10358 return __unload_module(); 10359 }
| static int update_conf | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1349 of file chan_zap.c.
References conf_add(), conf_del(), zt_subchannel::inthreeway, isslavenative(), zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), zt_bridge(), zt_handle_event(), and zt_hangup().
01350 { 01351 int needconf = 0; 01352 int x; 01353 int useslavenative; 01354 struct zt_pvt *slave = NULL; 01355 01356 useslavenative = isslavenative(p, &slave); 01357 /* Start with the obvious, general stuff */ 01358 for (x = 0; x < 3; x++) { 01359 /* Look for three way calls */ 01360 if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) { 01361 conf_add(p, &p->subs[x], x, 0); 01362 needconf++; 01363 } else { 01364 conf_del(p, &p->subs[x], x); 01365 } 01366 } 01367 /* If we have a slave, add him to our conference now. or DAX 01368 if this is slave native */ 01369 for (x = 0; x < MAX_SLAVES; x++) { 01370 if (p->slaves[x]) { 01371 if (useslavenative) 01372 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 01373 else { 01374 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 01375 needconf++; 01376 } 01377 } 01378 } 01379 /* If we're supposed to be in there, do so now */ 01380 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 01381 if (useslavenative) 01382 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 01383 else { 01384 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 01385 needconf++; 01386 } 01387 } 01388 /* If we have a master, add ourselves to his conference */ 01389 if (p->master) { 01390 if (isslavenative(p->master, NULL)) { 01391 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 01392 } else { 01393 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 01394 } 01395 } 01396 if (!needconf) { 01397 /* Nobody is left (or should be left) in our conference. 01398 Kill it. */ 01399 p->confno = -1; 01400 } 01401 if (option_debug) 01402 ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 01403 return 0; 01404 }
| static void wakeup_sub | ( | struct zt_pvt * | p, | |
| int | a, | |||
| void * | pri | |||
| ) | [static] |
Definition at line 783 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_null_frame, ast_queue_frame(), zt_pvt::lock, ast_channel::lock, zt_subchannel::owner, and zt_pvt::subs.
Referenced by swap_subs().
00785 { 00786 #ifdef HAVE_PRI 00787 if (pri) 00788 ast_mutex_unlock(&pri->lock); 00789 #endif 00790 for (;;) { 00791 if (p->subs[a].owner) { 00792 if (ast_mutex_trylock(&p->subs[a].owner->lock)) { 00793 ast_mutex_unlock(&p->lock); 00794 usleep(1); 00795 ast_mutex_lock(&p->lock); 00796 } else { 00797 ast_queue_frame(p->subs[a].owner, &ast_null_frame); 00798 ast_mutex_unlock(&p->subs[a].owner->lock); 00799 break; 00800 } 00801 } else 00802 break; 00803 } 00804 #ifdef HAVE_PRI 00805 if (pri) 00806 ast_mutex_lock(&pri->lock); 00807 #endif 00808 }
| static int zap_destroy_channel | ( | int | fd, | |
| int | argc, | |||
| char ** | argv | |||
| ) | [static] |
Definition at line 9713 of file chan_zap.c.
References RESULT_SHOWUSAGE, and zap_destroy_channel_bynum().
09714 { 09715 int channel; 09716 09717 if (argc != 4) 09718 return RESULT_SHOWUSAGE; 09719 09720 channel = atoi(argv[3]); 09721 09722 return zap_destroy_channel_bynum(channel); 09723 }
| static int zap_destroy_channel_bynum | ( | int | channel | ) | [static] |
Definition at line 6523 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().
06524 { 06525 struct zt_pvt *tmp = NULL; 06526 struct zt_pvt *prev = NULL; 06527 06528 tmp = iflist; 06529 while (tmp) { 06530 if (tmp->channel == channel) { 06531 destroy_channel(prev, tmp, 1); 06532 return RESULT_SUCCESS; 06533 } 06534 prev = tmp; 06535 tmp = tmp->next; 06536 } 06537 return RESULT_FAILURE; 06538 }
| static int zap_fake_event | ( | struct zt_pvt * | p, | |
| int | mode | |||
| ) | [static] |
Definition at line 10101 of file chan_zap.c.
References ast_log(), zt_pvt::fake_event, HANGUP, zt_pvt::owner, and TRANSFER.
Referenced by action_transfer(), and action_transferhangup().
10102 { 10103 if (p) { 10104 switch (mode) { 10105 case TRANSFER: 10106 p->fake_event = ZT_EVENT_WINKFLASH; 10107 break; 10108 case HANGUP: 10109 p->fake_event = ZT_EVENT_ONHOOK; 10110 break; 10111 default: 10112 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name); 10113 } 10114 } 10115 return 0; 10116 }
Definition at line 813 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), f, zt_pvt::lock, ast_channel::lock, and zt_pvt::owner.
Referenced by action_zapdialoffhook().
00815 { 00816 /* We must unlock the PRI to avoid the possibility of a deadlock */ 00817 #ifdef HAVE_PRI 00818 if (pri) 00819 ast_mutex_unlock(&pri->lock); 00820 #endif 00821 for (;;) { 00822 if (p->owner) { 00823 if (ast_mutex_trylock(&p->owner->lock)) { 00824 ast_mutex_unlock(&p->lock); 00825 usleep(1); 00826 ast_mutex_lock(&p->lock); 00827 } else { 00828 ast_queue_frame(p->owner, f); 00829 ast_mutex_unlock(&p->owner->lock); 00830 break; 00831 } 00832 } else 00833 break; 00834 } 00835 #ifdef HAVE_PRI 00836 if (pri) 00837 ast_mutex_lock(&pri->lock); 00838 #endif 00839 }
| static int zap_restart | ( | void | ) | [static] |
Definition at line 9726 of file chan_zap.c.
References ast_log(), ast_verbose(), destroy_channel(), iflist, option_debug, option_verbose, setup_zap(), and VERBOSE_PREFIX_1.
Referenced by action_zaprestart(), and zap_restart_cmd().
09727 { 09728 if (option_verbose > 0) 09729 ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n"); 09730 while (iflist) { 09731 if (option_debug) 09732 ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel); 09733 /* Also updates iflist: */ 09734 destroy_channel(NULL, iflist, 1); 09735 } 09736 if (option_debug) 09737 ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n"); 09738 if (setup_zap(0) != 0) { 09739 ast_log(LOG_WARNING, "Reload channels from zap config failed!\n"); 09740 return 1; 09741 } 09742 return 0; 09743 }
| static int zap_restart_cmd | ( | int | fd, | |
| int | argc, | |||
| char ** | argv | |||
| ) | [static] |
Definition at line 9745 of file chan_zap.c.
References RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and zap_restart().
09746 { 09747 if (argc != 2) { 09748 return RESULT_SHOWUSAGE; 09749 } 09750 09751 if (zap_restart() != 0) 09752 return RESULT_FAILURE; 09753 return RESULT_SUCCESS; 09754 }
| static int zap_show_channel | ( | int | fd, | |
| int | argc, | |||
| char ** | argv | |||
| ) | [static] |
Definition at line 9827 of file chan_zap.c.
References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::callwaitcas, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, zt_pvt::cid_ton, zt_pvt::confno, zt_pvt::context, zt_pvt::destroy, zt_pvt::dialing, zt_pvt::dsp, zt_pvt::dtmfrelax, zt_pvt::echocanbridged, zt_pvt::echocancel, zt_pvt::echocanon, zt_pvt::exten, zt_pvt::faxhandled, iflist, zt_pvt::inalarm, zt_pvt::inconference, zt_subchannel::inthreeway, zt_pvt::law, zt_subchannel::linear, lock, zt_pvt::master, zt_pvt::next, zt_subchannel::owner, zt_pvt::owner, zt_pvt::propconfno, zt_pvt::pulsedial, zt_pvt::radio, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, zt_pvt::sig, sig2str, zt_pvt::slaves, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, and zt_subchannel::zfd.
09828 { 09829 int channel; 09830 struct zt_pvt *tmp = NULL; 09831 ZT_CONFINFO ci; 09832 ZT_PARAMS ps; 09833 int x; 09834 ast_mutex_t *lock; 09835 struct zt_pvt *start; 09836 #ifdef HAVE_PRI 09837 char *c; 09838 int trunkgroup; 09839 struct zt_pri *pri=NULL; 09840 #endif 09841 09842 lock = &iflock; 09843 start = iflist; 09844 09845 if (argc != 4) 09846 return RESULT_SHOWUSAGE; 09847 #ifdef HAVE_PRI 09848 if ((c = strchr(argv[3], ':'))) { 09849 if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2) 09850 return RESULT_SHOWUSAGE; 09851 if ((trunkgroup < 1) || (channel < 1)) 09852 return RESULT_SHOWUSAGE; 09853 for (x = 0; x < NUM_SPANS; x++) { 09854 if (pris[x].trunkgroup == trunkgroup) { 09855 pri = pris + x; 09856 break; 09857 } 09858 } 09859 if (pri) { 09860 start = pri->crvs; 09861 lock = &pri->lock; 09862 } else { 09863 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 09864 return RESULT_FAILURE; 09865 } 09866 } else 09867 #endif 09868 channel = atoi(argv[3]); 09869 09870 ast_mutex_lock(lock); 09871 tmp = start; 09872 while (tmp) { 09873 if (tmp->channel == channel) { 09874 #ifdef HAVE_PRI 09875 if (pri) 09876 ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel); 09877 else 09878 #endif 09879 ast_cli(fd, "Channel: %d\n", tmp->channel); 09880 ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd); 09881 ast_cli(fd, "Span: %d\n", tmp->span); 09882 ast_cli(fd, "Extension: %s\n", tmp->exten); 09883 ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 09884 ast_cli(fd, "Context: %s\n", tmp->context); 09885 ast_cli(fd, "Caller ID: %s\n", tmp->cid_num); 09886 ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton); 09887 ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name); 09888 ast_cli(fd, "Destroy: %d\n", tmp->destroy); 09889 ast_cli(fd, "InAlarm: %d\n", tmp->inalarm); 09890 ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 09891 ast_cli(fd, "Radio: %d\n", tmp->radio); 09892 ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>"); 09893 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)" : ""); 09894 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)" : ""); 09895 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)" : ""); 09896 ast_cli(fd, "Confno: %d\n", tmp->confno); 09897 ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno); 09898 ast_cli(fd, "Real in conference: %d\n", tmp->inconference); 09899 ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 09900 ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 09901 ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 09902 ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown"); 09903 ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 09904 ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 09905 ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF"); 09906 if (tmp->master) 09907 ast_cli(fd, "Master Channel: %d\n", tmp->master->channel); 09908 for (x = 0; x < MAX_SLAVES; x++) { 09909 if (tmp->slaves[x]) 09910 ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 09911 } 09912 #ifdef HAVE_PRI 09913 if (tmp->pri) { 09914 ast_cli(fd, "PRI Flags: "); 09915 if (tmp->resetting) 09916 ast_cli(fd, "Resetting "); 09917 if (tmp->call) 09918 ast_cli(fd, "Call "); 09919 if (tmp->bearer) 09920 ast_cli(fd, "Bearer "); 09921 ast_cli(fd, "\n"); 09922 if (tmp->logicalspan) 09923 ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan); 09924 else 09925 ast_cli(fd, "PRI Logical Span: Implicit\n"); 09926 } 09927 09928 #endif 09929 memset(&ci, 0, sizeof(ci)); 09930 ps.channo = tmp->channel; 09931 if (tmp->subs[SUB_REAL].zfd > -1) { 09932 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) { 09933 ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 09934 } 09935 #ifdef ZT_GETCONFMUTE 09936 if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) { 09937 ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 09938 } 09939 #endif 09940 if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 09941 ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel); 09942 } else { 09943 ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 09944 } 09945 } 09946 ast_mutex_unlock(lock); 09947 return RESULT_SUCCESS; 09948 } 09949 tmp = tmp->next; 09950 } 09951 09952 ast_cli(fd, "Unable to find given channel %d\n", channel); 09953 ast_mutex_unlock(lock); 09954 return RESULT_FAILURE; 09955 }
| static int zap_show_channels | ( | int | fd, | |
| int | argc, | |||
| char ** | argv | |||
| ) | [static] |
Definition at line 9766 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.
09767 { 09768 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 09769 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n" 09770 struct zt_pvt *tmp = NULL; 09771 char tmps[20] = ""; 09772 ast_mutex_t *lock; 09773 struct zt_pvt *start; 09774 #ifdef HAVE_PRI 09775 int trunkgroup; 09776 struct zt_pri *pri = NULL; 09777 int x; 09778 #endif 09779 09780 lock = &iflock; 09781 start = iflist; 09782 09783 #ifdef HAVE_PRI 09784 if (argc == 4) { 09785 if ((trunkgroup = atoi(argv[3])) < 1) 09786 return RESULT_SHOWUSAGE; 09787 for (x = 0; x < NUM_SPANS; x++) { 09788 if (pris[x].trunkgroup == trunkgroup) { 09789 pri = pris + x; 09790 break; 09791 } 09792 } 09793 if (pri) { 09794 start = pri->crvs; 09795 lock = &pri->lock; 09796 } else { 09797 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 09798 return RESULT_FAILURE; 09799 } 09800 } else 09801 #endif 09802 if (argc != 3) 09803 return RESULT_SHOWUSAGE; 09804 09805 ast_mutex_lock(lock); 09806 #ifdef HAVE_PRI 09807 ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret"); 09808 #else 09809 ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret"); 09810 #endif 09811 09812 tmp = start; 09813 while (tmp) { 09814 if (tmp->channel > 0) { 09815 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 09816 } else 09817 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 09818 ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret); 09819 tmp = tmp->next; 09820 } 09821 ast_mutex_unlock(lock); 09822 return RESULT_SUCCESS; 09823 #undef FORMAT 09824 #undef FORMAT2 09825 }
| static int zap_show_status | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 9988 of file chan_zap.c.
References alarms, ast_cli(), ast_log(), FORMAT, FORMAT2, and RESULT_FAILURE.
09988 { 09989 #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n" 09990 #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n" 09991 09992 int span; 09993 int res; 09994 char alarms[50]; 09995 09996 int ctl; 09997 ZT_SPANINFO s; 09998 09999 ctl = open("/dev/zap/ctl", O_RDWR); 10000 if (ctl < 0) { 10001 ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno)); 10002 ast_cli(fd, "No Zaptel interface found.\n"); 10003 return RESULT_FAILURE; 10004 } 10005 ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4"); 10006 10007 for (span = 1; span < ZT_MAX_SPANS; ++span) { 10008 s.spanno = span; 10009 res = ioctl(ctl, ZT_SPANSTAT, &s); 10010 if (res) { 10011 continue; 10012 } 10013 alarms[0] = '\0'; 10014 if (s.alarms > 0) { 10015 if (s.alarms & ZT_ALARM_BLUE) 10016 strcat(alarms, "BLU/"); 10017 if (s.alarms & ZT_ALARM_YELLOW) 10018 strcat(alarms, "YEL/"); 10019 if (s.alarms & ZT_ALARM_RED) 10020 strcat(alarms, "RED/"); 10021 if (s.alarms & ZT_ALARM_LOOPBACK) 10022 strcat(alarms, "LB/"); 10023 if (s.alarms & ZT_ALARM_RECOVER) 10024 strcat(alarms, "REC/"); 10025 if (s.alarms & ZT_ALARM_NOTOPEN) 10026 strcat(alarms, "NOP/"); 10027 if (!strlen(alarms)) 10028 strcat(alarms, "UUU/"); 10029 if (strlen(alarms)) { 10030 /* Strip trailing / */ 10031 alarms[strlen(alarms) - 1] = '\0'; 10032 } 10033 } else { 10034 if (s.numchans) 10035 strcpy(alarms, "OK"); 10036 else 10037 strcpy(alarms, "UNCONFIGURED"); 10038 } 10039 10040 ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count); 10041 } 10042 close(ctl); 10043 10044 return RESULT_SUCCESS; 10045 #undef FORMAT 10046 #undef FORMAT2 10047 }
| static char* zap_sig2str | ( | int | sig | ) | [static] |
Definition at line 1159 of file chan_zap.c.
References SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_GR303FXOKS, SIG_GR303FXSKS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, and SIG_SFWINK.
01160 { 01161 static char buf[256]; 01162 switch (sig) { 01163 case SIG_EM: 01164 return "E & M Immediate"; 01165 case SIG_EMWINK: 01166 return "E & M Wink"; 01167 case SIG_EM_E1: 01168 return "E & M E1"; 01169 case SIG_FEATD: 01170 return "Feature Group D (DTMF)"; 01171 case SIG_FEATDMF: 01172 return "Feature Group D (MF)"; 01173 case SIG_FEATDMF_TA: 01174 return "Feature Groud D (MF) Tandem Access"; 01175 case SIG_FEATB: 01176 return "Feature Group B (MF)"; 01177 case SIG_E911: 01178 return "E911 (MF)"; 01179 case SIG_FGC_CAMA: 01180 return "FGC/CAMA (Dialpulse)"; 01181 case SIG_FGC_CAMAMF: 01182 return "FGC/CAMA (MF)"; 01183 case SIG_FXSLS: 01184 return "FXS Loopstart"; 01185 case SIG_FXSGS: 01186 return "FXS Groundstart"; 01187 case SIG_FXSKS: 01188 return "FXS Kewlstart"; 01189 case SIG_FXOLS: 01190 return "FXO Loopstart"; 01191 case SIG_FXOGS: 01192 return "FXO Groundstart"; 01193 case SIG_FXOKS: 01194 return "FXO Kewlstart"; 01195 case SIG_PRI: 01196 return "PRI Signalling"; 01197 case SIG_SF: 01198 return "SF (Tone) Signalling Immediate"; 01199 case SIG_SFWINK: 01200 return "SF (Tone) Signalling Wink"; 01201 case SIG_SF_FEATD: 01202 return "SF (Tone) Signalling with Feature Group D (DTMF)"; 01203 case SIG_SF_FEATDMF: 01204 return "SF (Tone) Signalling with Feature Group D (MF)"; 01205 case SIG_SF_FEATB: 01206 return "SF (Tone) Signalling with Feature Group B (MF)"; 01207 case SIG_GR303FXOKS: 01208 return "GR-303 Signalling with FXOKS"; 01209 case SIG_GR303FXSKS: 01210 return "GR-303 Signalling with FXSKS"; 01211 case 0: 01212 return "Pseudo Signalling"; 01213 default: 01214 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig); 01215 return buf; 01216 } 01217 }
| static int zt_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2728 of file chan_zap.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, zt_pvt::channel, zt_pvt::dialing, zt_pvt::digital, zt_pvt::hanguponpolarityswitch, zt_subchannel::inthreeway, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::oprmode, zt_subchannel::owner, zt_pvt::owner, zt_pvt::polaritydelaytv, zt_pvt::radio, zt_pvt::ringt, zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::span, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_subchannel::zfd, zt_enable_ec(), zt_get_index(), zt_set_hook(), and zt_train_ec().
02729 { 02730 struct zt_pvt *p = ast->tech_pvt; 02731 int res = 0; 02732 int index; 02733 int oldstate = ast->_state; 02734 ast_setstate(ast, AST_STATE_UP); 02735 ast_mutex_lock(&p->lock); 02736 index = zt_get_index(ast, p, 0); 02737 if (index < 0) 02738 index = SUB_REAL; 02739 /* nothing to do if a radio channel */ 02740 if ((p->radio || (p->oprmode < 0))) { 02741 ast_mutex_unlock(&p->lock); 02742 return 0; 02743 } 02744 switch (p->sig) { 02745 case SIG_FXSLS: 02746 case SIG_FXSGS: 02747 case SIG_FXSKS: 02748 p->ringt = 0; 02749 /* Fall through */ 02750 case SIG_EM: 02751 case SIG_EM_E1: 02752 case SIG_EMWINK: 02753 case SIG_FEATD: 02754 case SIG_FEATDMF: 02755 case SIG_FEATDMF_TA: 02756 case SIG_E911: 02757 case SIG_FGC_CAMA: 02758 case SIG_FGC_CAMAMF: 02759 case SIG_FEATB: 02760 case SIG_SF: 02761 case SIG_SFWINK: 02762 case SIG_SF_FEATD: 02763 case SIG_SF_FEATDMF: 02764 case SIG_SF_FEATB: 02765 case SIG_FXOLS: 02766 case SIG_FXOGS: 02767 case SIG_FXOKS: 02768 /* Pick up the line */ 02769 ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name); 02770 if (p->hanguponpolarityswitch) { 02771 gettimeofday(&p->polaritydelaytv, NULL); 02772 } 02773 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); 02774 tone_zone_play_tone(p->subs[index].zfd, -1); 02775 p->dialing = 0; 02776 if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) { 02777 if (oldstate == AST_STATE_RINGING) { 02778 ast_log(LOG_DEBUG, "Finally swapping real and threeway\n"); 02779 tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1); 02780 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02781 p->owner = p->subs[SUB_REAL].owner; 02782 } 02783 } 02784 if (p->sig & __ZT_SIG_FXS) { 02785 zt_enable_ec(p); 02786 zt_train_ec(p); 02787 } 02788 break; 02789 #ifdef HAVE_PRI 02790 case SIG_PRI: 02791 /* Send a pri acknowledge */ 02792 if (!pri_grab(p, p->pri)) { 02793 p->proceeding = 1; 02794 res = pri_answer(p->pri->pri, p->call, 0, !p->digital); 02795 pri_rel(p->pri); 02796 } else { 02797 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02798 res = -1; 02799 } 02800 break; 02801 #endif 02802 case 0: 02803 ast_mutex_unlock(&p->lock); 02804 return 0; 02805 default: 02806 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 02807 res = -1; 02808 } 02809 ast_mutex_unlock(&p->lock); 02810 return res; 02811 }
| static enum ast_bridge_result zt_bridge | ( | struct ast_channel * | c0, | |
| struct ast_channel * | c1, | |||
| int | flags, | |||
| struct ast_frame ** | fo, | |||
| struct ast_channel ** | rc, | |||
| int | timeoutms | |||
| ) | [static] |
Definition at line 3133 of file chan_zap.c.
References ast_channel::_state, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_read(), AST_STATE_RINGING, ast_verbose(), ast_waitfor_n(), ast_write(), zt_pvt::channel, disable_dtmf_detect(), zt_pvt::echocanbridged, enable_dtmf_detect(), f, ast_channel::fds, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, master, option_verbose, zt_subchannel::owner, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::sig, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, ast_channel::tech_pvt, zt_pvt::transfer, update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), zt_get_index(), zt_link(), and zt_unlink().
03134 { 03135 struct ast_channel *who; 03136 struct zt_pvt *p0, *p1, *op0, *op1; 03137 struct zt_pvt *master = NULL, *slave = NULL; 03138 struct ast_frame *f; 03139 int inconf = 0; 03140 int nothingok = 1; 03141 int ofd0, ofd1; 03142 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 03143 int os0 = -1, os1 = -1; 03144 int priority = 0; 03145 struct ast_channel *oc0, *oc1; 03146 enum ast_bridge_result res; 03147 03148 #ifdef PRI_2BCT 03149 int triedtopribridge = 0; 03150 q931_call *q931c0 = NULL, *q931c1 = NULL; 03151 #endif 03152 03153 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 03154 There is code below to handle it properly until DTMF is actually seen, 03155 but due to currently unresolved issues it's ignored... 03156 */ 03157 03158 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 03159 return AST_BRIDGE_FAILED_NOWARN; 03160 03161 ast_mutex_lock(&c0->lock); 03162 ast_mutex_lock(&c1->lock); 03163 03164 p0 = c0->tech_pvt; 03165 p1 = c1->tech_pvt; 03166 /* cant do pseudo-channels here */ 03167 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 03168 ast_mutex_unlock(&c0->lock); 03169 ast_mutex_unlock(&c1->lock); 03170 return AST_BRIDGE_FAILED_NOWARN; 03171 } 03172 03173 oi0 = zt_get_index(c0, p0, 0); 03174 oi1 = zt_get_index(c1, p1, 0); 03175 if ((oi0 < 0) || (oi1 < 0)) { 03176 ast_mutex_unlock(&c0->lock); 03177 ast_mutex_unlock(&c1->lock); 03178 return AST_BRIDGE_FAILED; 03179 } 03180 03181 op0 = p0 = c0->tech_pvt; 03182 op1 = p1 = c1->tech_pvt; 03183 ofd0 = c0->fds[0]; 03184 ofd1 = c1->fds[0]; 03185 oc0 = p0->owner; 03186 oc1 = p1->owner; 03187 03188 if (ast_mutex_trylock(&p0->lock)) { 03189 /* Don't block, due to potential for deadlock */ 03190 ast_mutex_unlock(&c0->lock); 03191 ast_mutex_unlock(&c1->lock); 03192 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03193 return AST_BRIDGE_RETRY; 03194 } 03195 if (ast_mutex_trylock(&p1->lock)) { 03196 /* Don't block, due to potential for deadlock */ 03197 ast_mutex_unlock(&p0->lock); 03198 ast_mutex_unlock(&c0->lock); 03199 ast_mutex_unlock(&c1->lock); 03200 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 03201 return AST_BRIDGE_RETRY; 03202 } 03203 03204 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03205 if (p0->owner && p1->owner) { 03206 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 03207 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 03208 master = p0; 03209 slave = p1; 03210 inconf = 1; 03211 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 03212 master = p1; 03213 slave = p0; 03214 inconf = 1; 03215 } else { 03216 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 03217 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 03218 p0->channel, 03219 oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03220 p0->subs[SUB_REAL].inthreeway, p0->channel, 03221 oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0, 03222 p1->subs[SUB_REAL].inthreeway); 03223 } 03224 nothingok = 0; 03225 } 03226 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 03227 if (p1->subs[SUB_THREEWAY].inthreeway) { 03228 master = p1; 03229 slave = p0; 03230 nothingok = 0; 03231 } 03232 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 03233 if (p0->subs[SUB_THREEWAY].inthreeway) { 03234 master = p0; 03235 slave = p1; 03236 nothingok = 0; 03237 } 03238 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 03239 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 03240 don't put us in anything */ 03241 if (p1->subs[SUB_CALLWAIT].inthreeway) { 03242 master = p1; 03243 slave = p0; 03244 nothingok = 0; 03245 } 03246 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 03247 /* Same as previous */ 03248 if (p0->subs[SUB_CALLWAIT].inthreeway) { 03249 master = p0; 03250 slave = p1; 03251 nothingok = 0; 03252 } 03253 } 03254 ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n", 03255 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 03256 if (master && slave) { 03257 /* Stop any tones, or play ringtone as appropriate. If they're bridged 03258 in an active threeway call with a channel that is ringing, we should 03259 indicate ringing. */ 03260 if ((oi1 == SUB_THREEWAY) && 03261 p1->subs[SUB_THREEWAY].inthreeway && 03262 p1->subs[SUB_REAL].owner && 03263 p1->subs[SUB_REAL].inthreeway && 03264 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03265 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name); 03266 tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE); 03267 os1 = p1->subs[SUB_REAL].owner->_state; 03268 } else { 03269 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1); 03270 tone_zone_play_tone(p0->subs[oi0].zfd, -1); 03271 } 03272 if ((oi0 == SUB_THREEWAY) && 03273 p0->subs[SUB_THREEWAY].inthreeway && 03274 p0->subs[SUB_REAL].owner && 03275 p0->subs[SUB_REAL].inthreeway && 03276 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 03277 ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name); 03278 tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE); 03279 os0 = p0->subs[SUB_REAL].owner->_state; 03280 } else { 03281 ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0); 03282 tone_zone_play_tone(p1->subs[oi0].zfd, -1); 03283 } 03284 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 03285 if (!p0->echocanbridged || !p1->echocanbridged) { 03286 /* Disable echo cancellation if appropriate */ 03287 zt_disable_ec(p0); 03288 zt_disable_ec(p1); 03289 } 03290 } 03291 zt_link(slave, master); 03292 master->inconference = inconf; 03293 } else if (!nothingok) 03294 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 03295 03296 update_conf(p0); 03297 update_conf(p1); 03298 t0 = p0->subs[SUB_REAL].inthreeway; 03299 t1 = p1->subs[SUB_REAL].inthreeway; 03300 03301 ast_mutex_unlock(&p0->lock); 03302 ast_mutex_unlock(&p1->lock); 03303 03304 ast_mutex_unlock(&c0->lock); 03305 ast_mutex_unlock(&c1->lock); 03306 03307 /* Native bridge failed */ 03308 if ((!master || !slave) && !nothingok) { 03309 zt_enable_ec(p0); 03310 zt_enable_ec(p1); 03311 return AST_BRIDGE_FAILED; 03312 } 03313 03314 if (option_verbose > 2) 03315 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 03316 03317 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03318 disable_dtmf_detect(op0); 03319 03320 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03321 disable_dtmf_detect(op1); 03322 03323 for (;;) { 03324 struct ast_channel *c0_priority[2] = {c0, c1}; 03325 struct ast_channel *c1_priority[2] = {c1, c0}; 03326 03327 /* Here's our main loop... Start by locking things, looking for private parts, 03328 and then balking if anything is wrong */ 03329 ast_mutex_lock(&c0->lock); 03330 ast_mutex_lock(&c1->lock); 03331 p0 = c0->tech_pvt; 03332 p1 = c1->tech_pvt; 03333 03334 if (op0 == p0) 03335 i0 = zt_get_index(c0, p0, 1); 03336 if (op1 == p1) 03337 i1 = zt_get_index(c1, p1, 1); 03338 ast_mutex_unlock(&c0->lock); 03339 ast_mutex_unlock(&c1->lock); 03340 03341 if (!timeoutms || 03342 (op0 != p0) || 03343 (op1 != p1) || 03344 (ofd0 != c0->fds[0]) || 03345 (ofd1 != c1->fds[0]) || 03346 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 03347 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 03348 (oc0 != p0->owner) || 03349 (oc1 != p1->owner) || 03350 (t0 != p0->subs[SUB_REAL].inthreeway) || 03351 (t1 != p1->subs[SUB_REAL].inthreeway) || 03352 (oi0 != i0) || 03353 (oi1 != i1)) { 03354 ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 03355 op0->channel, oi0, op1->channel, oi1); 03356 res = AST_BRIDGE_RETRY; 03357 goto return_from_bridge; 03358 } 03359 03360 #ifdef PRI_2BCT 03361 q931c0 = p0->call; 03362 q931c1 = p1->call; 03363 if (p0->transfer && p1->transfer 03364 && q931c0 && q931c1 03365 && !triedtopribridge) { 03366 pri_channel_bridge(q931c0, q931c1); 03367 triedtopribridge = 1; 03368 } 03369 #endif 03370 03371 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms); 03372 if (!who) { 03373 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 03374 continue; 03375 } 03376 f = ast_read(who); 03377 if (!f || (f->frametype == AST_FRAME_CONTROL)) { 03378 *fo = f; 03379 *rc = who; 03380 res = AST_BRIDGE_COMPLETE; 03381 goto return_from_bridge; 03382 } 03383 if (f->frametype == AST_FRAME_DTMF) { 03384 if ((who == c0) && p0->pulsedial) { 03385 ast_write(c1, f); 03386 } else if ((who == c1) && p1->pulsedial) { 03387 ast_write(c0, f); 03388 } else { 03389 *fo = f; 03390 *rc = who; 03391 res = AST_BRIDGE_COMPLETE; 03392 goto return_from_bridge; 03393 } 03394 } 03395 ast_frfree(f); 03396 03397 /* Swap who gets priority */ 03398 priority = !priority; 03399 } 03400 03401 return_from_bridge: 03402 if (op0 == p0) 03403 zt_enable_ec(p0); 03404 03405 if (op1 == p1) 03406 zt_enable_ec(p1); 03407 03408 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 03409 enable_dtmf_detect(op0); 03410 03411 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 03412 enable_dtmf_detect(op1); 03413 03414 zt_unlink(slave, master, 1); 03415 03416 return res; 03417 }
| static int zt_call | ( | struct ast_channel * | ast, | |
| char * | rdest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 1765 of file chan_zap.c.
References ast_channel::_state, ast_callerid_generate(), AST_LAW, ast_log(), ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), zt_pvt::callwait_name, zt_pvt::callwait_num, zt_pvt::callwaitcas, zt_pvt::callwaitrings, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::dialdest, zt_pvt::dialednone, zt_pvt::dialing, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::dop, zt_pvt::echobreak, zt_pvt::echorest, zt_pvt::echotraining, zt_pvt::finaldial, free, zt_pvt::hidecallerid, zt_pvt::hidecalleridname, IS_DIGITAL, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_pvt::law, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_CALLERID_SIZE, zt_subchannel::needbusy, zt_subchannel::needringing, zt_pvt::oprmode, option_verbose, zt_pvt::outgoing, zt_pvt::outsigmod, zt_pvt::owner, pbx_builtin_getvar_helper(), PRI_TRANS_CAP_DIGITAL, zt_pvt::priexclusive, zt_pvt::pulse, zt_pvt::radio, zt_pvt::rxgain, s, send_callerid(), zt_pvt::sendcalleridafter, set_actual_gain(), zt_pvt::sig, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, zt_pvt::stripmsd, SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, ast_channel::transfercapability, zt_pvt::txgain, zt_pvt::use_callerid, zt_pvt::use_callingpres, VERBOSE_PREFIX_3, zt_pvt::whichwink, zt_subchannel::zfd, zt_callwait(), and zt_get_index().
01766 { 01767 struct zt_pvt *p = ast->tech_pvt; 01768 int x, res, index,mysig; 01769 char *c, *n, *l; 01770 #ifdef HAVE_PRI 01771 char *s = NULL; 01772 #endif 01773 char dest[256]; /* must be same length as p->dialdest */ 01774 ast_mutex_lock(&p->lock); 01775 ast_copy_string(dest, rdest, sizeof(dest)); 01776 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 01777 if ((ast->_state == AST_STATE_BUSY)) { 01778 p->subs[SUB_REAL].needbusy = 1; 01779 ast_mutex_unlock(&p->lock); 01780 return 0; 01781 } 01782 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 01783 ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name); 01784 ast_mutex_unlock(&p->lock); 01785 return -1; 01786 } 01787 p->dialednone = 0; 01788 if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */ 01789 { 01790 /* Special pseudo -- automatically up */ 01791 ast_setstate(ast, AST_STATE_UP); 01792 ast_mutex_unlock(&p->lock); 01793 return 0; 01794 } 01795 x = ZT_FLUSH_READ | ZT_FLUSH_WRITE; 01796 res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x); 01797 if (res) 01798 ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel); 01799 p->outgoing = 1; 01800 01801 set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law); 01802 01803 mysig = p->sig; 01804 if (p->outsigmod > -1) 01805 mysig = p->outsigmod; 01806 01807 switch (mysig) { 01808 case SIG_FXOLS: 01809 case SIG_FXOGS: 01810 case SIG_FXOKS: 01811 if (p->owner == ast) { 01812 /* Normal ring, on hook */ 01813 01814 /* Don't send audio while on hook, until the call is answered */ 01815 p->dialing = 1; 01816 if (p->use_callerid) { 01817 /* Generate the Caller-ID spill if desired */ 01818 if (p->cidspill) { 01819 ast_log(LOG_WARNING, "cidspill already exists??\n"); 01820 free(p->cidspill); 01821 } 01822 p->callwaitcas = 0; 01823 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) { 01824 p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p)); 01825 p->cidpos = 0; 01826 send_callerid(p); 01827 } 01828 } 01829 /* Choose proper cadence */ 01830 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) { 01831 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1])) 01832 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name); 01833 p->cidrings = cidrings[p->distinctivering - 1]; 01834 } else { 01835 if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL)) 01836 ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name); 01837 p->cidrings = p->sendcalleridafter; 01838 } 01839 01840 /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */ 01841 c = strchr(dest, '/'); 01842 if (c) 01843 c++; 01844 if (c && (strlen(c) < p->stripmsd)) { 01845 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01846 c = NULL; 01847 } 01848 if (c) { 01849 p->dop.op = ZT_DIAL_OP_REPLACE; 01850 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c); 01851 ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c); 01852 } else { 01853 p->dop.dialstr[0] = '\0'; 01854 } 01855 x = ZT_RING; 01856 if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) { 01857 ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno)); 01858 ast_mutex_unlock(&p->lock); 01859 return -1; 01860 } 01861 p->dialing = 1; 01862 } else { 01863 /* Call waiting call */ 01864 p->callwaitrings = 0; 01865 if (ast->cid.cid_num) 01866 ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num)); 01867 else 01868 p->callwait_num[0] = '\0'; 01869 if (ast->cid.cid_name) 01870 ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name)); 01871 else 01872 p->callwait_name[0] = '\0'; 01873 /* Call waiting tone instead */ 01874 if (zt_callwait(ast)) { 01875 ast_mutex_unlock(&p->lock); 01876 return -1; 01877 } 01878 /* Make ring-back */ 01879 if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE)) 01880 ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name); 01881 01882 } 01883 n = ast->cid.cid_name; 01884 l = ast->cid.cid_num; 01885 if (l) 01886 ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num)); 01887 else 01888 p->lastcid_num[0] = '\0'; 01889 if (n) 01890 ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name)); 01891 else 01892 p->lastcid_name[0] = '\0'; 01893 ast_setstate(ast, AST_STATE_RINGING); 01894 index = zt_get_index(ast, p, 0); 01895 if (index > -1) { 01896 p->subs[index].needringing = 1; 01897 } 01898 break; 01899 case SIG_FXSLS: 01900 case SIG_FXSGS: 01901 case SIG_FXSKS: 01902 case SIG_EMWINK: 01903 case SIG_EM: 01904 case SIG_EM_E1: 01905 case SIG_FEATD: 01906 case SIG_FEATDMF: 01907 case SIG_E911: 01908 case SIG_FGC_CAMA: 01909 case SIG_FGC_CAMAMF: 01910 case SIG_FEATB: 01911 case SIG_SFWINK: 01912 case SIG_SF: 01913 case SIG_SF_FEATD: 01914 case SIG_SF_FEATDMF: 01915 case SIG_FEATDMF_TA: 01916 case SIG_SF_FEATB: 01917 c = strchr(dest, '/'); 01918 if (c) 01919 c++; 01920 else 01921 c = ""; 01922 if (strlen(c) < p->stripmsd) { 01923 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01924 ast_mutex_unlock(&p->lock); 01925 return -1; 01926 } 01927 #ifdef HAVE_PRI 01928 /* Start the trunk, if not GR-303 */ 01929 if (!p->pri) { 01930 #endif 01931 x = ZT_START; 01932 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 01933 if (res < 0) { 01934 if (errno != EINPROGRESS) { 01935 ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno)); 01936 ast_mutex_unlock(&p->lock); 01937 return -1; 01938 } 01939 } 01940 #ifdef HAVE_PRI 01941 } 01942 #endif 01943 ast_log(LOG_DEBUG, "Dialing '%s'\n", c); 01944 p->dop.op = ZT_DIAL_OP_REPLACE; 01945 01946 c += p->stripmsd; 01947 01948 switch (mysig) { 01949 case SIG_FEATD: 01950 l = ast->cid.cid_num; 01951 if (l) 01952 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c); 01953 else 01954 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c); 01955 break; 01956 case SIG_FEATDMF: 01957 l = ast->cid.cid_num; 01958 if (l) 01959 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c); 01960 else 01961 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c); 01962 break; 01963 case SIG_FEATDMF_TA: 01964 { 01965 const char *cic, *ozz; 01966 01967 /* If you have to go through a Tandem Access point you need to use this */ 01968 ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ"); 01969 if (!ozz) 01970 ozz = defaultozz; 01971 cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC"); 01972 if (!cic) 01973 cic = defaultcic; 01974 if (!ozz || !cic) { 01975 ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n"); 01976 ast_mutex_unlock(&p->lock); 01977 return -1; 01978 } 01979 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic); 01980 snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c); 01981 p->whichwink = 0; 01982 } 01983 break; 01984 case SIG_E911: 01985 ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr)); 01986 break; 01987 case SIG_FGC_CAMA: 01988 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c); 01989 break; 01990 case SIG_FGC_CAMAMF: 01991 case SIG_FEATB: 01992 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c); 01993 break; 01994 default: 01995 if (p->pulse) 01996 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c); 01997 else 01998 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c); 01999 break; 02000 } 02001 02002 if (p->echotraining && (strlen(p->dop.dialstr) > 4)) { 02003 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 02004 strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 02005 p->echorest[sizeof(p->echorest) - 1] = '\0'; 02006 p->echobreak = 1; 02007 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 02008 } else 02009 p->echobreak = 0; 02010 if (!res) { 02011 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 02012 x = ZT_ONHOOK; 02013 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 02014 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 02015 ast_mutex_unlock(&p->lock); 02016 return -1; 02017 } 02018 } else 02019 ast_log(LOG_DEBUG, "Deferring dialing...\n"); 02020 p->dialing = 1; 02021 if (ast_strlen_zero(c)) 02022 p->dialednone = 1; 02023 ast_setstate(ast, AST_STATE_DIALING); 02024 break; 02025 case 0: 02026 /* Special pseudo -- automatically up*/ 02027 ast_setstate(ast, AST_STATE_UP); 02028 break; 02029 case SIG_PRI: 02030 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ 02031 p->dialdest[0] = '\0'; 02032 break; 02033 default: 02034 ast_log(LOG_DEBUG, "not yet implemented\n"); 02035 ast_mutex_unlock(&p->lock); 02036 return -1; 02037 } 02038 #ifdef HAVE_PRI 02039 if (p->pri) { 02040 struct pri_sr *sr; 02041 #ifdef SUPPORT_USERUSER 02042 const char *useruser; 02043 #endif 02044 int pridialplan; 02045 int dp_strip; 02046 int prilocaldialplan; 02047 int ldp_strip; 02048 int exclusive; 02049 const char *rr_str; 02050 int redirect_reason; 02051 02052 c = strchr(dest, '/'); 02053 if (c) 02054 c++; 02055 else 02056 c = dest; 02057 if (!p->hidecalleridname) 02058 n = ast->cid.cid_name; 02059 else 02060 n = NULL; 02061 if (!p->hidecallerid) { 02062 l = ast->cid.cid_num; 02063 n = ast->cid.cid_name; 02064 } else { 02065 l = NULL; 02066 n = NULL; 02067 } 02068 if (strlen(c) < p->stripmsd) { 02069 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 02070 ast_mutex_unlock(&p->lock); 02071 return -1; 02072 } 02073 if (mysig != SIG_FXSKS) { 02074 p->dop.op = ZT_DIAL_OP_REPLACE; 02075 s = strchr(c + p->stripmsd, 'w'); 02076 if (s) { 02077 if (strlen(s) > 1) 02078 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s); 02079 else 02080 p->dop.dialstr[0] = '\0'; 02081 *s = '\0'; 02082 } else { 02083 p->dop.dialstr[0] = '\0'; 02084 } 02085 } 02086 if (pri_grab(p, p->pri)) { 02087 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 02088 ast_mutex_unlock(&p->lock); 02089 return -1; 02090 } 02091 if (!(p->call = pri_new_call(p->pri->pri))) { 02092 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel); 02093 pri_rel(p->pri); 02094 ast_mutex_unlock(&p->lock); 02095 return -1; 02096 } 02097 if (!(sr = pri_sr_new())) { 02098 ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel); 02099 pri_rel(p->pri); 02100 ast_mutex_unlock(&p->lock); 02101 } 02102 if (p->bearer || (mysig == SIG_FXSKS)) { 02103 if (p->bearer) { 02104 ast_log(LOG_DEBUG, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel); 02105 p->bearer->call = p->call; 02106 } else 02107 ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n"); 02108 pri_set_crv(p->pri->pri, p->call, p->channel, 0); 02109 } 02110 p->digital = IS_DIGITAL(ast->transfercapability); 02111 /* Add support for exclusive override */ 02112 if (p->priexclusive) 02113 exclusive = 1; 02114 else { 02115 /* otherwise, traditional behavior */ 02116 if (p->pri->nodetype == PRI_NETWORK) 02117 exclusive = 0; 02118 else 02119 exclusive = 1; 02120 } 02121 02122 pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1); 02123 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 02124 (p->digital ? -1 : 02125 ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW))); 02126 if (p->pri->facilityenable) 02127 pri_facility_enable(p->pri->pri); 02128 02129 if (option_verbose > 2) 02130 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); 02131 dp_strip = 0; 02132 pridialplan = p->pri->dialplan - 1; 02133 if (pridialplan == -2) { /* compute dynamically */ 02134 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02135 dp_strip = strlen(p->pri->internationalprefix); 02136 pridialplan = PRI_INTERNATIONAL_ISDN; 02137 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02138 dp_strip = strlen(p->pri->nationalprefix); 02139 pridialplan = PRI_NATIONAL_ISDN; 02140 } else { 02141 pridialplan = PRI_LOCAL_ISDN; 02142 } 02143 } 02144 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0); 02145 02146 ldp_strip = 0; 02147 prilocaldialplan = p->pri->localdialplan - 1; 02148 if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */ 02149 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 02150 ldp_strip = strlen(p->pri->internationalprefix); 02151 prilocaldialplan = PRI_INTERNATIONAL_ISDN; 02152 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 02153 ldp_strip = strlen(p->pri->nationalprefix); 02154 prilocaldialplan = PRI_NATIONAL_ISDN; 02155 } else { 02156 prilocaldialplan = PRI_LOCAL_ISDN; 02157 } 02158 } 02159 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, 02160 p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); 02161 if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) { 02162 if (!strcasecmp(rr_str, "UNKNOWN")) 02163 redirect_reason = 0; 02164 else if (!strcasecmp(rr_str, "BUSY")) 02165 redirect_reason = 1; 02166 else if (!strcasecmp(rr_str, "NO_REPLY")) 02167 redirect_reason = 2; 02168 else if (!strcasecmp(rr_str, "UNCONDITIONAL")) 02169 redirect_reason = 15; 02170 else 02171 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02172 } else 02173 redirect_reason = PRI_REDIR_UNCONDITIONAL; 02174 pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason); 02175 02176 #ifdef SUPPORT_USERUSER 02177 /* User-user info */ 02178 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO"); 02179 02180 if (useruser) 02181 pri_sr_set_useruser(sr, useruser); 02182 #endif 02183 02184 if (pri_setup(p->pri->pri, p->call, sr)) { 02185 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 02186 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan)); 02187 pri_rel(p->pri); 02188 ast_mutex_unlock(&p->lock); 02189 pri_sr_free(sr); 02190 return -1; 02191 } 02192 pri_sr_free(sr); 02193 ast_setstate(ast, AST_STATE_DIALING); 02194 pri_rel(p->pri); 02195 } 02196 #endif 02197 ast_mutex_unlock(&p->lock); 02198 return 0; 02199 }
| static int zt_callwait | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 1737 of file chan_zap.c.
References ast_gen_cas(), AST_LAW, ast_log(), ast_malloc, zt_pvt::callwaitcas, CALLWAITING_REPEAT_SAMPLES, zt_pvt::callwaitingcallerid, zt_pvt::callwaitingrepeat, zt_pvt::callwaitrings, zt_pvt::cidlen, zt_pvt::cidpos, zt_pvt::cidspill, free, LOG_WARNING, READ_SIZE, save_conference(), send_callerid(), and ast_channel::tech_pvt.
Referenced by zt_call(), and zt_read().
01738 { 01739 struct zt_pvt *p = ast->tech_pvt; 01740 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 01741 if (p->cidspill) { 01742 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 01743 free(p->cidspill); 01744 } 01745 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 01746 return -1; 01747 save_conference(p); 01748 /* Silence */ 01749 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 01750 if (!p->callwaitrings && p->callwaitingcallerid) { 01751 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 01752 p->callwaitcas = 1; 01753 p->cidlen = 2400 + 680 + READ_SIZE * 4; 01754 } else { 01755 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 01756 p->callwaitcas = 0; 01757 p->cidlen = 2400 + READ_SIZE * 4; 01758 } 01759 p->cidpos = 0; 01760 send_callerid(p); 01761 01762 return 0; 01763 }
| static struct zt_chan_conf zt_chan_conf_default | ( | void | ) | [static] |
returns a new zt_chan_conf with default values (by-value)
Definition at line 599 of file chan_zap.c.
References zt_chan_conf::chan, CID_SIG_BELL, CID_START_RING, zt_pvt::context, and DEFAULT_CIDRINGS.
Referenced by setup_zap().
00599 { 00600 /* recall that if a field is not included here it is initialized 00601 * to 0 or equivalent 00602 */ 00603 struct zt_chan_conf conf = { 00604 #ifdef HAVE_PRI 00605 .pri = { 00606 .nsf = PRI_NSF_NONE, 00607 .switchtype = PRI_SWITCH_NI2, 00608 .dialplan = PRI_NATIONAL_ISDN + 1, 00609 .localdialplan = PRI_NATIONAL_ISDN + 1, 00610 .nodetype = PRI_CPE, 00611 00612 .minunused = 2, 00613 .idleext = "", 00614 .idledial = "", 00615 .internationalprefix = "", 00616 .nationalprefix = "", 00617 .localprefix = "", 00618 .privateprefix = "", 00619 .unknownprefix = "", 00620 00621 .resetinterval = 3600 00622 }, 00623 #endif 00624 .chan = { 00625 .context = "default", 00626 .cid_num = "", 00627 .cid_name = "", 00628 .mohinterpret = "default", 00629 .mohsuggest = "", 00630 .transfertobusy = 1, 00631 00632 .cid_signalling = CID_SIG_BELL, 00633 .cid_start = CID_START_RING, 00634 .zaptrcallerid = 0, 00635 .use_callerid = 1, 00636 .sig = -1, 00637 .outsigmod = -1, 00638 00639 .tonezone = -1, 00640 00641 .echocancel = 1, 00642 00643 .busycount = 3, 00644 00645 .accountcode = "", 00646 00647 .mailbox = "", 00648 00649 00650 .polarityonanswerdelay = 600, 00651 00652 .sendcalleridafter = DEFAULT_CIDRINGS 00653 }, 00654 .timing = { 00655 .prewinktime = -1, 00656 .preflashtime = -1, 00657 .winktime = -1, 00658 .flashtime = -1, 00659 .starttime = -1, 00660 .rxwinktime = -1, 00661 .rxflashtime = -1, 00662 .debouncetime = -1 00663 }, 00664 .smdi_port = "/dev/ttyS0", 00665 }; 00666 00667 return conf; 00668 }
| static void zt_close | ( | int | fd | ) | [static] |
Definition at line 912 of file chan_zap.c.
Referenced by __unload_module(), alloc_sub(), destroy_channel(), and unalloc_sub().
| static int zt_confmute | ( | struct zt_pvt * | p, | |
| int | muted | |||
| ) | [inline, static] |
Definition at line 1620 of file chan_zap.c.
References ast_log(), zt_pvt::channel, LOG_WARNING, zt_pvt::sig, SIG_PRI, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_handle_dtmfup(), zt_handle_event(), zt_hangup(), and zt_new().
01621 { 01622 int x, y, res; 01623 x = muted; 01624 if (p->sig == SIG_PRI) { 01625 y = 1; 01626 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y); 01627 if (res) 01628 ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel); 01629 } 01630 res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x); 01631 if (res < 0) 01632 ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno)); 01633 return res; 01634 }
| static int zt_digit_begin | ( | struct ast_channel * | ast, | |
| char | digit | |||
| ) | [static] |
Definition at line 999 of file chan_zap.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DIALING, zt_pvt::begindigit, zt_pvt::dialdest, zt_pvt::dialing, digit_to_dtmfindex(), zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::owner, zt_pvt::pulse, zt_pvt::sig, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, and zt_get_index().
01000 { 01001 struct zt_pvt *pvt; 01002 int index; 01003 int dtmf = -1; 01004 01005 pvt = chan->tech_pvt; 01006 01007 ast_mutex_lock(&pvt->lock); 01008 01009 index = zt_get_index(chan, pvt, 0); 01010 01011 if ((index != SUB_REAL) || !pvt->owner) 01012 goto out; 01013 01014 #ifdef HAVE_PRI 01015 if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) { 01016 if (pvt->setup_ack) { 01017 if (!pri_grab(pvt, pvt->pri)) { 01018 pri_information(pvt->pri->pri, pvt->call, digit); 01019 pri_rel(pvt->pri); 01020 } else 01021 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span); 01022 } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) { 01023 int res; 01024 ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit); 01025 res = strlen(pvt->dialdest); 01026 pvt->dialdest[res++] = digit; 01027 pvt->dialdest[res] = '\0'; 01028 } 01029 goto out; 01030 } 01031 #endif 01032 if ((dtmf = digit_to_dtmfindex(digit)) == -1) 01033 goto out; 01034 01035 if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) { 01036 int res; 01037 ZT_DIAL_OPERATION zo = { 01038 .op = ZT_DIAL_OP_APPEND, 01039 .dialstr[0] = 'T', 01040 .dialstr[1] = digit, 01041 .dialstr[2] = 0, 01042 }; 01043 if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo))) 01044 ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit); 01045 else 01046 pvt->dialing = 1; 01047 } else { 01048 ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit); 01049 pvt->dialing = 1; 01050 pvt->begindigit = digit; 01051 } 01052 01053 out: 01054 ast_mutex_unlock(&pvt->lock); 01055 01056 return 0; 01057 }
| static int zt_digit_end | ( | struct ast_channel * | ast, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Definition at line 1059 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::begindigit, zt_pvt::dialing, zt_pvt::lock, LOG_DEBUG, zt_pvt::owner, zt_pvt::pulse, zt_pvt::sig, SIG_PRI, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, and zt_get_index().
01060 { 01061 struct zt_pvt *pvt; 01062 int res = 0; 01063 int index; 01064 int x; 01065 01066 pvt = chan->tech_pvt; 01067 01068 ast_mutex_lock(&pvt->lock); 01069 01070 index = zt_get_index(chan, pvt, 0); 01071 01072 if ((index != SUB_REAL) || !pvt->owner || pvt->pulse) 01073 goto out; 01074 01075 #ifdef HAVE_PRI 01076 /* This means that the digit was already sent via PRI signalling */ 01077 if (pvt->sig == SIG_PRI && !pvt->begindigit) 01078 goto out; 01079 #endif 01080 01081 if (pvt->begindigit) { 01082 x = -1; 01083 ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit); 01084 res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x); 01085 pvt->dialing = 0; 01086 pvt->begindigit = 0; 01087 } 01088 01089 out: 01090 ast_mutex_unlock(&pvt->lock); 01091 01092 return res; 01093 }
| static void zt_disable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1455 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echocanon, LOG_DEBUG, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), handle_init_event(), zt_bridge(), zt_handle_event(), zt_hangup(), and zt_setoption().
01456 { 01457 int x; 01458 int res; 01459 if (p->echocancel) { 01460 x = 0; 01461 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01462 if (res) 01463 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel); 01464 else 01465 ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel); 01466 } 01467 p->echocanon = 0; 01468 }
| static void zt_enable_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1406 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::digital, zt_pvt::echocancel, zt_pvt::echocanon, LOG_DEBUG, LOG_WARNING, zt_pvt::sig, SIG_PRI, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by handle_init_event(), ss_thread(), zt_answer(), zt_bridge(), zt_handle_event(), and zt_setoption().
01407 { 01408 int x; 01409 int res; 01410 if (!p) 01411 return; 01412 if (p->echocanon) { 01413 ast_log(LOG_DEBUG, "Echo cancellation already on\n"); 01414 return; 01415 } 01416 if (p->digital) { 01417 ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n"); 01418 return; 01419 } 01420 if (p->echocancel) { 01421 if (p->sig == SIG_PRI) { 01422 x = 1; 01423 res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x); 01424 if (res) 01425 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel); 01426 } 01427 x = p->echocancel; 01428 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x); 01429 if (res) 01430 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel); 01431 else { 01432 p->echocanon = 1; 01433 ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel); 01434 } 01435 } else 01436 ast_log(LOG_DEBUG, "No echo cancellation requested\n"); 01437 }
| static struct ast_frame * zt_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4577 of file chan_zap.c.
References __zt_exception(), ast_mutex_lock(), ast_mutex_unlock(), f, zt_pvt::lock, and ast_channel::tech_pvt.
04578 { 04579 struct zt_pvt *p = ast->tech_pvt; 04580 struct ast_frame *f; 04581 ast_mutex_lock(&p->lock); 04582 f = __zt_exception(ast); 04583 ast_mutex_unlock(&p->lock); 04584 return f; 04585 }
| static int zt_fixup | ( | struct ast_channel * | oldchan, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
Definition at line 3419 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), zt_pvt::channel, zt_pvt::lock, LOG_DEBUG, zt_subchannel::owner, zt_pvt::owner, zt_pvt::subs, ast_channel::tech_pvt, and zt_unlink().
03420 { 03421 struct zt_pvt *p = newchan->tech_pvt; 03422 int x; 03423 ast_mutex_lock(&p->lock); 03424 ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name); 03425 if (p->owner == oldchan) { 03426 p->owner = newchan; 03427 } 03428 for (x = 0; x < 3; x++) 03429 if (p->subs[x].owner == oldchan) { 03430 if (!x) 03431 zt_unlink(NULL, p, 0); 03432 p->subs[x].owner = newchan; 03433 } 03434 if (newchan->_state == AST_STATE_RINGING) 03435 zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0); 03436 update_conf(p); 03437 ast_mutex_unlock(&p->lock); 03438 return 0; 03439 }
| static int zt_func_read | ( | struct ast_channel * | chan, | |
| char * | function, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 2994 of file chan_zap.c.
References ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::lock, zt_pvt::rxgain, ast_channel::tech_pvt, and zt_pvt::txgain.
02995 { 02996 struct zt_pvt *p = chan->tech_pvt; 02997 02998 if (!strcasecmp(data, "rxgain")) { 02999 ast_mutex_lock(&p->lock); 03000 snprintf(buf, len, "%f", p->rxgain); 03001 ast_mutex_unlock(&p->lock); 03002 } else if (!strcasecmp(data, "txgain")) { 03003 ast_mutex_lock(&p->lock); 03004 snprintf(buf, len, "%f", p->txgain); 03005 ast_mutex_unlock(&p->lock); 03006 } else { 03007 ast_copy_string(buf, "", len); 03008 } 03009 return 0; 03010 }
| static int zt_get_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_getevent which ignores a bunch of events.
Definition at line 256 of file chan_zap.c.
Referenced by __zt_exception(), ss_thread(), and zt_handle_event().
00257 { 00258 int j; 00259 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00260 return -1; 00261 return j; 00262 }
| static int zt_get_index | ( | struct ast_channel * | ast, | |
| struct zt_pvt * | p, | |||
| int | nullok | |||
| ) | [static] |
Definition at line 763 of file chan_zap.c.
References ast_log(), LOG_WARNING, zt_subchannel::owner, and zt_pvt::subs.
Referenced by __zt_exception(), ss_thread(), zt_answer(), zt_bridge(), zt_call(), zt_digit_begin(), zt_digit_end(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_read(), zt_sendtext(), zt_setoption(), and zt_write().
00764 { 00765 int res; 00766 if (p->subs[0].owner == ast) 00767 res = 0; 00768 else if (p->subs[1].owner == ast) 00769 res = 1; 00770 else if (p->subs[2].owner == ast) 00771 res = 2; 00772 else { 00773 res = -1; 00774 if (!nullok) 00775 ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n"); 00776 } 00777 return res; 00778 }
| static void zt_handle_dtmfup | ( | struct ast_channel * | ast, | |
| int | index, | |||
| struct ast_frame ** | dest | |||
| ) | [static] |
Definition at line 3587 of file chan_zap.c.
References ast_async_goto(), AST_CONTROL_ANSWER, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_NULL, ast_log(), ast_verbose(), zt_pvt::callprogress, zt_pvt::callwaitcas, ast_channel::cid, ast_callerid::cid_num, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_channel::context, ast_channel::exten, zt_subchannel::f, f, zt_pvt::faxhandled, ast_frame::frametype, free, LOG_DEBUG, LOG_NOTICE, ast_channel::macrocontext, option_verbose, pbx_builtin_setvar_helper(), S_OR, send_cwcidspill(), ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, VERBOSE_PREFIX_3, and zt_confmute().
Referenced by zt_handle_event(), and zt_read().
03588 { 03589 struct zt_pvt *p = ast->tech_pvt; 03590 struct ast_frame *f = *dest; 03591 03592 ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name); 03593 if (p->confirmanswer) { 03594 ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name); 03595 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 03596 of a DTMF digit */ 03597 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03598 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03599 *dest = &p->subs[index].f; 03600 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 03601 p->confirmanswer = 0; 03602 } else if (p->callwaitcas) { 03603 if ((f->subclass == 'A') || (f->subclass == 'D')) { 03604 ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n"); 03605 if (p->cidspill) 03606 free(p->cidspill); 03607 send_cwcidspill(p); 03608 } 03609 if ((f->subclass != 'm') && (f->subclass != 'u')) 03610 p->callwaitcas = 0; 03611 p->subs[index].f.frametype = AST_FRAME_NULL; 03612 p->subs[index].f.subclass = 0; 03613 *dest = &p->subs[index].f; 03614 } else if (f->subclass == 'f') { 03615 /* Fax tone -- Handle and return NULL */ 03616 if ((p->callprogress & 0x6) && !p->faxhandled) { 03617 p->faxhandled++; 03618 if (strcmp(ast->exten, "fax")) { 03619 const char *target_context = S_OR(ast->macrocontext, ast->context); 03620 03621 if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) { 03622 if (option_verbose > 2) 03623 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name); 03624 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 03625 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 03626 if (ast_async_goto(ast, target_context, "fax", 1)) 03627 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 03628 } else 03629 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 03630 } else 03631 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 03632 } else 03633 ast_log(LOG_DEBUG, "Fax already handled\n"); 03634 zt_confmute(p, 0); 03635 p->subs[index].f.frametype = AST_FRAME_NULL; 03636 p->subs[index].f.subclass = 0; 03637 *dest = &p->subs[index].f; 03638 } else if (f->subclass == 'm') { 03639 /* Confmute request */ 03640 zt_confmute(p, 1); 03641 p->subs[index].f.frametype = AST_FRAME_NULL; 03642 p->subs[index].f.subclass = 0; 03643 *dest = &p->subs[index].f; 03644 } else if (f->subclass == 'u') { 03645 /* Unmute */ 03646 zt_confmute(p, 0); 03647 p->subs[index].f.frametype = AST_FRAME_NULL; 03648 p->subs[index].f.subclass = 0; 03649 *dest = &p->subs[index].f; 03650 } else 03651 zt_confmute(p, 0); 03652 }
| static struct ast_frame* zt_handle_event | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 3654 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, alarm2str(), alloc_sub(), zt_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_pthread_create, ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdup, ast_strlen_zero(), ast_verbose(), attempt_transfer(), zt_pvt::callwaitcas, CANPROGRESSDETECT, zt_pvt::channel, check_for_conference(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_ani2, zt_pvt::cid_name, ast_callerid::cid_name, cid_name, zt_pvt::cid_num, ast_callerid::cid_num, cid_num, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, ast_frame::data, ast_frame::datalen, zt_pvt::dialdest, zt_pvt::dialing, zt_pvt::dop, zt_pvt::echobreak, zt_pvt::echocanon, zt_pvt::echorest, zt_pvt::echotraining, event2str(), EVENT_FLAG_SYSTEM, zt_subchannel::f, f, zt_pvt::fake_event, zt_pvt::finaldial, zt_pvt::flashtime, ast_frame::frametype, free, get_alarms(), zt_pvt::hanguponpolarityswitch, has_voicemail(), zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, ast_frame::mallocd, manager_event(), MIN_MS_SINCE_FLASH, zt_pvt::mohsuggest, zt_pvt::msgstate, zt_subchannel::needflash, zt_subchannel::needhold, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::onhooktime, zt_pvt::oprmode, zt_pvt::oprpeer, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::outsigmod, zt_pvt::overlapdial, zt_subchannel::owner, zt_pvt::owner, ast_channel::pbx, zt_pvt::polarity, POLARITY_IDLE, POLARITY_REV, zt_pvt::polaritydelaytv, zt_pvt::polarityonanswerdelay, zt_pvt::pulsedial, zt_pvt::radio, restore_conference(), ast_channel::rings, zt_pvt::ringt, zt_pvt::ringt_base, S_OR, ast_frame::samples, save_conference(), zt_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, ast_frame::src, ss_thread(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, zt_pvt::threewaycalling, zt_pvt::transfer, zt_pvt::transfertobusy, unalloc_sub(), update_conf(), VERBOSE_PREFIX_3, zt_pvt::whichwink, zt_pvt::zaptrcallerid, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_enable_ec(), ZT_EVENT_DTMFDOWN, ZT_EVENT_DTMFUP, zt_get_event(), zt_get_index(), zt_handle_dtmfup(), zt_new(), zt_ring_phone(), zt_set_hook(), and zt_train_ec().
Referenced by __zt_exception().
03655 { 03656 int res, x; 03657 int index, mysig; 03658 char *c; 03659 struct zt_pvt *p = ast->tech_pvt; 03660 pthread_t threadid; 03661 pthread_attr_t attr; 03662 struct ast_channel *chan; 03663 struct ast_frame *f; 03664 03665 index = zt_get_index(ast, p, 0); 03666 mysig = p->sig; 03667 if (p->outsigmod > -1) 03668 mysig = p->outsigmod; 03669 p->subs[index].f.frametype = AST_FRAME_NULL; 03670 p->subs[index].f.subclass = 0; 03671 p->subs[index].f.datalen = 0; 03672 p->subs[index].f.samples = 0; 03673 p->subs[index].f.mallocd = 0; 03674 p->subs[index].f.offset = 0; 03675 p->subs[index].f.src = "zt_handle_event"; 03676 p->subs[index].f.data = NULL; 03677 f = &p->subs[index].f; 03678 03679 if (index < 0) 03680 return &p->subs[index].f; 03681 if (p->fake_event) { 03682 res = p->fake_event; 03683 p->fake_event = 0; 03684 } else 03685 res = zt_get_event(p->subs[index].zfd); 03686 03687 ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index); 03688 03689 if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) { 03690 p->pulsedial = (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0; 03691 03692 ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 03693 #ifdef HAVE_PRI 03694 if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) { 03695 /* absorb event */ 03696 } else { 03697 #endif 03698 p->subs[index].f.frametype = AST_FRAME_DTMF_END; 03699 p->subs[index].f.subclass = res & 0xff; 03700 #ifdef HAVE_PRI 03701 } 03702 #endif 03703 zt_handle_dtmfup(ast, index, &f); 03704 return f; 03705 } 03706 03707 if (res & ZT_EVENT_DTMFDOWN) { 03708 ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff); 03709 /* Mute conference */ 03710 zt_confmute(p, 1); 03711 p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN; 03712 p->subs[index].f.subclass = res & 0xff; 03713 return &p->subs[index].f; 03714 } 03715 03716 switch (res) { 03717 #ifdef ZT_EVENT_EC_DISABLED 03718 case ZT_EVENT_EC_DISABLED: 03719 if (option_verbose > 2) 03720 ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel); 03721 p->echocanon = 0; 03722 break; 03723 #endif 03724 case ZT_EVENT_BITSCHANGED: 03725 ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig)); 03726 case ZT_EVENT_PULSE_START: 03727 /* Stop tone if there's a pulse start and the PBX isn't started */ 03728 if (!ast->pbx) 03729 tone_zone_play_tone(p->subs[index].zfd, -1); 03730 break; 03731 case ZT_EVENT_DIALCOMPLETE: 03732 if (p->inalarm) break; 03733 if ((p->radio || (p->oprmode < 0))) break; 03734 if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) { 03735 ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name); 03736 return NULL; 03737 } 03738 if (!x) { /* if not still dialing in driver */ 03739 zt_enable_ec(p); 03740 if (p->echobreak) { 03741 zt_train_ec(p); 03742 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 03743 p->dop.op = ZT_DIAL_OP_REPLACE; 03744 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 03745 p->echobreak = 0; 03746 } else { 03747 p->dialing = 0; 03748 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) { 03749 /* if thru with dialing after offhook */ 03750 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 03751 ast_setstate(ast, AST_STATE_UP); 03752 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03753 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03754 break; 03755 } else { /* if to state wait for offhook to dial rest */ 03756 /* we now wait for off hook */ 03757 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 03758 } 03759 } 03760 if (ast->_state == AST_STATE_DIALING) { 03761 if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 03762 ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n"); 03763 } else if (p->confirmanswer || (!p->dialednone && ((mysig == SIG_EM) || (mysig == SIG_EM_E1) || (mysig == SIG_EMWINK) || (mysig == SIG_FEATD) || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF) || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB) || (mysig == SIG_SF) || (mysig == SIG_SFWINK) || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF) || (mysig == SIG_SF_FEATB)))) { 03764 ast_setstate(ast, AST_STATE_RINGING); 03765 } else if (!p->answeronpolarityswitch) { 03766 ast_setstate(ast, AST_STATE_UP); 03767 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03768 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03769 } 03770 } 03771 } 03772 } 03773 break; 03774 case ZT_EVENT_ALARM: 03775 #ifdef HAVE_PRI 03776 if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) { 03777 /* T309 is not enabled : hangup calls when alarm occurs */ 03778 if (p->call) { 03779 if (p->pri && p->pri->pri) { 03780 if (!pri_grab(p, p->pri)) { 03781 pri_hangup(p->pri->pri, p->call, -1); 03782 pri_destroycall(p->pri->pri, p->call); 03783 p->call = NULL; 03784 pri_rel(p->pri); 03785 } else 03786 ast_log(LOG_WARNING, "Failed to grab PRI!\n"); 03787 } else 03788 ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n"); 03789 } 03790 if (p->owner) 03791 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03792 } 03793 if (p->bearer) 03794 p->bearer->inalarm = 1; 03795 else 03796 #endif 03797 p->inalarm = 1; 03798 res = get_alarms(p); 03799 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm2str(res)); 03800 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 03801 "Alarm: %s\r\n" 03802 "Channel: %d\r\n", 03803 alarm2str(res), p->channel); 03804 #ifdef HAVE_LIBPRI 03805 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 03806 /* fall through intentionally */ 03807 } else { 03808 break; 03809 } 03810 #endif 03811 case ZT_EVENT_ONHOOK: 03812 if (p->radio) { 03813 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03814 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 03815 break; 03816 } 03817 if (p->oprmode < 0) 03818 { 03819 if (p->oprmode != -1) break; 03820 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 03821 { 03822 /* Make sure it starts ringing */ 03823 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 03824 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING); 03825 save_conference(p->oprpeer); 03826 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 03827 } 03828 break; 03829 } 03830 switch (p->sig) { 03831 case SIG_FXOLS: 03832 case SIG_FXOGS: 03833 case SIG_FXOKS: 03834 p->onhooktime = time(NULL); 03835 p->msgstate = -1; 03836 /* Check for some special conditions regarding call waiting */ 03837 if (index == SUB_REAL) { 03838 /* The normal line was hung up */ 03839 if (p->subs[SUB_CALLWAIT].owner) { 03840 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 03841 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 03842 if (option_verbose > 2) 03843 ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel); 03844 unalloc_sub(p, SUB_CALLWAIT); 03845 #if 0 03846 p->subs[index].needanswer = 0; 03847 p->subs[index].needringing = 0; 03848 #endif 03849 p->callwaitingrepeat = 0; 03850 p->cidcwexpire = 0; 03851 p->owner = NULL; 03852 /* Don't start streaming audio yet if the incoming call isn't up yet */ 03853 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 03854 p->dialing = 1; 03855 zt_ring_phone(p); 03856 } else if (p->subs[SUB_THREEWAY].owner) { 03857 unsigned int mssinceflash; 03858 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 03859 the private structure -- not especially easy or clean */ 03860 while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) { 03861 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 03862 ast_mutex_unlock(&p->lock); 03863 ast_mutex_unlock(&ast->lock); 03864 usleep(1); 03865 /* We can grab ast and p in that order, without worry. We should make sure 03866 nothing seriously bad has happened though like some sort of bizarre double 03867 masquerade! */ 03868 ast_mutex_lock(&ast->lock); 03869 ast_mutex_lock(&p->lock); 03870 if (p->owner != ast) { 03871 ast_log(LOG_WARNING, "This isn't good...\n"); 03872 return NULL; 03873 } 03874 } 03875 if (!p->subs[SUB_THREEWAY].owner) { 03876 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 03877 return NULL; 03878 } 03879 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 03880 ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash); 03881 if (mssinceflash < MIN_MS_SINCE_FLASH) { 03882 /* It hasn't been long enough since the last flashook. This is probably a bounce on 03883 hanging up. Hangup both channels now */ 03884 if (p->subs[SUB_THREEWAY].owner) 03885 ast_queue_hangup(p->subs[SUB_THREEWAY].owner); 03886 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03887 ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 03888 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03889 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 03890 if (p->transfer) { 03891 /* In any case this isn't a threeway call anymore */ 03892 p->subs[SUB_REAL].inthreeway = 0; 03893 p->subs[SUB_THREEWAY].inthreeway = 0; 03894 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 03895 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 03896 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03897 /* Swap subs and dis-own channel */ 03898 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03899 p->owner = NULL; 03900 /* Ring the phone */ 03901 zt_ring_phone(p); 03902 } else { 03903 if ((res = attempt_transfer(p)) < 0) { 03904 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03905 if (p->subs[SUB_THREEWAY].owner) 03906 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03907 } else if (res) { 03908 /* Don't actually hang up at this point */ 03909 if (p->subs[SUB_THREEWAY].owner) 03910 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03911 break; 03912 } 03913 } 03914 } else { 03915 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 03916 if (p->subs[SUB_THREEWAY].owner) 03917 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03918 } 03919 } else { 03920 ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock); 03921 /* Swap subs and dis-own channel */ 03922 swap_subs(p, SUB_THREEWAY, SUB_REAL); 03923 p->owner = NULL; 03924 /* Ring the phone */ 03925 zt_ring_phone(p); 03926 } 03927 } 03928 } else { 03929 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index); 03930 } 03931 /* Fall through */ 03932 default: 03933 zt_disable_ec(p); 03934 return NULL; 03935 } 03936 break; 03937 case ZT_EVENT_RINGOFFHOOK: 03938 if (p->inalarm) break; 03939 if (p->oprmode < 0) 03940 { 03941 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 03942 { 03943 /* Make sure it stops ringing */ 03944 zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); 03945 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1); 03946 restore_conference(p->oprpeer); 03947 } 03948 break; 03949 } 03950 if (p->radio) 03951 { 03952 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03953 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 03954 break; 03955 } 03956 /* for E911, its supposed to wait for offhook then dial 03957 the second half of the dial string */ 03958 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 03959 c = strchr(p->dialdest, '/'); 03960 if (c) 03961 c++; 03962 else 03963 c = p->dialdest; 03964 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 03965 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 03966 if (strlen(p->dop.dialstr) > 4) { 03967 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 03968 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 03969 p->echorest[sizeof(p->echorest) - 1] = '\0'; 03970 p->echobreak = 1; 03971 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 03972 } else 03973 p->echobreak = 0; 03974 if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) { 03975 x = ZT_ONHOOK; 03976 ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03977 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno)); 03978 return NULL; 03979 } 03980 p->dialing = 1; 03981 return &p->subs[index].f; 03982 } 03983 switch (p->sig) { 03984 case SIG_FXOLS: 03985 case SIG_FXOGS: 03986 case SIG_FXOKS: 03987 switch (ast->_state) { 03988 case AST_STATE_RINGING: 03989 zt_enable_ec(p); 03990 zt_train_ec(p); 03991 p->subs[index].f.frametype = AST_FRAME_CONTROL; 03992 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 03993 /* Make sure it stops ringing */ 03994 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 03995 ast_log(LOG_DEBUG, "channel %d answered\n", p->channel); 03996 if (p->cidspill) { 03997 /* Cancel any running CallerID spill */ 03998 free(p->cidspill); 03999 p->cidspill = NULL; 04000 } 04001 p->dialing = 0; 04002 p->callwaitcas = 0; 04003 if (p->confirmanswer) { 04004 /* Ignore answer if "confirm answer" is enabled */ 04005 p->subs[index].f.frametype = AST_FRAME_NULL; 04006 p->subs[index].f.subclass = 0; 04007 } else if (!ast_strlen_zero(p->dop.dialstr)) { 04008 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 04009 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04010 if (res < 0) { 04011 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04012 p->dop.dialstr[0] = '\0'; 04013 return NULL; 04014 } else { 04015 ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 04016 p->subs[index].f.frametype = AST_FRAME_NULL; 04017 p->subs[index].f.subclass = 0; 04018 p->dialing = 1; 04019 } 04020 p->dop.dialstr[0] = '\0'; 04021 ast_setstate(ast, AST_STATE_DIALING); 04022 } else 04023 ast_setstate(ast, AST_STATE_UP); 04024 return &p->subs[index].f; 04025 case AST_STATE_DOWN: 04026 ast_setstate(ast, AST_STATE_RING); 04027 ast->rings = 1; 04028 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04029 p->subs[index].f.subclass = AST_CONTROL_OFFHOOK; 04030 ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel); 04031 return &p->subs[index].f; 04032 case AST_STATE_UP: 04033 /* Make sure it stops ringing */ 04034 zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 04035 /* Okay -- probably call waiting*/ 04036 if (ast_bridged_channel(p->owner)) 04037 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 04038 p->subs[index].needunhold = 1; 04039 break; 04040 case AST_STATE_RESERVED: 04041 /* Start up dialtone */ 04042 if (has_voicemail(p)) 04043 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); 04044 else 04045 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE); 04046 break; 04047 default: 04048 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 04049 } 04050 break; 04051 case SIG_FXSLS: 04052 case SIG_FXSGS: 04053 case SIG_FXSKS: 04054 if (ast->_state == AST_STATE_RING) { 04055 p->ringt = p->ringt_base; 04056 } 04057 04058 /* If we get a ring then we cannot be in 04059 * reversed polarity. So we reset to idle */ 04060 ast_log(LOG_DEBUG, "Setting IDLE polarity due " 04061 "to ring. Old polarity was %d\n", 04062 p->polarity); 04063 p->polarity = POLARITY_IDLE; 04064 04065 /* Fall through */ 04066 case SIG_EM: 04067 case SIG_EM_E1: 04068 case SIG_EMWINK: 04069 case SIG_FEATD: 04070 case SIG_FEATDMF: 04071 case SIG_FEATDMF_TA: 04072 case SIG_E911: 04073 case SIG_FGC_CAMA: 04074 case SIG_FGC_CAMAMF: 04075 case SIG_FEATB: 04076 case SIG_SF: 04077 case SIG_SFWINK: 04078 case SIG_SF_FEATD: 04079 case SIG_SF_FEATDMF: 04080 case SIG_SF_FEATB: 04081 if (ast->_state == AST_STATE_PRERING) 04082 ast_setstate(ast, AST_STATE_RING); 04083 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 04084 if (option_debug) 04085 ast_log(LOG_DEBUG, "Ring detected\n"); 04086 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04087 p->subs[index].f.subclass = AST_CONTROL_RING; 04088 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 04089 if (option_debug) 04090 ast_log(LOG_DEBUG, "Line answered\n"); 04091 if (p->confirmanswer) { 04092 p->subs[index].f.frametype = AST_FRAME_NULL; 04093 p->subs[index].f.subclass = 0; 04094 } else { 04095 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04096 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04097 ast_setstate(ast, AST_STATE_UP); 04098 } 04099 } else if (ast->_state != AST_STATE_RING) 04100 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 04101 break; 04102 default: 04103 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 04104 } 04105 break; 04106 #ifdef ZT_EVENT_RINGBEGIN 04107 case ZT_EVENT_RINGBEGIN: 04108 switch (p->sig) { 04109 case SIG_FXSLS: 04110 case SIG_FXSGS: 04111 case SIG_FXSKS: 04112 if (ast->_state == AST_STATE_RING) { 04113 p->ringt = p->ringt_base; 04114 } 04115 break; 04116 } 04117 break; 04118 #endif 04119 case ZT_EVENT_RINGEROFF: 04120 if (p->inalarm) break; 04121 if ((p->radio || (p->oprmode < 0))) break; 04122 ast->rings++; 04123 if ((ast->rings > p->cidrings) && (p->cidspill)) { 04124 ast_log(LOG_WARNING, "Didn't finish Caller-ID spill. Cancelling.\n"); 04125 free(p->cidspill); 04126 p->cidspill = NULL; 04127 p->callwaitcas = 0; 04128 } 04129 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04130 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04131 break; 04132 case ZT_EVENT_RINGERON: 04133 break; 04134 case ZT_EVENT_NOALARM: 04135 p->inalarm = 0; 04136 #ifdef HAVE_PRI 04137 /* Extremely unlikely but just in case */ 04138 if (p->bearer) 04139 p->bearer->inalarm = 0; 04140 #endif 04141 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 04142 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", 04143 "Channel: %d\r\n", p->channel); 04144 break; 04145 case ZT_EVENT_WINKFLASH: 04146 if (p->inalarm) break; 04147 if (p->radio) break; 04148 if (p->oprmode < 0) break; 04149 if (p->oprmode > 1) 04150 { 04151 struct zt_params par; 04152 04153 if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1) 04154 { 04155 if (!par.rxisoffhook) 04156 { 04157 /* Make sure it stops ringing */ 04158 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF); 04159 zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING); 04160 save_conference(p); 04161 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04162 } 04163 } 04164 break; 04165 } 04166 /* Remember last time we got a flash-hook */ 04167 gettimeofday(&p->flashtime, NULL); 04168 switch (mysig) { 04169 case SIG_FXOLS: 04170 case SIG_FXOGS: 04171 case SIG_FXOKS: 04172 ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 04173 index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 04174 p->callwaitcas = 0; 04175 04176 if (index != SUB_REAL) { 04177 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel); 04178 goto winkflashdone; 04179 } 04180 04181 if (p->subs[SUB_CALLWAIT].owner) { 04182 /* Swap to call-wait */ 04183 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 04184 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 04185 p->owner = p->subs[SUB_REAL].owner; 04186 ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name); 04187 if (p->owner->_state == AST_STATE_RINGING) { 04188 ast_setstate(p->owner, AST_STATE_UP); 04189 p->subs[SUB_REAL].needanswer = 1; 04190 } 04191 p->callwaitingrepeat = 0; 04192 p->cidcwexpire = 0; 04193 /* Start music on hold if appropriate */ 04194 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 04195 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 04196 S_OR(p->mohsuggest, NULL), 04197 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04198 } 04199 p->subs[SUB_CALLWAIT].needhold = 1; 04200 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 04201 ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD, 04202 S_OR(p->mohsuggest, NULL), 04203 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04204 } 04205 p->subs[SUB_REAL].needunhold = 1; 04206 } else if (!p->subs[SUB_THREEWAY].owner) { 04207 char cid_num[256]; 04208 char cid_name[256]; 04209 04210 if (!p->threewaycalling) { 04211 /* Just send a flash if no 3-way calling */ 04212 p->subs[SUB_REAL].needflash = 1; 04213 goto winkflashdone; 04214 } else if (!check_for_conference(p)) { 04215 if (p->zaptrcallerid && p->owner) { 04216 if (p->owner->cid.cid_num) 04217 ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num)); 04218 if (p->owner->cid.cid_name) 04219 ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name)); 04220 } 04221 /* XXX This section needs much more error checking!!! XXX */ 04222 /* Start a 3-way call if feasible */ 04223 if (!((ast->pbx) || 04224 (ast->_state == AST_STATE_UP) || 04225 (ast->_state == AST_STATE_RING))) { 04226 ast_log(LOG_DEBUG, "Flash when call not up or ringing\n"); 04227 goto winkflashdone; 04228 } 04229 if (alloc_sub(p, SUB_THREEWAY)) { 04230 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 04231 goto winkflashdone; 04232 } 04233 /* Make new channel */ 04234 chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0); 04235 if (p->zaptrcallerid) { 04236 if (!p->origcid_num) 04237 p->origcid_num = ast_strdup(p->cid_num); 04238 if (!p->origcid_name) 04239 p->origcid_name = ast_strdup(p->cid_name); 04240 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 04241 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 04242 } 04243 /* Swap things around between the three-way and real call */ 04244 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04245 /* Disable echo canceller for better dialing */ 04246 zt_disable_ec(p); 04247 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL); 04248 if (res) 04249 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 04250 p->owner = chan; 04251 pthread_attr_init(&attr); 04252 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04253 if (!chan) { 04254 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 04255 } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) { 04256 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 04257 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 04258 zt_enable_ec(p); 04259 ast_hangup(chan); 04260 } else { 04261 if (option_verbose > 2) 04262 ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel); 04263 /* Start music on hold if appropriate */ 04264 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 04265 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 04266 S_OR(p->mohsuggest, NULL), 04267 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 04268 } 04269 p->subs[SUB_THREEWAY].needhold = 1; 04270 } 04271 pthread_attr_destroy(&attr); 04272 } 04273 } else { 04274 /* Already have a 3 way call */ 04275 if (p->subs[SUB_THREEWAY].inthreeway) { 04276 /* Call is already up, drop the last person */ 04277 if (option_debug) 04278 ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel); 04279 /* If the primary call isn't answered yet, use it */ 04280 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 04281 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 04282 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04283 p->owner = p->subs[SUB_REAL].owner; 04284 } 04285 /* Drop the last call and stop the conference */ 04286 if (option_verbose > 2) 04287 ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name); 04288 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04289 p->subs[SUB_REAL].inthreeway = 0; 04290 p->subs[SUB_THREEWAY].inthreeway = 0; 04291 } else { 04292 /* Lets see what we're up to */ 04293 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 04294 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 04295 int otherindex = SUB_THREEWAY; 04296 04297 if (option_verbose > 2) 04298 ast_verbose(VERBOSE_PREFIX_3 "Building conference on call on %s and %s\n", p->subs[SUB_THREEWAY].owner->name, p->subs[SUB_REAL].owner->name); 04299 /* Put them in the threeway, and flip */ 04300 p->subs[SUB_THREEWAY].inthreeway = 1; 04301 p->subs[SUB_REAL].inthreeway = 1; 04302 if (ast->_state == AST_STATE_UP) { 04303 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04304 otherindex = SUB_REAL; 04305 } 04306 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 04307 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 04308 p->subs[otherindex].needunhold = 1; 04309 p->owner = p->subs[SUB_REAL].owner; 04310 if (ast->_state == AST_STATE_RINGING) { 04311 ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n"); 04312 res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); 04313 res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE); 04314 } 04315 } else { 04316 if (option_verbose > 2) 04317 ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name); 04318 swap_subs(p, SUB_THREEWAY, SUB_REAL); 04319 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 04320 p->owner = p->subs[SUB_REAL].owner; 04321 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 04322 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 04323 p->subs[SUB_REAL].needunhold = 1; 04324 zt_enable_ec(p); 04325 } 04326 04327 } 04328 } 04329 winkflashdone: 04330 update_conf(p); 04331 break; 04332 case SIG_EM: 04333 case SIG_EM_E1: 04334 case SIG_EMWINK: 04335 case SIG_FEATD: 04336 case SIG_SF: 04337 case SIG_SFWINK: 04338 case SIG_SF_FEATD: 04339 case SIG_FXSLS: 04340 case SIG_FXSGS: 04341 if (p->dialing) 04342 ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel); 04343 else 04344 ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 04345 break; 04346 case SIG_FEATDMF_TA: 04347 switch (p->whichwink) { 04348 case 0: 04349 ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04350 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani); 04351 break; 04352 case 1: 04353 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 04354 break; 04355 case 2: 04356 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 04357 return NULL; 04358 } 04359 p->whichwink++; 04360 /* Fall through */ 04361 case SIG_FEATDMF: 04362 case SIG_E911: 04363 case SIG_FGC_CAMAMF: 04364 case SIG_FGC_CAMA: 04365 case SIG_FEATB: 04366 case SIG_SF_FEATDMF: 04367 case SIG_SF_FEATB: 04368 /* FGD MF *Must* wait for wink */ 04369 if (!ast_strlen_zero(p->dop.dialstr)) 04370 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04371 else if (res < 0) { 04372 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04373 p->dop.dialstr[0] = '\0'; 04374 return NULL; 04375 } else 04376 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04377 p->dop.dialstr[0] = '\0'; 04378 break; 04379 default: 04380 ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig); 04381 } 04382 break; 04383 case ZT_EVENT_HOOKCOMPLETE: 04384 if (p->inalarm) break; 04385 if ((p->radio || (p->oprmode < 0))) break; 04386 switch (mysig) { 04387 case SIG_FXSLS: /* only interesting for FXS */ 04388 case SIG_FXSGS: 04389 case SIG_FXSKS: 04390 case SIG_EM: 04391 case SIG_EM_E1: 04392 case SIG_EMWINK: 04393 case SIG_FEATD: 04394 case SIG_SF: 04395 case SIG_SFWINK: 04396 case SIG_SF_FEATD: 04397 if (!ast_strlen_zero(p->dop.dialstr)) 04398 res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop); 04399 else if (res < 0) { 04400 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 04401 p->dop.dialstr[0] = '\0'; 04402 return NULL; 04403 } else 04404 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 04405 p->dop.dialstr[0] = '\0'; 04406 p->dop.op = ZT_DIAL_OP_REPLACE; 04407 break; 04408 case SIG_FEATDMF: 04409 case SIG_FEATDMF_TA: 04410 case SIG_E911: 04411 case SIG_FGC_CAMA: 04412 case SIG_FGC_CAMAMF: 04413 case SIG_FEATB: 04414 case SIG_SF_FEATDMF: 04415 case SIG_SF_FEATB: 04416 ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 04417 break; 04418 default: 04419 break; 04420 } 04421 break; 04422 case ZT_EVENT_POLARITY: 04423 /* 04424 * If we get a Polarity Switch event, check to see 04425 * if we should change the polarity state and 04426 * mark the channel as UP or if this is an indication 04427 * of remote end disconnect. 04428 */ 04429 if (p->polarity == POLARITY_IDLE) { 04430 p->polarity = POLARITY_REV; 04431 if (p->answeronpolarityswitch && 04432 ((ast->_state == AST_STATE_DIALING) || 04433 (ast->_state == AST_STATE_RINGING))) { 04434 ast_log(LOG_DEBUG, "Answering on polarity switch!\n"); 04435 ast_setstate(p->owner, AST_STATE_UP); 04436 if (p->hanguponpolarityswitch) { 04437 gettimeofday(&p->polaritydelaytv, NULL); 04438 } 04439 } else 04440 ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 04441 } 04442 /* Removed else statement from here as it was preventing hangups from ever happening*/ 04443 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 04444 if (p->hanguponpolarityswitch && 04445 (p->polarityonanswerdelay > 0) && 04446 (p->polarity == POLARITY_REV) && 04447 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 04448 /* Added log_debug information below to provide a better indication of what is going on */ 04449 ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 1: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) ); 04450 04451 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 04452 ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 04453 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 04454 p->polarity = POLARITY_IDLE; 04455 } else { 04456 ast_log(LOG_DEBUG, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state); 04457 } 04458 } else { 04459 p->polarity = POLARITY_IDLE; 04460 ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 04461 } 04462 /* Added more log_debug information below to provide a better indication of what is going on */ 04463 ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) ); 04464 break; 04465 default: 04466 ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel); 04467 } 04468 return &p->subs[index].f; 04469 }
| static int zt_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2400 of file chan_zap.c.
References ast_channel::_state, ast_bridged_channel(), ast_channel_setoption(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_dsp_digitmode(), ast_dsp_free(), ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_AUDIO_MODE, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, ast_queue_control(), ast_queue_control_data(), AST_STATE_RESERVED, AST_STATE_UP, ast_strlen_zero(), ast_verbose(), zt_pvt::callwaitcas, zt_pvt::callwaiting, zt_pvt::callwaitingrepeat, zt_pvt::channel, zt_pvt::cid_name, zt_pvt::cid_num, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, zt_pvt::confirmanswer, zt_pvt::destroy, destroy_channel(), zt_pvt::dialing, zt_pvt::didtdd, zt_pvt::digital, zt_pvt::distinctivering, zt_pvt::dsp, DSP_DIGITMODE_DTMF, zt_pvt::dtmfrelax, zt_pvt::exten, zt_pvt::faxhandled, free, zt_pvt::guardtime, ast_channel::hangupcause, zt_pvt::hidecallerid, iflist, zt_pvt::ignoredtmf, zt_subchannel::inthreeway, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, LOG_WARNING, zt_pvt::mohsuggest, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needringing, zt_pvt::next, zt_pvt::onhooktime, zt_pvt::oprmode, option_debug, option_verbose, zt_pvt::origcid_name, zt_pvt::origcid_num, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_getvar_helper(), zt_pvt::permcallwaiting, zt_pvt::permhidecallerid, zt_pvt::polarity, POLARITY_IDLE, zt_pvt::prev, zt_pvt::pulsedial, zt_pvt::radio, zt_pvt::rdnis, reset_conf(), restart_monitor(), restore_gains(), zt_pvt::ringt, S_OR, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, zt_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, zt_pvt::subs, swap_subs(), ast_channel::tech_pvt, unalloc_sub(), update_conf(), VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_confmute(), zt_disable_ec(), zt_get_index(), zt_set_hook(), and zt_setlinear().
02401 { 02402 int res; 02403 int index,x, law; 02404 /*static int restore_gains(struct zt_pvt *p);*/ 02405 struct zt_pvt *p = ast->tech_pvt; 02406 struct zt_pvt *tmp = NULL; 02407 struct zt_pvt *prev = NULL; 02408 ZT_PARAMS par; 02409 02410 if (option_debug) 02411 ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name); 02412 if (!ast->tech_pvt) { 02413 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 02414 return 0; 02415 } 02416 02417 ast_mutex_lock(&p->lock); 02418 02419 index = zt_get_index(ast, p, 1); 02420 02421 if (p->sig == SIG_PRI) { 02422 x = 1; 02423 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02424 } 02425 02426 x = 0; 02427 zt_confmute(p, 0); 02428 restore_gains(p); 02429 if (p->origcid_num) { 02430 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 02431 free(p->origcid_num); 02432 p->origcid_num = NULL; 02433 } 02434 if (p->origcid_name) { 02435 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 02436 free(p->origcid_name); 02437 p->origcid_name = NULL; 02438 } 02439 if (p->dsp) 02440 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 02441 if (p->exten) 02442 p->exten[0] = '\0'; 02443 02444 if (option_debug) 02445 ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 02446 p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); 02447 p->ignoredtmf = 0; 02448 02449 if (index > -1) { 02450 /* Real channel, do some fixup */ 02451 p->subs[index].owner = NULL; 02452 p->subs[index].needanswer = 0; 02453 p->subs[index].needflash = 0; 02454 p->subs[index].needringing = 0; 02455 p->subs[index].needbusy = 0; 02456 p->subs[index].needcongestion = 0; 02457 p->subs[index].linear = 0; 02458 p->subs[index].needcallerid = 0; 02459 p->polarity = POLARITY_IDLE; 02460 zt_setlinear(p->subs[index].zfd, 0); 02461 if (index == SUB_REAL) { 02462 if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) { 02463 ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n"); 02464 if (p->subs[SUB_CALLWAIT].inthreeway) { 02465 /* We had flipped over to answer a callwait and now it's gone */ 02466 ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n"); 02467 /* Move to the call-wait, but un-own us until they flip back. */ 02468 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02469 unalloc_sub(p, SUB_CALLWAIT); 02470 p->owner = NULL; 02471 } else { 02472 /* The three way hung up, but we still have a call wait */ 02473 ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 02474 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02475 unalloc_sub(p, SUB_THREEWAY); 02476 if (p->subs[SUB_REAL].inthreeway) { 02477 /* This was part of a three way call. Immediately make way for 02478 another call */ 02479 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02480 p->owner = p->subs[SUB_REAL].owner; 02481 } else { 02482 /* This call hasn't been completed yet... Set owner to NULL */ 02483 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02484 p->owner = NULL; 02485 } 02486 p->subs[SUB_REAL].inthreeway = 0; 02487 } 02488 } else if (p->subs[SUB_CALLWAIT].zfd > -1) { 02489 /* Move to the call-wait and switch back to them. */ 02490 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 02491 unalloc_sub(p, SUB_CALLWAIT); 02492 p->owner = p->subs[SUB_REAL].owner; 02493 if (p->owner->_state != AST_STATE_UP) 02494 p->subs[SUB_REAL].needanswer = 1; 02495 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 02496 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 02497 } else if (p->subs[SUB_THREEWAY].zfd > -1) { 02498 swap_subs(p, SUB_THREEWAY, SUB_REAL); 02499 unalloc_sub(p, SUB_THREEWAY); 02500 if (p->subs[SUB_REAL].inthreeway) { 02501 /* This was part of a three way call. Immediately make way for 02502 another call */ 02503 ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n"); 02504 p->owner = p->subs[SUB_REAL].owner; 02505 } else { 02506 /* This call hasn't been completed yet... Set owner to NULL */ 02507 ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n"); 02508 p->owner = NULL; 02509 } 02510 p->subs[SUB_REAL].inthreeway = 0; 02511 } 02512 } else if (index == SUB_CALLWAIT) { 02513 /* Ditch the holding callwait call, and immediately make it availabe */ 02514 if (p->subs[SUB_CALLWAIT].inthreeway) { 02515 /* This is actually part of a three way, placed on hold. Place the third part 02516 on music on hold now */ 02517 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 02518 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 02519 S_OR(p->mohsuggest, NULL), 02520 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02521 } 02522 p->subs[SUB_THREEWAY].inthreeway = 0; 02523 /* Make it the call wait now */ 02524 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 02525 unalloc_sub(p, SUB_THREEWAY); 02526 } else 02527 unalloc_sub(p, SUB_CALLWAIT); 02528 } else if (index == SUB_THREEWAY) { 02529 if (p->subs[SUB_CALLWAIT].inthreeway) { 02530 /* The other party of the three way call is currently in a call-wait state. 02531 Start music on hold for them, and take the main guy out of the third call */ 02532 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 02533 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 02534 S_OR(p->mohsuggest, NULL), 02535 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 02536 } 02537 p->subs[SUB_CALLWAIT].inthreeway = 0; 02538 } 02539 p->subs[SUB_REAL].inthreeway = 0; 02540 /* If this was part of a three way call index, let us make 02541 another three way call */ 02542 unalloc_sub(p, SUB_THREEWAY); 02543 } else { 02544 /* This wasn't any sort of call, but how are we an index? */ 02545 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 02546 } 02547 } 02548 02549 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 02550 p->owner = NULL; 02551 p->ringt = 0; 02552 p->distinctivering = 0; 02553 p->confirmanswer = 0; 02554 p->cidrings = 1; 02555 p->outgoing = 0; 02556 p->digital = 0; 02557 p->faxhandled = 0; 02558 p->pulsedial = 0; 02559 p->onhooktime = time(NULL); 02560 #ifdef HAVE_PRI 02561 p->proceeding = 0; 02562 p->progress = 0; 02563 p->alerting = 0; 02564 p->setup_ack = 0; 02565 #endif 02566 if (p->dsp) { 02567 ast_dsp_free(p->dsp); 02568 p->dsp = NULL; 02569 } 02570 02571 law = ZT_LAW_DEFAULT; 02572 res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law); 02573 if (res < 0) 02574 ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel); 02575 /* Perform low level hangup if no owner left */ 02576 #ifdef HAVE_PRI 02577 if (p->pri) { 02578 #ifdef SUPPORT_USERUSER 02579 const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO"); 02580 #endif 02581 02582 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */ 02583 if (p->call && (!p->bearer || (p->bearer->call == p->call))) { 02584 if (!pri_grab(p, p->pri)) { 02585 if (p->alreadyhungup) { 02586 ast_log(LOG_DEBUG, "Already hungup... Calling hangup once, and clearing call\n"); 02587 02588 #ifdef SUPPORT_USERUSER 02589 pri_call_set_useruser(p->call, useruser); 02590 #endif 02591 02592 pri_hangup(p->pri->pri, p->call, -1); 02593 p->call = NULL; 02594 if (p->bearer) 02595 p->bearer->call = NULL; 02596 } else { 02597 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE"); 02598 int icause = ast->hangupcause ? ast->hangupcause : -1; 02599 ast_log(LOG_DEBUG, "Not yet hungup... Calling hangup once with icause, and clearing call\n"); 02600 02601 #ifdef SUPPORT_USERUSER 02602 pri_call_set_useruser(p->call, useruser); 02603 #endif 02604 02605 p->alreadyhungup = 1; 02606 if (p->bearer) 02607 p->bearer->alreadyhungup = 1; 02608 if (cause) { 02609 if (atoi(cause)) 02610 icause = atoi(cause); 02611 } 02612 pri_hangup(p->pri->pri, p->call, icause); 02613 } 02614 if (res < 0) 02615 ast_log(LOG_WARNING, "pri_disconnect failed\n"); 02616 pri_rel(p->pri); 02617 } else { 02618 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 02619 res = -1; 02620 } 02621 } else { 02622 if (p->bearer) 02623 ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call); 02624 p->call = NULL; 02625 res = 0; 02626 } 02627 } 02628 #endif 02629 if (p->sig && (p->sig != SIG_PRI)) 02630 res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); 02631 if (res < 0) { 02632 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 02633 } 02634 switch (p->sig) { 02635 case SIG_FXOGS: 02636 case SIG_FXOLS: 02637 case SIG_FXOKS: 02638 res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); 02639 if (!res) { 02640 #if 0 02641 ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 02642 #endif 02643 /* If they're off hook, try playing congestion */ 02644 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0)))) 02645 tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); 02646 else 02647 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02648 } 02649 break; 02650 case SIG_FXSGS: 02651 case SIG_FXSLS: 02652 case SIG_FXSKS: 02653 /* Make sure we're not made available for at least two seconds assuming 02654 we were actually used for an inbound or outbound call. */ 02655 if (ast->_state != AST_STATE_RESERVED) { 02656 time(&p->guardtime); 02657 p->guardtime += 2; 02658 } 02659 break; 02660 default: 02661 tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1); 02662 } 02663 if (p->cidspill) 02664 free(p->cidspill); 02665 if (p->sig) 02666 zt_disable_ec(p); 02667 x = 0; 02668 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 02669 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 02670 p->didtdd = 0; 02671 p->cidspill = NULL; 02672 p->callwaitcas = 0; 02673 p->callwaiting = p->permcallwaiting; 02674 p->hidecallerid = p->permhidecallerid; 02675 p->dialing = 0; 02676 p->rdnis[0] = '\0'; 02677 update_conf(p); 02678 reset_conf(p); 02679 /* Restore data mode */ 02680 if (p->sig == SIG_PRI) { 02681 x = 0; 02682 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 02683 } 02684 #ifdef HAVE_PRI 02685 if (p->bearer) { 02686 ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel); 02687 /* Free up the bearer channel as well, and 02688 don't use its file descriptor anymore */ 02689 update_conf(p->bearer); 02690 reset_conf(p->bearer); 02691 p->bearer->owner = NULL; 02692 p->bearer->realcall = NULL; 02693 p->bearer = NULL; 02694 p->subs[SUB_REAL].zfd = -1; 02695 p->pri = NULL; 02696 } 02697 #endif 02698 restart_monitor(); 02699 } 02700 02701 p->callwaitingrepeat = 0; 02702 p->cidcwexpire = 0; 02703 p->oprmode = 0; 02704 ast->tech_pvt = NULL; 02705 ast_mutex_unlock(&p->lock); 02706 ast_module_unref(ast_module_info->self); 02707 if (option_verbose > 2) 02708 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name); 02709 02710 ast_mutex_lock(&iflock); 02711 tmp = iflist; 02712 prev = NULL; 02713 if (p->destroy) { 02714 while (tmp) { 02715 if (tmp == p) { 02716 destroy_channel(prev, tmp, 0); 02717 break; 02718 } else { 02719 prev = tmp; 02720 tmp = tmp->next; 02721 } 02722 } 02723 } 02724 ast_mutex_unlock(&iflock); 02725 return 0; 02726 }
| static int zt_indicate | ( | struct ast_channel * | chan, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 4985 of file chan_zap.c.
References ast_channel::_softhangup, ast_channel::_state, AST_CAUSE_CONGESTION, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, zt_pvt::digital, zt_pvt::dop, func, ast_channel::hangupcause, ISTRUNK, zt_pvt::lock, LOG_DEBUG, zt_pvt::mohinterpret, zt_pvt::outgoing, zt_pvt::priindication_oob, zt_pvt::radio, zt_pvt::sig, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, zt_pvt::span, SUB_REAL, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_set_hook().
04986 { 04987 struct zt_pvt *p = chan->tech_pvt; 04988 int res=-1; 04989 int index; 04990 int func = ZT_FLASH; 04991 ast_mutex_lock(&p->lock); 04992 index = zt_get_index(chan, p, 0); 04993 ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name); 04994 if (index == SUB_REAL) { 04995 switch (condition) { 04996 case AST_CONTROL_BUSY: 04997 #ifdef HAVE_PRI 04998 if (p->priindication_oob && p->sig == SIG_PRI) { 04999 chan->hangupcause = AST_CAUSE_USER_BUSY; 05000 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05001 res = 0; 05002 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05003 if (p->pri->pri) { 05004 if (!pri_grab(p, p->pri)) { 05005 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05006 pri_rel(p->pri); 05007 } 05008 else 05009 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05010 } 05011 p->progress = 1; 05012 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05013 } else 05014 #endif 05015 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY); 05016 break; 05017 case AST_CONTROL_RINGING: 05018 #ifdef HAVE_PRI 05019 if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) { 05020 if (p->pri->pri) { 05021 if (!pri_grab(p, p->pri)) { 05022 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05023 pri_rel(p->pri); 05024 } 05025 else 05026 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05027 } 05028 p->alerting = 1; 05029 } 05030 #endif 05031 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE); 05032 if (chan->_state != AST_STATE_UP) { 05033 if ((chan->_state != AST_STATE_RING) || 05034 ((p->sig != SIG_FXSKS) && 05035 (p->sig != SIG_FXSLS) && 05036 (p->sig != SIG_FXSGS))) 05037 ast_setstate(chan, AST_STATE_RINGING); 05038 } 05039 break; 05040 case AST_CONTROL_PROCEEDING: 05041 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 05042 #ifdef HAVE_PRI 05043 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05044 if (p->pri->pri) { 05045 if (!pri_grab(p, p->pri)) { 05046 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 05047 pri_rel(p->pri); 05048 } 05049 else 05050 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05051 } 05052 p->proceeding = 1; 05053 } 05054 #endif 05055 /* don't continue in ast_indicate */ 05056 res = 0; 05057 break; 05058 case AST_CONTROL_PROGRESS: 05059 ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 05060 #ifdef HAVE_PRI 05061 p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */ 05062 if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05063 if (p->pri->pri) { 05064 if (!pri_grab(p, p->pri)) { 05065 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05066 pri_rel(p->pri); 05067 } 05068 else 05069 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05070 } 05071 p->progress = 1; 05072 } 05073 #endif 05074 /* don't continue in ast_indicate */ 05075 res = 0; 05076 break; 05077 case AST_CONTROL_CONGESTION: 05078 chan->hangupcause = AST_CAUSE_CONGESTION; 05079 #ifdef HAVE_PRI 05080 if (p->priindication_oob && p->sig == SIG_PRI) { 05081 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 05082 chan->_softhangup |= AST_SOFTHANGUP_DEV; 05083 res = 0; 05084 } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) { 05085 if (p->pri) { 05086 if (!pri_grab(p, p->pri)) { 05087 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1); 05088 pri_rel(p->pri); 05089 } else 05090 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05091 } 05092 p->progress = 1; 05093 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05094 } else 05095 #endif 05096 res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); 05097 break; 05098 case AST_CONTROL_HOLD: 05099 #ifdef HAVE_PRI 05100 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05101 if (!pri_grab(p, p->pri)) { 05102 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); 05103 pri_rel(p->pri); 05104 } else 05105 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05106 } else 05107 #endif 05108 ast_moh_start(chan, data, p->mohinterpret); 05109 break; 05110 case AST_CONTROL_UNHOLD: 05111 #ifdef HAVE_PRI 05112 if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) { 05113 if (!pri_grab(p, p->pri)) { 05114 res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); 05115 pri_rel(p->pri); 05116 } else 05117 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 05118 } else 05119 #endif 05120 ast_moh_stop(chan); 05121 break; 05122 case AST_CONTROL_RADIO_KEY: 05123 if (p->radio) 05124 res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); 05125 res = 0; 05126 break; 05127 case AST_CONTROL_RADIO_UNKEY: 05128 if (p->radio) 05129 res = zt_set_hook(p->subs[index].zfd, ZT_RINGOFF); 05130 res = 0; 05131 break; 05132 case AST_CONTROL_FLASH: 05133 /* flash hookswitch */ 05134 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 05135 /* Clear out the dial buffer */ 05136 p->dop.dialstr[0] = '\0'; 05137 if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 05138 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 05139 chan->name, strerror(errno)); 05140 } else 05141 res = 0; 05142 } else 05143 res = 0; 05144 break; 05145 case -1: 05146 res = tone_zone_play_tone(p->subs[index].zfd, -1); 05147 break; 05148 } 05149 } else 05150 res = 0; 05151 ast_mutex_unlock(&p->lock); 05152 return res; 05153 }
Definition at line 3071 of file chan_zap.c.
References ast_log(), LOG_WARNING, and master.
Referenced by zt_bridge().
03071 { 03072 int x; 03073 if (!slave || !master) { 03074 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 03075 return; 03076 } 03077 for (x = 0; x < MAX_SLAVES; x++) { 03078 if (!master->slaves[x]) { 03079 master->slaves[x] = slave; 03080 break; 03081 } 03082 } 03083 if (x >= MAX_SLAVES) { 03084 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 03085 master->slaves[MAX_SLAVES - 1] = slave; 03086 } 03087 if (slave->master) 03088 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 03089 slave->master = master; 03090 03091 ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 03092 }
| static struct ast_channel * zt_new | ( | struct zt_pvt * | , | |
| int | , | |||
| int | , | |||
| int | , | |||
| int | , | |||
| int | ||||
| ) | [static] |
Definition at line 5155 of file chan_zap.c.
References accountcode, zt_pvt::accountcode, zt_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, zt_pvt::amaflags, asprintf, AST_ADSI_UNAVAILABLE, ast_channel_alloc(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_busy_count(), ast_dsp_set_busy_pattern(), ast_dsp_set_call_progress_zone(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), ast_random(), AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_transfercapability2str(), zt_pvt::busy_quietlength, zt_pvt::busy_tonelength, zt_pvt::busycount, zt_pvt::busydetect, zt_pvt::call_forward, zt_pvt::callgroup, ast_channel::callgroup, zt_pvt::callingpres, zt_pvt::callprogress, CANBUSYDETECT, CANPROGRESSDETECT, CHAN_PSEUDO, zt_pvt::channel, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, zt_pvt::cid_name, ast_callerid::cid_name, zt_pvt::cid_num, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, zt_pvt::cid_ton, ast_callerid::cid_ton, ast_channel::context, zt_pvt::context, zt_pvt::digital, zt_pvt::dnid, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, zt_pvt::dsp_features, DSP_PROGRESS_TALK, zt_pvt::dtmfrelax, ast_channel::exten, zt_pvt::exten, zt_pvt::fake_event, ast_channel::fds, free, global_jbconf, zt_pvt::hardwaredtmf, language, zt_pvt::language, zt_subchannel::linear, LOG_DEBUG, ast_channel::nativeformats, NEED_MFDETECT, zt_pvt::outgoing, zt_pvt::owner, zt_subchannel::owner, pbx_builtin_setvar_helper(), zt_pvt::pickupgroup, ast_channel::pickupgroup, PRI_TRANS_CAP_DIGITAL, ast_channel::rawreadformat, ast_channel::rawwriteformat, zt_pvt::rdnis, ast_channel::readformat, ast_channel::rings, zt_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_PRI, SUB_REAL, zt_pvt::subs, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, ast_channel::writeformat, zap_tech, zt_subchannel::zfd, zt_confmute(), and zt_setlinear().
Referenced by handle_init_event(), zt_handle_event(), and zt_request().
05156 { 05157 struct ast_channel *tmp; 05158 int deflaw; 05159 int res; 05160 int x,y; 05161 int features; 05162 char *b2 = 0; 05163 ZT_PARAMS ps; 05164 if (i->subs[index].owner) { 05165 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]); 05166 return NULL; 05167 } 05168 y = 1; 05169 do { 05170 if (b2) 05171 free(b2); 05172 #ifdef HAVE_PRI 05173 if (i->bearer || (i->pri && (i->sig == SIG_FXSKS))) 05174 asprintf(&b2, "Zap/%d:%d-%d", i->pri->trunkgroup, i->channel, y); 05175 else 05176 #endif 05177 if (i->channel == CHAN_PSEUDO) 05178 asprintf(&b2, "Zap/pseudo-%ld", ast_random()); 05179 else 05180 asprintf(&b2, "Zap/%d-%d", i->channel, y); 05181 for (x = 0; x < 3; x++) { 05182 if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name)) 05183 break; 05184 } 05185 y++; 05186 } while (x < 3); 05187 tmp = ast_channel_alloc(0, state, 0, 0, i->accountcode, i->exten, i->context, i->amaflags, b2); 05188 if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */ 05189 free(b2); 05190 if (!tmp) 05191 return NULL; 05192 tmp->tech = &zap_tech; 05193 ps.channo = i->channel; 05194 res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps); 05195 if (res) { 05196 ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n"); 05197 ps.curlaw = ZT_LAW_MULAW; 05198 } 05199 if (ps.curlaw == ZT_LAW_ALAW) 05200 deflaw = AST_FORMAT_ALAW; 05201 else 05202 deflaw = AST_FORMAT_ULAW; 05203 if (law) { 05204 if (law == ZT_LAW_ALAW) 05205 deflaw = AST_FORMAT_ALAW; 05206 else 05207 deflaw = AST_FORMAT_ULAW; 05208 } 05209 tmp->fds[0] = i->subs[index].zfd; 05210 tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw; 05211 /* Start out assuming ulaw since it's smaller :) */ 05212 tmp->rawreadformat = deflaw; 05213 tmp->readformat = deflaw; 05214 tmp->rawwriteformat = deflaw; 05215 tmp->writeformat = deflaw; 05216 i->subs[index].linear = 0; 05217 zt_setlinear(i->subs[index].zfd, i->subs[index].linear); 05218 features = 0; 05219 if (i->busydetect && CANBUSYDETECT(i)) 05220 features |= DSP_FEATURE_BUSY_DETECT; 05221 if ((i->callprogress & 1) && CANPROGRESSDETECT(i)) 05222 features |= DSP_FEATURE_CALL_PROGRESS; 05223 if ((!i->outgoing && (i->callprogress & 4)) || 05224 (i->outgoing && (i->callprogress & 2))) { 05225 features |= DSP_FEATURE_FAX_DETECT; 05226 } 05227 #ifdef ZT_TONEDETECT 05228 x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; 05229 if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) { 05230 #endif 05231 i->hardwaredtmf = 0; 05232 features |= DSP_FEATURE_DTMF_DETECT; 05233 #ifdef ZT_TONEDETECT 05234 } else if (NEED_MFDETECT(i)) { 05235 i->hardwaredtmf = 1; 05236 features |= DSP_FEATURE_DTMF_DETECT; 05237 } 05238 #endif 05239 if (features) { 05240 if (i->dsp) { 05241 ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name); 05242 } else { 05243 if (i->channel != CHAN_PSEUDO) 05244 i->dsp = ast_dsp_new(); 05245 else 05246 i->dsp = NULL; 05247 if (i->dsp) { 05248 i->dsp_features = features & ~DSP_PROGRESS_TALK; 05249 #ifdef HAVE_PRI 05250 /* We cannot do progress detection until receives PROGRESS message */ 05251 if (i->outgoing && (i->sig == SIG_PRI)) { 05252 /* Remember requested DSP features, don't treat 05253 talking as ANSWER */ 05254 features = 0; 05255 } 05256 #endif 05257 ast_dsp_set_features(i->dsp, features); 05258 ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 05259 if (!ast_strlen_zero(progzone)) 05260 ast_dsp_set_call_progress_zone(i->dsp, progzone); 05261 if (i->busydetect && CANBUSYDETECT(i)) { 05262 ast_dsp_set_busy_count(i->dsp, i->busycount); 05263 ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength); 05264 } 05265 } 05266 } 05267 } 05268 05269 if (state == AST_STATE_RING) 05270 tmp->rings = 1; 05271 tmp->tech_pvt = i; 05272 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 05273 /* Only FXO signalled stuff can be picked up */ 05274 tmp->callgroup = i->callgroup; 05275 tmp->pickupgroup = i->pickupgroup; 05276 } 05277 if (!ast_strlen_zero(i->language)) 05278 ast_string_field_set(tmp, language, i->language); 05279 if (!i->owner) 05280 i->owner = tmp; 05281 if (!ast_strlen_zero(i->accountcode)) 05282 ast_string_field_set(tmp, accountcode, i->accountcode); 05283 if (i->amaflags) 05284 tmp->amaflags = i->amaflags; 05285 i->subs[index].owner = tmp; 05286 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05287 ast_string_field_set(tmp, call_forward, i->call_forward); 05288 /* If we've been told "no ADSI" then enforce it */ 05289 if (!i->adsi) 05290 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05291 if (!ast_strlen_zero(i->exten)) 05292 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05293 if (!ast_strlen_zero(i->rdnis)) 05294 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05295 if (!ast_strlen_zero(i->dnid)) 05296 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05297 05298 /* Don't use ast_set_callerid() here because it will 05299 * generate a needless NewCallerID event */ 05300 #ifdef PRI_ANI 05301 tmp->cid.cid_num = ast_strdup(i->cid_num); 05302 tmp->cid.cid_name = ast_strdup(i->cid_name); 05303 if (!ast_strlen_zero(i->cid_ani)) 05304 tmp->cid.cid_ani = ast_strdup(i->cid_ani); 05305 else 05306 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05307 #else 05308 tmp->cid.cid_num = ast_strdup(i->cid_num); 05309 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05310 tmp->cid.cid_name = ast_strdup(i->cid_name); 05311 #endif 05312 tmp->cid.cid_pres = i->callingpres; 05313 tmp->cid.cid_ton = i->cid_ton; 05314 #ifdef HAVE_PRI 05315 tmp->transfercapability = transfercapability; 05316 pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability)); 05317 if (transfercapability & PRI_TRANS_CAP_DIGITAL) 05318 i->digital = 1; 05319 /* Assume calls are not idle calls unless we're told differently */ 05320 i->isidlecall = 0; 05321 i->alreadyhungup = 0; 05322 #endif 05323 /* clear the fake event in case we posted one before we had ast_channel */ 05324 i->fake_event = 0; 05325 /* Assure there is no confmute on this channel */ 05326 zt_confmute(i, 0); 05327 /* Configure the new channel jb */ 05328 ast_jb_configure(tmp, &global_jbconf); 05329 if (startpbx) { 05330 if (ast_pbx_start(tmp)) { 05331 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05332 ast_hangup(tmp); 05333 i->owner = NULL; 05334 return NULL; 05335 } 05336 } 05337 05338 ast_module_ref(ast_module_info->self); 05339 05340 return tmp; 05341 }
| static int zt_open | ( | char * | fn | ) | [static] |
Definition at line 871 of file chan_zap.c.
References ast_log(), LOG_WARNING, and READ_SIZE.
Referenced by alloc_sub(), chandup(), and mkintf().
00872 { 00873 int fd; 00874 int isnum; 00875 int chan = 0; 00876 int bs; 00877 int x; 00878 isnum = 1; 00879 for (x = 0; x < strlen(fn); x++) { 00880 if (!isdigit(fn[x])) { 00881 isnum = 0; 00882 break; 00883 } 00884 } 00885 if (isnum) { 00886 chan = atoi(fn); 00887 if (chan < 1) { 00888 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn); 00889 return -1; 00890 } 00891 fn = "/dev/zap/channel"; 00892 } 00893 fd = open(fn, O_RDWR | O_NONBLOCK); 00894 if (fd < 0) { 00895 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno)); 00896 return -1; 00897 } 00898 if (chan) { 00899 if (ioctl(fd, ZT_SPECIFY, &chan)) { 00900 x = errno; 00901 close(fd); 00902 errno = x; 00903 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno)); 00904 return -1; 00905 } 00906 } 00907 bs = READ_SIZE; 00908 if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) return -1; 00909 return fd; 00910 }
| static struct ast_frame * zt_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 4587 of file chan_zap.c.
References __zt_exception(), ast_channel::_state, ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_dsp_process(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_callerid(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verbose(), zt_subchannel::buffer, zt_pvt::busydetect, zt_pvt::callprogress, zt_pvt::callwaitcas, zt_pvt::callwaitingrepeat, zt_pvt::callwaitrings, zt_pvt::channel, CHECK_BLOCKING, zt_pvt::cidcwexpire, zt_pvt::cidrings, zt_pvt::cidspill, ast_frame::data, ast_frame::datalen, ast_frame::delivery, zt_pvt::dialing, zt_pvt::dsp, zt_subchannel::f, f, zt_pvt::fake_event, zt_pvt::firstradio, ast_frame::frametype, zt_pvt::ignoredtmf, zt_pvt::inalarm, zt_subchannel::inthreeway, zt_pvt::lastcid_name, zt_pvt::lastcid_num, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, ast_frame::mallocd, zt_subchannel::needanswer, zt_subchannel::needbusy, zt_subchannel::needcallerid, zt_subchannel::needcongestion, zt_subchannel::needflash, zt_subchannel::needhold, zt_subchannel::needringing, zt_subchannel::needunhold, ast_frame::offset, zt_pvt::oprmode, option_verbose, zt_pvt::outgoing, zt_pvt::overlapdial, zt_pvt::owner, zt_pvt::pulsedial, zt_pvt::radio, ast_channel::rawreadformat, READ_SIZE, restore_conference(), ast_channel::rings, zt_pvt::ringt, S_OR, ast_frame::samples, send_callerid(), zt_pvt::sig, SIG_PRI, ast_frame::src, SUB_CALLWAIT, SUB_REAL, ast_frame::subclass, zt_pvt::subs, zt_pvt::tdd, tdd_feed(), ast_channel::tech_pvt, VERBOSE_PREFIX_3, zt_subchannel::zfd, zt_callwait(), zt_get_index(), zt_handle_dtmfup(), and zt_setlinear().
04588 { 04589 struct zt_pvt *p = ast->tech_pvt; 04590 int res; 04591 int index; 04592 void *readbuf; 04593 struct ast_frame *f; 04594 04595 04596 ast_mutex_lock(&p->lock); 04597 04598 index = zt_get_index(ast, p, 0); 04599 04600 /* Hang up if we don't really exist */ 04601 if (index < 0) { 04602 ast_log(LOG_WARNING, "We dont exist?\n"); 04603 ast_mutex_unlock(&p->lock); 04604 return NULL; 04605 } 04606 04607 if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL; 04608 04609 p->subs[index].f.frametype = AST_FRAME_NULL; 04610 p->subs[index].f.datalen = 0; 04611 p->subs[index].f.samples = 0; 04612 p->subs[index].f.mallocd = 0; 04613 p->subs[index].f.offset = 0; 04614 p->subs[index].f.subclass = 0; 04615 p->subs[index].f.delivery = ast_tv(0,0); 04616 p->subs[index].f.src = "zt_read"; 04617 p->subs[index].f.data = NULL; 04618 04619 /* make sure it sends initial key state as first frame */ 04620 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio)) 04621 { 04622 ZT_PARAMS ps; 04623 04624 ps.channo = p->channel; 04625 if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) { 04626 ast_mutex_unlock(&p->lock); 04627 return NULL; 04628 } 04629 p->firstradio = 1; 04630 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04631 if (ps.rxisoffhook) 04632 { 04633 p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY; 04634 } 04635 else 04636 { 04637 p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY; 04638 } 04639 ast_mutex_unlock(&p->lock); 04640 return &p->subs[index].f; 04641 } 04642 if (p->ringt == 1) { 04643 ast_mutex_unlock(&p->lock); 04644 return NULL; 04645 } 04646 else if (p->ringt > 0) 04647 p->ringt--; 04648 04649 if (p->subs[index].needringing) { 04650 /* Send ringing frame if requested */ 04651 p->subs[index].needringing = 0; 04652 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04653 p->subs[index].f.subclass = AST_CONTROL_RINGING; 04654 ast_setstate(ast, AST_STATE_RINGING); 04655 ast_mutex_unlock(&p->lock); 04656 return &p->subs[index].f; 04657 } 04658 04659 if (p->subs[index].needbusy) { 04660 /* Send busy frame if requested */ 04661 p->subs[index].needbusy = 0; 04662 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04663 p->subs[index].f.subclass = AST_CONTROL_BUSY; 04664 ast_mutex_unlock(&p->lock); 04665 return &p->subs[index].f; 04666 } 04667 04668 if (p->subs[index].needcongestion) { 04669 /* Send congestion frame if requested */ 04670 p->subs[index].needcongestion = 0; 04671 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04672 p->subs[index].f.subclass = AST_CONTROL_CONGESTION; 04673 ast_mutex_unlock(&p->lock); 04674 return &p->subs[index].f; 04675 } 04676 04677 if (p->subs[index].needcallerid) { 04678 ast_set_callerid(ast, S_OR(p->lastcid_num, NULL), 04679 S_OR(p->lastcid_name, NULL), 04680 S_OR(p->lastcid_num, NULL) 04681 ); 04682 p->subs[index].needcallerid = 0; 04683 } 04684 04685 if (p->subs[index].needanswer) { 04686 /* Send answer frame if requested */ 04687 p->subs[index].needanswer = 0; 04688 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04689 p->subs[index].f.subclass = AST_CONTROL_ANSWER; 04690 ast_mutex_unlock(&p->lock); 04691 return &p->subs[index].f; 04692 } 04693 04694 if (p->subs[index].needflash) { 04695 /* Send answer frame if requested */ 04696 p->subs[index].needflash = 0; 04697 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04698 p->subs[index].f.subclass = AST_CONTROL_FLASH; 04699 ast_mutex_unlock(&p->lock); 04700 return &p->subs[index].f; 04701 } 04702 04703 if (p->subs[index].needhold) { 04704 /* Send answer frame if requested */ 04705 p->subs[index].needhold = 0; 04706 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04707 p->subs[index].f.subclass = AST_CONTROL_HOLD; 04708 ast_mutex_unlock(&p->lock); 04709 ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name); 04710 return &p->subs[index].f; 04711 } 04712 04713 if (p->subs[index].needunhold) { 04714 /* Send answer frame if requested */ 04715 p->subs[index].needunhold = 0; 04716 p->subs[index].f.frametype = AST_FRAME_CONTROL; 04717 p->subs[index].f.subclass = AST_CONTROL_UNHOLD; 04718 ast_mutex_unlock(&p->lock); 04719 ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name); 04720 return &p->subs[index].f; 04721 } 04722 04723 if (ast->rawreadformat == AST_FORMAT_SLINEAR) { 04724 if (!p->subs[index].linear) { 04725 p->subs[index].linear = 1; 04726 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04727 if (res) 04728 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index); 04729 } 04730 } else if ((ast->rawreadformat == AST_FORMAT_ULAW) || 04731 (ast->rawreadformat == AST_FORMAT_ALAW)) { 04732 if (p->subs[index].linear) { 04733 p->subs[index].linear = 0; 04734 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04735 if (res) 04736 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index); 04737 } 04738 } else { 04739 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat)); 04740 ast_mutex_unlock(&p->lock); 04741 return NULL; 04742 } 04743 readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET; 04744 CHECK_BLOCKING(ast); 04745 res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04746 ast_clear_flag(ast, AST_FLAG_BLOCKING); 04747 /* Check for hangup */ 04748 if (res < 0) { 04749 f = NULL; 04750 if (res == -1) { 04751 if (errno == EAGAIN) { 04752 /* Return "NULL" frame if there is nobody there */ 04753 ast_mutex_unlock(&p->lock); 04754 return &p->subs[index].f; 04755 } else if (errno == ELAST) { 04756 f = __zt_exception(ast); 04757 } else 04758 ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno)); 04759 } 04760 ast_mutex_unlock(&p->lock); 04761 return f; 04762 } 04763 if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) { 04764 ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE); 04765 f = __zt_exception(ast); 04766 ast_mutex_unlock(&p->lock); 04767 return f; 04768 } 04769 if (p->tdd) { /* if in TDD mode, see if we receive that */ 04770 int c; 04771 04772 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 04773 if (c < 0) { 04774 ast_log(LOG_DEBUG,"tdd_feed failed\n"); 04775 ast_mutex_unlock(&p->lock); 04776 return NULL; 04777 } 04778 if (c) { /* if a char to return */ 04779 p->subs[index].f.subclass = 0; 04780 p->subs[index].f.frametype = AST_FRAME_TEXT; 04781 p->subs[index].f.mallocd = 0; 04782 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04783 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET; 04784 p->subs[index].f.datalen = 1; 04785 *((char *) p->subs[index].f.data) = c; 04786 ast_mutex_unlock(&p->lock); 04787 return &p->subs[index].f; 04788 } 04789 } 04790 if (p->callwaitingrepeat) 04791 p->callwaitingrepeat--; 04792 if (p->cidcwexpire) 04793 p->cidcwexpire--; 04794 /* Repeat callwaiting */ 04795 if (p->callwaitingrepeat == 1) { 04796 p->callwaitrings++; 04797 zt_callwait(ast); 04798 } 04799 /* Expire CID/CW */ 04800 if (p->cidcwexpire == 1) { 04801 if (option_verbose > 2) 04802 ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n"); 04803 restore_conference(p); 04804 } 04805 if (p->subs[index].linear) { 04806 p->subs[index].f.datalen = READ_SIZE * 2; 04807 } else 04808 p->subs[index].f.datalen = READ_SIZE; 04809 04810 /* Handle CallerID Transmission */ 04811 if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) { 04812 send_callerid(p); 04813 } 04814 04815 p->subs[index].f.frametype = AST_FRAME_VOICE; 04816 p->subs[index].f.subclass = ast->rawreadformat; 04817 p->subs[index].f.samples = READ_SIZE; 04818 p->subs[index].f.mallocd = 0; 04819 p->subs[index].f.offset = AST_FRIENDLY_OFFSET; 04820 p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]); 04821 #if 0 04822 ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name); 04823 #endif 04824 if (p->dialing || /* Transmitting something */ 04825 (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 04826 ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 04827 ) { 04828 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 04829 don't send anything */ 04830 p->subs[index].f.frametype = AST_FRAME_NULL; 04831 p->subs[index].f.subclass = 0; 04832 p->subs[index].f.samples = 0; 04833 p->subs[index].f.mallocd = 0; 04834 p->subs[index].f.offset = 0; 04835 p->subs[index].f.data = NULL; 04836 p->subs[index].f.datalen= 0; 04837 } 04838 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) { 04839 /* Perform busy detection. etc on the zap line */ 04840 f = ast_dsp_process(ast, p->dsp, &p->subs[index].f); 04841 if (f) { 04842 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) { 04843 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 04844 /* Treat this as a "hangup" instead of a "busy" on the assumption that 04845 a busy */ 04846 f = NULL; 04847 } 04848 } else if (f->frametype == AST_FRAME_DTMF) { 04849 #ifdef HAVE_PRI 04850 if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) { 04851 /* Don't accept in-band DTMF when in overlap dial mode */ 04852 f->frametype = AST_FRAME_NULL; 04853 f->subclass = 0; 04854 } 04855 #endif 04856 /* DSP clears us of being pulse */ 04857 p->pulsedial = 0; 04858 } 04859 } 04860 } else 04861 f = &p->subs[index].f; 04862 04863 if (f && (f->frametype == AST_FRAME_DTMF)) 04864 zt_handle_dtmfup(ast, index, &f); 04865 04866 /* If we have a fake_event, trigger exception to handle it */ 04867 if (p->fake_event) 04868 ast_set_flag(ast, AST_FLAG_EXCEPTION); 04869 04870 ast_mutex_unlock(&p->lock); 04871 return f; 04872 }
| static struct ast_channel * zt_request | ( | const char * | type, | |
| int | format, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static] |
Definition at line 7698 of file chan_zap.c.
References alloc_sub(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CDR_CALLWAIT, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RESERVED, ast_strdupa, AST_TRANS_CAP_DIGITAL, ast_verbose(), available(), ast_channel::cdrflags, CHAN_PSEUDO, chandup(), zt_pvt::channel, zt_pvt::confirmanswer, zt_pvt::digital, zt_pvt::distinctivering, iflist, zt_pvt::inalarm, lock, LOG_DEBUG, LOG_NOTICE, zt_pvt::next, option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::prev, restart_monitor(), round_robin, s, zt_pvt::sig, SIG_FXSKS, strsep(), SUB_CALLWAIT, SUB_REAL, zt_pvt::subs, ast_channel::transfercapability, zt_subchannel::zfd, and zt_new().
07699 { 07700 int groupmatch = 0; 07701 int channelmatch = -1; 07702 int roundrobin = 0; 07703 int callwait = 0; 07704 int busy = 0; 07705 struct zt_pvt *p; 07706 struct ast_channel *tmp = NULL; 07707 char *dest=NULL; 07708 int x; 07709 char *s; 07710 char opt=0; 07711 int res=0, y=0; 07712 int backwards = 0; 07713 #ifdef HAVE_PRI 07714 int crv; 07715 int bearer = -1; 07716 int trunkgroup; 07717 struct zt_pri *pri=NULL; 07718 #endif 07719 struct zt_pvt *exit, *start, *end; 07720 ast_mutex_t *lock; 07721 int channelmatched = 0; 07722 int groupmatched = 0; 07723 07724 /* Assume we're locking the iflock */ 07725 lock = &iflock; 07726 start = iflist; 07727 end = ifend; 07728 if (data) { 07729 dest = ast_strdupa((char *)data); 07730 } else { 07731 ast_log(LOG_WARNING, "Channel requested with no data\n"); 07732 return NULL; 07733 } 07734 if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') { 07735 /* Retrieve the group number */ 07736 char *stringp=NULL; 07737 stringp=dest + 1; 07738 s = strsep(&stringp, "/"); 07739 if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 07740 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data); 07741 return NULL; 07742 } 07743 groupmatch = 1 << x; 07744 if (toupper(dest[0]) == 'G') { 07745 if (dest[0] == 'G') { 07746 backwards = 1; 07747 p = ifend; 07748 } else 07749 p = iflist; 07750 } else { 07751 if (dest[0] == 'R') { 07752 backwards = 1; 07753 p = round_robin[x]?round_robin[x]->prev:ifend; 07754 if (!p) 07755 p = ifend; 07756 } else { 07757 p = round_robin[x]?round_robin[x]->next:iflist; 07758 if (!p) 07759 p = iflist; 07760 } 07761 roundrobin = 1; 07762 } 07763 } else { 07764 char *stringp=NULL; 07765 stringp=dest; 07766 s = strsep(&stringp, "/"); 07767 p = iflist; 07768 if (!strcasecmp(s, "pseudo")) { 07769 /* Special case for pseudo */ 07770 x = CHAN_PSEUDO; 07771 channelmatch = x; 07772 } 07773 #ifdef HAVE_PRI 07774 else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) { 07775 if ((trunkgroup < 1) || (crv < 1)) { 07776 ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data); 07777 return NULL; 07778 } 07779 res--; 07780 for (x = 0; x < NUM_SPANS; x++) { 07781 if (pris[x].trunkgroup == trunkgroup) { 07782 pri = pris + x; 07783 lock = &pri->lock; 07784 start = pri->crvs; 07785 end = pri->crvend; 07786 break; 07787 } 07788 } 07789 if (!pri) { 07790 ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup); 07791 return NULL; 07792 } 07793 channelmatch = crv; 07794 p = pris[x].crvs; 07795 } 07796 #endif 07797 else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) { 07798 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data); 07799 return NULL; 07800 } else { 07801 channelmatch = x; 07802 } 07803 } 07804 /* Search for an unowned channel */ 07805 ast_mutex_lock(lock); 07806 exit = p; 07807 while (p && !tmp) { 07808 if (roundrobin) 07809 round_robin[x] = p; 07810 #if 0 07811 ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch); 07812 #endif 07813 07814 if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) { 07815 if (option_debug) 07816 ast_log(LOG_DEBUG, "Using channel %d\n", p->channel); 07817 if (p->inalarm) 07818 goto next; 07819 07820 callwait = (p->owner != NULL); 07821 #ifdef HAVE_PRI 07822 if (pri && (p->subs[SUB_REAL].zfd < 0)) { 07823 if (p->sig != SIG_FXSKS) { 07824 /* Gotta find an actual channel to use for this 07825 CRV if this isn't a callwait */ 07826 bearer = pri_find_empty_chan(pri, 0); 07827 if (bearer < 0) { 07828 ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv); 07829 p = NULL; 07830 break; 07831 } 07832 pri_assign_bearer(p, pri, pri->pvts[bearer]); 07833 } else { 07834 if (alloc_sub(p, 0)) { 07835 ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n"); 07836 p = NULL; 07837 break; 07838 } else 07839 ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n"); 07840 p->pri = pri; 07841 } 07842 } 07843 #endif 07844 if (p->channel == CHAN_PSEUDO) { 07845 p = chandup(p); 07846 if (!p) { 07847 break; 07848 } 07849 } 07850 if (p->owner) { 07851 if (alloc_sub(p, SUB_CALLWAIT)) { 07852 p = NULL; 07853 break; 07854 } 07855 } 07856 p->outgoing = 1; 07857 tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0); 07858 #ifdef HAVE_PRI 07859 if (p->bearer) { 07860 /* Log owner to bearer channel, too */ 07861 p->bearer->owner = tmp; 07862 } 07863 #endif 07864 /* Make special notes */ 07865 if (res > 1) { 07866 if (opt == 'c') { 07867 /* Confirm answer */ 07868 p->confirmanswer = 1; 07869 } else if (opt == 'r') { 07870 /* Distinctive ring */ 07871 if (res < 3) 07872 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data); 07873 else 07874 p->distinctivering = y; 07875 } else if (opt == 'd') { 07876 /* If this is an ISDN call, make it digital */ 07877 p->digital = 1; 07878 if (tmp) 07879 tmp->transfercapability = AST_TRANS_CAP_DIGITAL; 07880 } else { 07881 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data); 07882 } 07883 } 07884 /* Note if the call is a call waiting call */ 07885 if (tmp && callwait) 07886 tmp->cdrflags |= AST_CDR_CALLWAIT; 07887 break; 07888 } 07889 next: 07890 if (backwards) { 07891 p = p->prev; 07892 if (!p) 07893 p = end; 07894 } else { 07895 p = p->next; 07896 if (!p) 07897 p = start; 07898 } 07899 /* stop when you roll to the one that we started from */ 07900 if (p == exit) 07901 break; 07902 } 07903 ast_mutex_unlock(lock); 07904 restart_monitor(); 07905 if (callwait) 07906 *cause = AST_CAUSE_BUSY; 07907 else if (!tmp) { 07908 if (channelmatched) { 07909 if (busy) 07910 *cause = AST_CAUSE_BUSY; 07911 } else if (groupmatched) { 07912 *cause = AST_CAUSE_CONGESTION; 07913 } 07914 } 07915 07916 return tmp; 07917 }
| static int zt_ring_phone | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 3441 of file chan_zap.c.
References ast_log(), SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by __zt_exception(), and zt_handle_event().
03442 { 03443 int x; 03444 int res; 03445 /* Make sure our transmit state is on hook */ 03446 x = 0; 03447 x = ZT_ONHOOK; 03448 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03449 do { 03450 x = ZT_RING; 03451 res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x); 03452 if (res) { 03453 switch (errno) { 03454 case EBUSY: 03455 case EINTR: 03456 /* Wait just in case */ 03457 usleep(10000); 03458 continue; 03459 case EINPROGRESS: 03460 res = 0; 03461 break; 03462 default: 03463 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 03464 res = 0; 03465 } 03466 } 03467 } while (res); 03468 return res; 03469 }
| static int zt_sendtext | ( | struct ast_channel * | c, | |
| const char * | text | |||
| ) | [static] |
Definition at line 11300 of file chan_zap.c.
References ASCII_BYTES_PER_CHAR, ast_check_hangup(), AST_LAW, ast_log(), ast_malloc, zt_pvt::channel, END_SILENCE_LEN, pollfd::events, pollfd::fd, free, HEADER_LEN, HEADER_MS, LOG_ERROR, zt_pvt::mate, option_debug, poll(), POLLOUT, PUT_CLID, PUT_CLID_MARKMS, READ_SIZE, pollfd::revents, zt_pvt::subs, zt_pvt::tdd, TDD_BYTES_PER_CHAR, tdd_generate(), ast_channel::tech_pvt, TRAILER_MS, zt_subchannel::zfd, and zt_get_index().
11301 { 11302 #define END_SILENCE_LEN 400 11303 #define HEADER_MS 50 11304 #define TRAILER_MS 5 11305 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 11306 #define ASCII_BYTES_PER_CHAR 80 11307 11308 unsigned char *buf,*mybuf; 11309 struct zt_pvt *p = c->tech_pvt; 11310 struct pollfd fds[1]; 11311 int size,res,fd,len,x; 11312 int bytes=0; 11313 /* Initial carrier (imaginary) */ 11314 float cr = 1.0; 11315 float ci = 0.0; 11316 float scont = 0.0; 11317 int index; 11318 11319 index = zt_get_index(c, p, 0); 11320 if (index < 0) { 11321 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 11322 return -1; 11323 } 11324 if (!text[0]) return(0); /* if nothing to send, dont */ 11325 if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ 11326 if (p->mate) 11327 buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 11328 else 11329 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 11330 if (!buf) 11331 return -1; 11332 mybuf = buf; 11333 if (p->mate) { 11334 int codec = AST_LAW(p); 11335 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */ 11336 PUT_CLID_MARKMS; 11337 } 11338 /* Put actual message */ 11339 for (x = 0; text[x]; x++) { 11340 PUT_CLID(text[x]); 11341 } 11342 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */ 11343 PUT_CLID_MARKMS; 11344 } 11345 len = bytes; 11346 buf = mybuf; 11347 } else { 11348 len = tdd_generate(p->tdd, buf, text); 11349 if (len < 1) { 11350 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text)); 11351 free(mybuf); 11352 return -1; 11353 } 11354 } 11355 memset(buf + len, 0x7f, END_SILENCE_LEN); 11356 len += END_SILENCE_LEN; 11357 fd = p->subs[index].zfd; 11358 while (len) { 11359 if (ast_check_hangup(c)) { 11360 free(mybuf); 11361 return -1; 11362 } 11363 size = len; 11364 if (size > READ_SIZE) 11365 size = READ_SIZE; 11366 fds[0].fd = fd; 11367 fds[0].events = POLLOUT | POLLPRI; 11368 fds[0].revents = 0; 11369 res = poll(fds, 1, -1); 11370 if (!res) { 11371 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 11372 continue; 11373 } 11374 /* if got exception */ 11375 if (fds[0].revents & POLLPRI) 11376 return -1; 11377 if (!(fds[0].revents & POLLOUT)) { 11378 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 11379 continue; 11380 } 11381 res = write(fd, buf, size); 11382 if (res != size) { 11383 if (res == -1) { 11384 free(mybuf); 11385 return -1; 11386 } 11387 if (option_debug) 11388 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 11389 break; 11390 } 11391 len -= size; 11392 buf += size; 11393 } 11394 free(mybuf); 11395 return(0); 11396 }
| static int zt_set_hook | ( | int | fd, | |
| int | hs | |||
| ) | [inline, static] |
Definition at line 1607 of file chan_zap.c.
References ast_log(), and LOG_WARNING.
Referenced by __zt_exception(), handle_init_event(), ss_thread(), zt_answer(), zt_handle_event(), zt_hangup(), zt_indicate(), and zt_wink().
01608 { 01609 int x, res; 01610 x = hs; 01611 res = ioctl(fd, ZT_HOOK, &x); 01612 if (res < 0) 01613 { 01614 if (errno == EINPROGRESS) return 0; 01615 ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno)); 01616 } 01617 return res; 01618 }
| static int zt_setlinear | ( | int | zfd, | |
| int | linear | |||
| ) | [static] |
Definition at line 918 of file chan_zap.c.
Referenced by send_callerid(), ss_thread(), zt_hangup(), zt_new(), zt_read(), and zt_write().
00919 { 00920 int res; 00921 res = ioctl(zfd, ZT_SETLINEAR, &linear); 00922 if (res) 00923 return res; 00924 return 0; 00925 }
| static int zt_setoption | ( | struct ast_channel * | chan, | |
| int | option, | |||
| void * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 2813 of file chan_zap.c.
References ast_check_hangup(), ast_dsp_digitmode(), ast_log(), AST_OPTION_AUDIO_MODE, AST_OPTION_ECHOCAN, AST_OPTION_OPRMODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_tdd_gen_ecdisa(), zt_pvt::channel, zt_pvt::didtdd, zt_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_DIGITMODE_RELAXDTMF, zt_pvt::dtmfrelax, pollfd::events, pollfd::fd, zt_pvt::law, len, LOG_DEBUG, LOG_WARNING, zt_pvt::mate, oprmode::mode, zt_pvt::oprmode, zt_pvt::oprpeer, option_debug, oprmode::peer, poll(), POLLOUT, POLLPRI, READ_SIZE, pollfd::revents, zt_pvt::rxgain, set_actual_rxgain(), set_actual_txgain(), SUB_REAL, zt_pvt::subs, zt_pvt::tdd, tdd_free(), tdd_new(), ast_channel::tech_pvt, zt_pvt::txgain, zt_subchannel::zfd, zt_disable_ec(), zt_enable_ec(), and zt_get_index().
02814 { 02815 char *cp; 02816 signed char *scp; 02817 int x; 02818 int index; 02819 struct zt_pvt *p = chan->tech_pvt, *pp; 02820 struct oprmode *oprmode; 02821 02822 02823 /* all supported options require data */ 02824 if (!data || (datalen < 1)) { 02825 errno = EINVAL; 02826 return -1; 02827 } 02828 02829 switch (option) { 02830 case AST_OPTION_TXGAIN: 02831 scp = (signed char *) data; 02832 index = zt_get_index(chan, p, 0); 02833 if (index < 0) { 02834 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 02835 return -1; 02836 } 02837 ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp); 02838 return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law); 02839 case AST_OPTION_RXGAIN: 02840 scp = (signed char *) data; 02841 index = zt_get_index(chan, p, 0); 02842 if (index < 0) { 02843 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 02844 return -1; 02845 } 02846 ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp); 02847 return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law); 02848 case AST_OPTION_TONE_VERIFY: 02849 if (!p->dsp) 02850 break; 02851 cp = (char *) data; 02852 switch (*cp) { 02853 case 1: 02854 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name); 02855 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 02856 break; 02857 case 2: 02858 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name); 02859 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 02860 break; 02861 default: 02862 ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name); 02863 ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 02864 break; 02865 } 02866 break; 02867 case AST_OPTION_TDD: 02868 /* turn on or off TDD */ 02869 cp = (char *) data; 02870 p->mate = 0; 02871 if (!*cp) { /* turn it off */ 02872 if (option_debug) 02873 ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name); 02874 if (p->tdd) 02875 tdd_free(p->tdd); 02876 p->tdd = 0; 02877 break; 02878 } 02879 ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n", 02880 (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name); 02881 zt_disable_ec(p); 02882 /* otherwise, turn it on */ 02883 if (!p->didtdd) { /* if havent done it yet */ 02884 unsigned char mybuf[41000], *buf; 02885 int size, res, fd, len; 02886 struct pollfd fds[1]; 02887 02888 buf = mybuf; 02889 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 02890 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 02891 len = 40000; 02892 index = zt_get_index(chan, p, 0); 02893 if (index < 0) { 02894 ast_log(LOG_WARNING, "No index in TDD?\n"); 02895 return -1; 02896 } 02897 fd = p->subs[index].zfd; 02898 while (len) { 02899 if (ast_check_hangup(chan)) 02900 return -1; 02901 size = len; 02902 if (size > READ_SIZE) 02903 size = READ_SIZE; 02904 fds[0].fd = fd; 02905 fds[0].events = POLLPRI | POLLOUT; 02906 fds[0].revents = 0; 02907 res = poll(fds, 1, -1); 02908 if (!res) { 02909 ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel); 02910 continue; 02911 } 02912 /* if got exception */ 02913 if (fds[0].revents & POLLPRI) 02914 return -1; 02915 if (!(fds[0].revents & POLLOUT)) { 02916 ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel); 02917 continue; 02918 } 02919 res = write(fd, buf, size); 02920 if (res != size) { 02921 if (res == -1) return -1; 02922 ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 02923 break; 02924 } 02925 len -= size; 02926 buf += size; 02927 } 02928 p->didtdd = 1; /* set to have done it now */ 02929 } 02930 if (*cp == 2) { /* Mate mode */ 02931 if (p->tdd) 02932 tdd_free(p->tdd); 02933 p->tdd = 0; 02934 p->mate = 1; 02935 break; 02936 } 02937 if (!p->tdd) { /* if we dont have one yet */ 02938 p->tdd = tdd_new(); /* allocate one */ 02939 } 02940 break; 02941 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 02942 if (!p->dsp) 02943 break; 02944 cp = (char *) data; 02945 ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n", 02946 *cp ? "ON" : "OFF", (int) *cp, chan->name); 02947 ast_dsp_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax); 02948 break; 02949 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 02950 cp = (char *) data; 02951 if (!*cp) { 02952 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name); 02953 x = 0; 02954 zt_disable_ec(p); 02955 } else { 02956 ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name); 02957 x = 1; 02958 } 02959 if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1) 02960 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x); 02961 break; 02962 case AST_OPTION_OPRMODE: /* Operator services mode */ 02963 oprmode = (struct oprmode *) data; 02964 pp = oprmode->peer->tech_pvt; 02965 p->oprmode = pp->oprmode = 0; 02966 /* setup peers */ 02967 p->oprpeer = pp; 02968 pp->oprpeer = p; 02969 /* setup modes, if any */ 02970 if (oprmode->mode) 02971 { 02972 pp->oprmode = oprmode->mode; 02973 p->oprmode = -oprmode->mode; 02974 } 02975 ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n", 02976 oprmode->mode, chan->name,oprmode->peer->name);; 02977 break; 02978 case AST_OPTION_ECHOCAN: 02979 cp = (char *) data; 02980 if (*cp) { 02981 ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name); 02982 zt_enable_ec(p); 02983 } else { 02984 ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name); 02985 zt_disable_ec(p); 02986 } 02987 break; 02988 } 02989 errno = 0; 02990 02991 return 0; 02992 }
| static void zt_train_ec | ( | struct zt_pvt * | p | ) | [static] |
Definition at line 1439 of file chan_zap.c.
References ast_log(), zt_pvt::channel, zt_pvt::echocancel, zt_pvt::echotraining, LOG_DEBUG, LOG_WARNING, SUB_REAL, zt_pvt::subs, and zt_subchannel::zfd.
Referenced by zt_answer(), and zt_handle_event().
01440 { 01441 int x; 01442 int res; 01443 if (p && p->echocancel && p->echotraining) { 01444 x = p->echotraining; 01445 res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x); 01446 if (res) 01447 ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel); 01448 else { 01449 ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel); 01450 } 01451 } else 01452 ast_log(LOG_DEBUG, "No echo training requested\n"); 01453 }
Definition at line 3013 of file chan_zap.c.
References ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), conf_del(), zt_pvt::lock, LOG_DEBUG, master, and SUB_REAL.
Referenced by zt_bridge(), and zt_fixup().
03014 { 03015 /* Unlink a specific slave or all slaves/masters from a given master */ 03016 int x; 03017 int hasslaves; 03018 if (!master) 03019 return; 03020 if (needlock) { 03021 ast_mutex_lock(&master->lock); 03022 if (slave) { 03023 while (ast_mutex_trylock(&slave->lock)) { 03024 ast_mutex_unlock(&master->lock); 03025 usleep(1); 03026 ast_mutex_lock(&master->lock); 03027 } 03028 } 03029 } 03030 hasslaves = 0; 03031 for (x = 0; x < MAX_SLAVES; x++) { 03032 if (master->slaves[x]) { 03033 if (!slave || (master->slaves[x] == slave)) { 03034 /* Take slave out of the conference */ 03035 ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 03036 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 03037 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 03038 master->slaves[x]->master = NULL; 03039 master->slaves[x] = NULL; 03040 } else 03041 hasslaves = 1; 03042 } 03043 if (!hasslaves) 03044 master->inconference = 0; 03045 } 03046 if (!slave) { 03047 if (master->master) { 03048 /* Take master out of the conference */ 03049 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 03050 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 03051 hasslaves = 0; 03052 for (x = 0; x < MAX_SLAVES; x++) { 03053 if (master->master->slaves[x] == master) 03054 master->master->slaves[x] = NULL; 03055 else if (master->master->slaves[x]) 03056 hasslaves = 1; 03057 } 03058 if (!hasslaves) 03059 master->master->inconference = 0; 03060 } 03061 master->master = NULL; 03062 } 03063 update_conf(master); 03064 if (needlock) { 03065 if (slave) 03066 ast_mutex_unlock(&slave->lock); 03067 ast_mutex_unlock(&master->lock); 03068 } 03069 }
| static int zt_wait_event | ( | int | fd | ) | [inline, static] |
Avoid the silly zt_waitevent which ignores a bunch of events.
Definition at line 265 of file chan_zap.c.
Referenced by flash_exec(), and ss_thread().
00266 { 00267 int i, j = 0; 00268 i = ZT_IOMUX_SIGEVENT; 00269 if (ioctl(fd, ZT_IOMUX, &i) == -1) 00270 return -1; 00271 if (ioctl(fd, ZT_GETEVENT, &j) == -1) 00272 return -1; 00273 return j; 00274 }
| static int zt_wink | ( | struct zt_pvt * | p, | |
| int | index | |||
| ) | [static] |
Definition at line 5363 of file chan_zap.c.
References zt_pvt::subs, zt_subchannel::zfd, and zt_set_hook().
Referenced by ss_thread().
05364 { 05365 int j; 05366 zt_set_hook(p->subs[index].zfd, ZT_WINK); 05367 for (;;) 05368 { 05369 /* set bits of interest */ 05370 j = ZT_IOMUX_SIGEVENT; 05371 /* wait for some happening */ 05372 if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1); 05373 /* exit loop if we have it */ 05374 if (j & ZT_IOMUX_SIGEVENT) break; 05375 } 05376 /* get the event info */ 05377 if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1); 05378 return 0; 05379 }
| static int zt_write | ( | struct ast_channel * | ast, | |
| struct ast_frame * | frame | |||
| ) | [static] |
Definition at line 4897 of file chan_zap.c.
References AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), zt_pvt::channel, zt_pvt::cidspill, ast_frame::data, ast_frame::datalen, zt_pvt::dialing, zt_pvt::digital, ast_frame::frametype, zt_subchannel::linear, zt_pvt::lock, LOG_DEBUG, my_zt_write(), option_debug, zt_pvt::outgoing, zt_pvt::owner, zt_pvt::sig, SIG_PRI, zt_pvt::span, ast_frame::subclass, zt_pvt::subs, ast_channel::tech_pvt, zt_subchannel::zfd, zt_get_index(), and zt_setlinear().
04898 { 04899 struct zt_pvt *p = ast->tech_pvt; 04900 int res; 04901 unsigned char outbuf[4096]; 04902 int index; 04903 index = zt_get_index(ast, p, 0); 04904 if (index < 0) { 04905 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name); 04906 return -1; 04907 } 04908 04909 #if 0 04910 #ifdef HAVE_PRI 04911 ast_mutex_lock(&p->lock); 04912 if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) { 04913 if (p->pri->pri) { 04914 if (!pri_grab(p, p->pri)) { 04915 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital); 04916 pri_rel(p->pri); 04917 } else 04918 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span); 04919 } 04920 p->proceeding=1; 04921 } 04922 ast_mutex_unlock(&p->lock); 04923 #endif 04924 #endif 04925 /* Write a frame of (presumably voice) data */ 04926 if (frame->frametype != AST_FRAME_VOICE) { 04927 if (frame->frametype != AST_FRAME_IMAGE) 04928 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 04929 return 0; 04930 } 04931 if ((frame->subclass != AST_FORMAT_SLINEAR) && 04932 (frame->subclass != AST_FORMAT_ULAW) && 04933 (frame->subclass != AST_FORMAT_ALAW)) { 04934 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass); 04935 return -1; 04936 } 04937 if (p->dialing) { 04938 if (option_debug) 04939 ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name); 04940 return 0; 04941 } 04942 if (!p->owner) { 04943 if (option_debug) 04944 ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name); 04945 return 0; 04946 } 04947 if (p->cidspill) { 04948 if (option_debug) 04949 ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n"); 04950 return 0; 04951 } 04952 /* Return if it's not valid data */ 04953 if (!frame->data || !frame->datalen) 04954 return 0; 04955 if (frame->datalen > sizeof(outbuf) * 2) { 04956 ast_log(LOG_WARNING, "Frame too large\n"); 04957 return 0; 04958 } 04959 04960 if (frame->subclass == AST_FORMAT_SLINEAR) { 04961 if (!p->subs[index].linear) { 04962 p->subs[index].linear = 1; 04963 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04964 if (res) 04965 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 04966 } 04967 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1); 04968 } else { 04969 /* x-law already */ 04970 if (p->subs[index].linear) { 04971 p->subs[index].linear = 0; 04972 res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear); 04973 if (res) 04974 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 04975 } 04976 res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0); 04977 } 04978 if (res < 0) { 04979 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 04980 return -1; 04981 } 04982 return 0; 04983 }
| int alarm |
struct { ... } alarms[] [static] |
Referenced by alarm2str(), and zap_show_status().
struct zt_ring_cadence cadences[NUM_CADENCE_MAX] [static] |
Definition at line 739 of file chan_zap.c.
int cidrings[NUM_CADENCE_MAX] [static] |
cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on.
Definition at line 750 of file chan_zap.c.
const char config[] = "zapata.conf" [static] |
Definition at line 164 of file chan_zap.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 108 of file chan_zap.c.
char defaultcic[64] = "" [static] |
Definition at line 203 of file chan_zap.c.
char defaultozz[64] = "" [static] |
Definition at line 204 of file chan_zap.c.
char destroy_channel_usage[] [static] |
Initial value:
"Usage: zap destroy channel <chan num>\n" " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n"
Definition at line 10061 of file chan_zap.c.
int distinctiveringaftercid = 0 [static] |
Definition at line 209 of file chan_zap.c.
struct zt_distRings drings [static] |
char* events[] [static] |
int firstdigittimeout = 16000 [static] |
int gendigittimeout = 8000 [static] |
struct ast_jb_conf global_jbconf [static] |
Definition at line 115 of file chan_zap.c.
int ifcount = 0 [static] |
Definition at line 235 of file chan_zap.c.
int matchdigittimeout = 3000 [static] |
How long to wait for an extra digit, if there is an ambiguous match.
Definition at line 229 of file chan_zap.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 247 of file chan_zap.c.
| char* name |
Definition at line 1119 of file chan_zap.c.
int num_cadence = 4 [static] |
Definition at line 736 of file chan_zap.c.
int numbufs = 4 [static] |
Definition at line 211 of file chan_zap.c.
char progzone[10] = "" [static] |
Definition at line 206 of file chan_zap.c.
int ringt_base = DEFAULT_RINGT [static] |
Definition at line 290 of file chan_zap.c.
| struct zt_pvt* round_robin[32] |
char show_channel_usage[] [static] |
Initial value:
"Usage: zap show channel <chan num>\n" " Detailed information about a given channel\n"
Definition at line 10053 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 10049 of file chan_zap.c.
char* subnames[] [static] |
const char tdesc[] = "Zapata Telephony Driver" [static] |
Definition at line 158 of file chan_zap.c.
int usedistinctiveringdetection = 0 [static] |
Definition at line 208 of file chan_zap.c.
int user_has_defined_cadences = 0 [static] |
Definition at line 737 of file chan_zap.c.
struct ast_cli_entry zap_cli[] [static] |
char zap_restart_usage[] [static] |
Definition at line 10065 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 9957 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 10057 of file chan_zap.c.
struct ast_channel_tech zap_tech [static] |
Definition at line 686 of file chan_zap.c.
Referenced by __unload_module(), load_module(), ss_thread(), and zt_new().
1.5.1