#include "asterisk.h"
#include <sys/signal.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <math.h>
#include <ctype.h>
#include <dahdi/user.h>
#include <dahdi/tonezone.h>
#include "sig_analog.h"
#include "sig_pri.h"
#include "sig_ss7.h"
#include <openr2.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.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/cel.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/tdd.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
#include "asterisk/causes.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/transcap.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj.h"
#include "asterisk/event.h"
#include "asterisk/devicestate.h"
#include "asterisk/paths.h"
#include "asterisk/ccss.h"
#include "asterisk/data.h"
Go to the source code of this file.
Data Structures | |
struct | dahdi_chan_conf |
Channel configuration from chan_dahdi.conf . This struct is used for parsing the [channels] section of chan_dahdi.conf. Generally there is a field here for every possible configuration item. More... | |
struct | dahdi_distRings |
struct | dahdi_mfcr2 |
struct | dahdi_mfcr2_conf |
struct | dahdi_parms_pseudo |
struct | dahdi_pri |
struct | dahdi_pvt |
struct | dahdi_ss7 |
struct | dahdi_starting_point |
struct | dahdi_subchannel |
struct | distRingData |
struct | mwi_thread_data |
struct | mwisend_info |
struct | ringContextData |
Defines | |
#define | ASCII_BYTES_PER_CHAR 80 |
#define | AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
#define | CALLPROGRESS_FAX (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING) |
#define | CALLPROGRESS_FAX_INCOMING 4 |
#define | CALLPROGRESS_FAX_OUTGOING 2 |
#define | CALLPROGRESS_PROGRESS 1 |
#define | CALLWAITING_REPEAT_SAMPLES ((10000 * 8) / READ_SIZE) |
#define | CALLWAITING_SILENT_SAMPLES ((300 * 8) / READ_SIZE) |
#define | CALLWAITING_SUPPRESS_SAMPLES ((100 * 8) / READ_SIZE) |
#define | CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */) |
#define | CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */) |
#define | CHAN_PSEUDO -2 |
#define | CHAN_TAG "Chan " |
#define | CIDCW_EXPIRE_SAMPLES ((500 * 8) / READ_SIZE) |
#define | CONF_USER_REAL (1 << 0) |
#define | CONF_USER_THIRDCALL (1 << 1) |
#define | CONTEXT_TAG "Context - " |
#define | dahdi_get_index(ast, p, nullok) _dahdi_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__) |
#define | DATA_EXPORT_DAHDI_PVT(MEMBER) |
#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 %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n" |
#define | FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" |
#define | FORMAT "%4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n" |
#define | FORMAT "%4s %40s\n" |
#define | FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n" |
#define | FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\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_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_SPANS 32 |
#define | POLARITY_IDLE 0 |
#define | POLARITY_REV 1 |
#define | PROC_DAHDI_OPT_NOCHAN (1 << 0) |
#define | PROC_DAHDI_OPT_NOWARN (1 << 1) |
#define | R2_LINK_CAPACITY 10 |
#define | READ_SIZE 160 |
#define | REPORT_CHANNEL_ALARMS 1 |
#define | REPORT_SPAN_ALARMS 2 |
#define | sig2str dahdi_sig2str |
#define | SIG_BRI (0x2000000 | DAHDI_SIG_CLEAR) |
#define | SIG_BRI_PTMP (0X4000000 | DAHDI_SIG_CLEAR) |
#define | SIG_E911 (0x1000000 | DAHDI_SIG_EM) |
#define | SIG_EM DAHDI_SIG_EM |
#define | SIG_EM_E1 DAHDI_SIG_EM_E1 |
#define | SIG_EMWINK (0x0100000 | DAHDI_SIG_EM) |
#define | SIG_FEATB (0x0800000 | DAHDI_SIG_EM) |
#define | SIG_FEATD (0x0200000 | DAHDI_SIG_EM) |
#define | SIG_FEATDMF (0x0400000 | DAHDI_SIG_EM) |
#define | SIG_FEATDMF_TA (0x2000000 | DAHDI_SIG_EM) |
#define | SIG_FGC_CAMA (0x4000000 | DAHDI_SIG_EM) |
#define | SIG_FGC_CAMAMF (0x8000000 | DAHDI_SIG_EM) |
#define | SIG_FXOGS DAHDI_SIG_FXOGS |
#define | SIG_FXOKS DAHDI_SIG_FXOKS |
#define | SIG_FXOLS DAHDI_SIG_FXOLS |
#define | SIG_FXSGS DAHDI_SIG_FXSGS |
#define | SIG_FXSKS DAHDI_SIG_FXSKS |
#define | SIG_FXSLS DAHDI_SIG_FXSLS |
#define | SIG_MFCR2 DAHDI_SIG_CAS |
#define | SIG_MFCR2_MAX_CHANNELS 672 |
#define | SIG_PRI DAHDI_SIG_CLEAR |
#define | SIG_PRI_LIB_HANDLE_CASES |
#define | SIG_SF DAHDI_SIG_SF |
#define | SIG_SF_FEATB (0x0800000 | DAHDI_SIG_SF) |
#define | SIG_SF_FEATD (0x0200000 | DAHDI_SIG_SF) |
#define | SIG_SF_FEATDMF (0x0400000 | DAHDI_SIG_SF) |
#define | SIG_SFWINK (0x0100000 | DAHDI_SIG_SF) |
#define | SIG_SS7 (0x1000000 | DAHDI_SIG_CLEAR) |
#define | SMDI_MD_WAIT_TIMEOUT 1500 |
#define | SUB_CALLWAIT 1 |
#define | SUB_REAL 0 |
#define | SUB_THREEWAY 2 |
#define | TRAILER_MS 5 |
#define | TRANSFER 0 |
Enumerations | |
enum | DAHDI_IFLIST { DAHDI_IFLIST_NONE, DAHDI_IFLIST_MAIN, DAHDI_IFLIST_NO_B_CHAN } |
enum | mwisend_states { MWI_SEND_NULL = 0, MWI_SEND_SA, MWI_SEND_SA_WAIT, MWI_SEND_PAUSE, MWI_SEND_SPILL, MWI_SEND_CLEANUP, MWI_SEND_DONE } |
Functions | |
static struct ast_frame * | __dahdi_exception (struct ast_channel *ast) |
static void | __reg_module (void) |
static int | __unload_module (void) |
static void | __unreg_module (void) |
static int | _dahdi_get_index (struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line) |
static int | action_dahdidialoffhook (struct mansession *s, const struct message *m) |
static int | action_dahdidndoff (struct mansession *s, const struct message *m) |
static int | action_dahdidndon (struct mansession *s, const struct message *m) |
static int | action_dahdirestart (struct mansession *s, const struct message *m) |
static int | action_dahdishowchannels (struct mansession *s, const struct message *m) |
static int | action_transfer (struct mansession *s, const struct message *m) |
static int | action_transferhangup (struct mansession *s, const struct message *m) |
static char * | alarm2str (int alm) |
static int | alloc_sub (struct dahdi_pvt *p, int x) |
static int | analog_lib_handles (int signalling, int radio, int oprmode) |
static void * | analog_ss_thread (void *data) |
static int | analog_tone_to_dahditone (enum analog_tone tone) |
static int | analogsub_to_dahdisub (enum analog_sub analogsub) |
AST_DATA_STRUCTURE (dahdi_pvt, DATA_EXPORT_DAHDI_PVT) | |
static int | attempt_transfer (struct dahdi_pvt *p) |
static int | available (struct dahdi_pvt **pvt, int is_specific_channel) |
static int | build_channels (struct dahdi_chan_conf *conf, const char *value, int reload, int lineno, int *found_pseudo) |
static int | bump_gains (struct dahdi_pvt *p) |
static int | calc_energy (const unsigned char *buf, int len, format_t law) |
static int | check_for_conference (struct dahdi_pvt *p) |
static char * | complete_span_4 (const char *line, const char *word, int pos, int state) |
static char * | complete_span_helper (const char *line, const char *word, int pos, int state, int rpos) |
static int | conf_add (struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel) |
static int | conf_del (struct dahdi_pvt *p, struct dahdi_subchannel *c, int index) |
static struct ast_str * | create_channel_name (struct dahdi_pvt *i, int is_outgoing, char *address) |
static int | dahdi_accept_r2_call_exec (struct ast_channel *chan, const char *data) |
static int | dahdi_answer (struct ast_channel *ast) |
static openr2_call_disconnect_cause_t | dahdi_ast_cause_to_r2_cause (int cause) |
static enum ast_bridge_result | dahdi_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | dahdi_call (struct ast_channel *ast, char *rdest, int timeout) |
static int | dahdi_callwait (struct ast_channel *ast) |
static int | dahdi_cc_callback (struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback) |
Callback made when dial failed to get a channel out of dahdi_request(). | |
static struct dahdi_chan_conf | dahdi_chan_conf_default (void) |
static int | dahdi_channels_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static void | dahdi_close (int fd) |
static void | dahdi_close_pri_fd (struct dahdi_pri *pri, int fd_num) |
static void | dahdi_close_ss7_fd (struct dahdi_ss7 *ss7, int fd_num) |
static void | dahdi_close_sub (struct dahdi_pvt *chan_pvt, int sub_num) |
static int | dahdi_confmute (struct dahdi_pvt *p, int muted) |
static char * | dahdi_destroy_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static int | dahdi_destroy_channel_bynum (int channel) |
static int | dahdi_devicestate (void *data) |
static int | dahdi_digit_begin (struct ast_channel *ast, char digit) |
static int | dahdi_digit_end (struct ast_channel *ast, char digit, unsigned int duration) |
static void | dahdi_disable_ec (struct dahdi_pvt *p) |
static int | dahdi_dnd (struct dahdi_pvt *dahdichan, int flag) |
enable or disable the chan_dahdi Do-Not-Disturb mode for a DAHDI channel | |
static void | dahdi_enable_ec (struct dahdi_pvt *p) |
static struct ast_frame * | dahdi_exception (struct ast_channel *ast) |
static int | dahdi_fake_event (struct dahdi_pvt *p, int mode) |
static int | dahdi_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static int | dahdi_func_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len) |
static int | dahdi_func_write (struct ast_channel *chan, const char *function, char *data, const char *value) |
static int | dahdi_get_event (int fd) |
Avoid the silly dahdi_getevent which ignores a bunch of events. | |
static void | dahdi_handle_dtmf (struct ast_channel *ast, int idx, struct ast_frame **dest) |
static struct ast_frame * | dahdi_handle_event (struct ast_channel *ast) |
static int | dahdi_hangup (struct ast_channel *ast) |
static void | dahdi_iflist_extract (struct dahdi_pvt *pvt) |
static void | dahdi_iflist_insert (struct dahdi_pvt *pvt) |
static int | dahdi_indicate (struct ast_channel *chan, int condition, const void *data, size_t datalen) |
static void | dahdi_link (struct dahdi_pvt *slave, struct dahdi_pvt *master) |
static void | dahdi_lock_sub_owner (struct dahdi_pvt *pvt, int sub_idx) |
static struct ast_channel * | dahdi_new (struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid) |
static int | dahdi_new_pri_nobch_channel (struct sig_pri_span *pri) |
static void | dahdi_nobch_extract (struct sig_pri_span *pri, struct dahdi_pvt *pvt) |
static void | dahdi_nobch_insert (struct sig_pri_span *pri, struct dahdi_pvt *pvt) |
static int | dahdi_open (char *fn) |
static void | dahdi_pri_error (struct pri *pri, char *s) |
static void | dahdi_pri_message (struct pri *pri, char *s) |
static void | dahdi_pri_update_span_devstate (struct sig_pri_span *pri) |
static int | dahdi_queryoption (struct ast_channel *chan, int option, void *data, int *datalen) |
static void | dahdi_queue_frame (struct dahdi_pvt *p, struct ast_frame *f) |
static int16_t | dahdi_r2_alaw_to_linear (uint8_t sample) |
static int | dahdi_r2_answer (struct dahdi_pvt *p) |
static int | dahdi_r2_cause_to_ast_cause (openr2_call_disconnect_cause_t cause) |
static void | dahdi_r2_destroy_links (void) |
static void | dahdi_r2_disconnect_call (struct dahdi_pvt *p, openr2_call_disconnect_cause_t cause) |
static openr2_calling_party_category_t | dahdi_r2_get_channel_category (struct ast_channel *c) |
static struct dahdi_mfcr2 * | dahdi_r2_get_link (void) |
static uint8_t | dahdi_r2_linear_to_alaw (int sample) |
static void | dahdi_r2_on_ani_digit_received (openr2_chan_t *r2chan, char digit) |
static void | dahdi_r2_on_billing_pulse_received (openr2_chan_t *r2chan) |
static void | dahdi_r2_on_call_accepted (openr2_chan_t *r2chan, openr2_call_mode_t mode) |
static void | dahdi_r2_on_call_answered (openr2_chan_t *r2chan) |
static void | dahdi_r2_on_call_disconnect (openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause) |
static void | dahdi_r2_on_call_end (openr2_chan_t *r2chan) |
static void | dahdi_r2_on_call_init (openr2_chan_t *r2chan) |
static void | dahdi_r2_on_call_offered (openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category) |
static void | dahdi_r2_on_call_read (openr2_chan_t *r2chan, const unsigned char *buf, int buflen) |
static void | dahdi_r2_on_chan_log (openr2_chan_t *r2chan, openr2_log_level_t level, const char *fmt, va_list ap) |
static void | dahdi_r2_on_context_log (openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap) |
static int | dahdi_r2_on_dnis_digit_received (openr2_chan_t *r2chan, char digit) |
static void | dahdi_r2_on_hardware_alarm (openr2_chan_t *r2chan, int alarm) |
static void | dahdi_r2_on_line_blocked (openr2_chan_t *r2chan) |
static void | dahdi_r2_on_line_idle (openr2_chan_t *r2chan) |
static void | dahdi_r2_on_os_error (openr2_chan_t *r2chan, int errorcode) |
static void | dahdi_r2_on_protocol_error (openr2_chan_t *r2chan, openr2_protocol_error_t reason) |
static int | dahdi_r2_set_context (struct dahdi_mfcr2 *r2_link, const struct dahdi_chan_conf *conf) |
static void | dahdi_r2_write_log (openr2_log_level_t level, char *logmessage) |
static struct ast_frame * | dahdi_read (struct ast_channel *ast) |
static struct ast_channel * | dahdi_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) |
static int | dahdi_restart (void) |
static char * | dahdi_restart_cmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static int | dahdi_ring_phone (struct dahdi_pvt *p) |
static int | dahdi_send_callrerouting_facility_exec (struct ast_channel *chan, const char *data) |
static int | dahdi_send_keypad_facility_exec (struct ast_channel *chan, const char *digits) |
static int | dahdi_sendtext (struct ast_channel *c, const char *text) |
static char * | dahdi_set_dnd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static int | dahdi_set_hook (int fd, int hs) |
static char * | dahdi_set_hwgain (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | dahdi_set_swgain (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static int | dahdi_setlaw (int dfd, int law) |
static int | dahdi_setlinear (int dfd, int linear) |
static int | dahdi_setoption (struct ast_channel *chan, int option, void *data, int datalen) |
static char * | dahdi_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | dahdi_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | dahdi_show_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | dahdi_show_version (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | dahdi_sig2str (int sig) |
static int | dahdi_sig_pri_lib_handles (int signaling) |
static void | dahdi_softhangup_all (void) |
static void | dahdi_ss7_error (struct ss7 *ss7, char *s) |
static void | dahdi_ss7_message (struct ss7 *ss7, char *s) |
static int | dahdi_status_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static void | dahdi_train_ec (struct dahdi_pvt *p) |
static void | dahdi_unlink (struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock) |
static void | dahdi_unlink_pri_pvt (struct dahdi_pvt *pvt) |
static void | dahdi_unlink_ss7_pvt (struct dahdi_pvt *pvt) |
static int | dahdi_version_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static int | dahdi_wait_event (int fd) |
Avoid the silly dahdi_waitevent which ignores a bunch of events. | |
static int | dahdi_wink (struct dahdi_pvt *p, int index) |
static int | dahdi_write (struct ast_channel *ast, struct ast_frame *frame) |
static enum analog_event | dahdievent_to_analogevent (int event) |
static enum analog_sigtype | dahdisig_to_analogsig (int sig) |
static void | deep_copy_dahdi_chan_conf (struct dahdi_chan_conf *dest, const struct dahdi_chan_conf *src) |
static void | destroy_all_channels (void) |
static void | destroy_channel (struct dahdi_pvt *cur, int now) |
static void | destroy_dahdi_pvt (struct dahdi_pvt *pvt) |
static struct dahdi_pvt * | determine_starting_point (const char *data, struct dahdi_starting_point *param) |
static int | device2chan (const char *subdir, int channel, char *path, int pathlen) |
static int | digit_to_dtmfindex (char digit) |
static void | disable_dtmf_detect (struct dahdi_pvt *p) |
static void * | do_monitor (void *data) |
static int | drc_sample (int sample, float drc) |
static struct dahdi_pvt * | duplicate_pseudo (struct dahdi_pvt *src) |
static void | enable_dtmf_detect (struct dahdi_pvt *p) |
static const char * | event2str (int event) |
static void | fill_rxgain (struct dahdi_gains *g, float gain, float drc, int law) |
static void | fill_txgain (struct dahdi_gains *g, float gain, float drc, int law) |
static struct dahdi_pvt * | find_channel (int channel) |
static struct dahdi_pvt * | find_next_iface_in_span (struct dahdi_pvt *cur) |
static int | get_alarms (struct dahdi_pvt *p) |
static void | handle_alarms (struct dahdi_pvt *p, int alms) |
static void | handle_clear_alarms (struct dahdi_pvt *p) |
static char * | handle_dahdi_show_cadences (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static struct dahdi_pvt * | handle_init_event (struct dahdi_pvt *i, int event) |
static char * | handle_mfcr2_call_files (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_mfcr2_set_blocked (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_mfcr2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_mfcr2_set_idle (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_mfcr2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_mfcr2_show_variants (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_mfcr2_version (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_pri_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_pri_service_disable_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_pri_service_enable_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_pri_service_generic (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a, int changestatus) |
static char * | handle_pri_set_debug_file (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_pri_show_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_pri_show_span (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_pri_show_spans (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_pri_version (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_ss7_block_cic (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_ss7_block_linkset (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_ss7_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_ss7_show_linkset (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_ss7_unblock_cic (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_ss7_unblock_linkset (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_ss7_version (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static int | has_voicemail (struct dahdi_pvt *p) |
static int | is_group_or_channel_match (struct dahdi_pvt *p, int span, ast_group_t groupmatch, int *groupmatched, int channelmatch, int *channelmatched) |
static int | isourconf (struct dahdi_pvt *p, struct dahdi_subchannel *c) |
static int | isslavenative (struct dahdi_pvt *p, struct dahdi_pvt **out) |
static int | linkset_addsigchan (int sigchan) |
static int | load_module (void) |
static void * | mfcr2_monitor (void *data) |
static struct dahdi_pvt * | mkintf (int channel, const struct dahdi_chan_conf *conf, int reloading) |
static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
static int | mwi_send_init (struct dahdi_pvt *pvt) |
static int | mwi_send_process_buffer (struct dahdi_pvt *pvt, int num_read) |
static int | mwi_send_process_event (struct dahdi_pvt *pvt, int event) |
static void * | mwi_thread (void *data) |
static void | my_all_subchannels_hungup (void *pvt) |
static int | my_allocate_sub (void *pvt, enum analog_sub analogsub) |
static void | my_answer_polarityswitch (void *pvt) |
static int | my_callwait (void *pvt) |
static void | my_cancel_cidspill (void *pvt) |
static int | my_check_confirmanswer (void *pvt) |
static int | my_check_for_conference (void *pvt) |
static int | my_check_waitingfordt (void *pvt) |
static int | my_complete_conference_update (void *pvt, int needconference) |
static int | my_conf_add (void *pvt, enum analog_sub sub) |
static int | my_conf_del (void *pvt, enum analog_sub sub) |
static int | my_confmute (void *pvt, int mute) |
static int | my_dahdi_write (struct dahdi_pvt *p, unsigned char *buf, int len, int idx, int linear) |
static void | my_deadlock_avoidance_private (void *pvt) |
static void | my_decrease_ss_count (void) |
static int | my_dial_digits (void *pvt, enum analog_sub sub, struct analog_dialoperation *dop) |
static int | my_distinctive_ring (struct ast_channel *chan, void *pvt, int idx, int *ringdata) |
static int | my_dsp_reset_and_flush_digits (void *pvt) |
static int | my_dsp_set_digitmode (void *pvt, enum analog_dsp_digitmode mode) |
static int | my_flash (void *pvt) |
static void | my_get_and_handle_alarms (void *pvt) |
static int | my_get_callerid (void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout) |
static int | my_get_event (void *pvt) |
static const char * | my_get_orig_dialstring (void *pvt) |
static void * | my_get_sigpvt_bridged_channel (struct ast_channel *chan) |
static int | my_get_sub_fd (void *pvt, enum analog_sub sub) |
static int | my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms) |
static void | my_handle_dchan_exception (struct sig_pri_span *pri, int index) |
static void | my_handle_dtmf (void *pvt, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest) |
static void | my_handle_link_exception (struct sig_ss7_linkset *linkset, int which) |
static void | my_handle_notify_message (struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent) |
static void | my_hangup_polarityswitch (void *pvt) |
static int | my_has_voicemail (void *pvt) |
static void | my_increase_ss_count (void) |
static int | my_is_dialing (void *pvt, enum analog_sub sub) |
static int | my_is_off_hook (void *pvt) |
static void | my_lock_private (void *pvt) |
static void | my_module_ref (void) |
static void | my_module_unref (void) |
static struct ast_channel * | my_new_analog_ast_channel (void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor) |
static struct ast_channel * | my_new_pri_ast_channel (void *pvt, int state, enum sig_pri_law law, char *exten, const struct ast_channel *requestor) |
static struct ast_channel * | my_new_ss7_ast_channel (void *pvt, int state, enum sig_ss7_law law, char *exten, const struct ast_channel *requestor) |
static int | my_off_hook (void *pvt) |
static int | my_on_hook (void *pvt) |
static int | my_play_tone (void *pvt, enum analog_sub sub, enum analog_tone tone) |
static void | my_pri_fixup_chans (void *chan_old, void *chan_new) |
static void | my_pri_make_cc_dialstring (void *priv, char *buf, size_t buf_size) |
static void | my_pri_open_media (void *p) |
static int | my_pri_play_tone (void *pvt, enum sig_pri_tone tone) |
static int | my_ring (void *pvt) |
static int | my_send_callerid (void *pvt, int cwcid, struct ast_party_caller *caller) |
static void | my_set_alarm (void *pvt, int in_alarm) |
static void | my_set_cadence (void *pvt, int *cidrings, struct ast_channel *ast) |
static void | my_set_callerid (void *pvt, const struct ast_party_caller *caller) |
static void | my_set_callwaiting (void *pvt, int callwaiting_enable) |
static void | my_set_confirmanswer (void *pvt, int flag) |
static void | my_set_dialing (void *pvt, int is_dialing) |
static void | my_set_digital (void *pvt, int is_digital) |
static void | my_set_dnid (void *pvt, const char *dnid) |
static int | my_set_echocanceller (void *pvt, int enable) |
static void | my_set_inservice (void *pvt, int is_inservice) |
static void | my_set_inthreeway (void *pvt, enum analog_sub sub, int inthreeway) |
static int | my_set_linear_mode (void *pvt, enum analog_sub sub, int linear_mode) |
static void | my_set_locallyblocked (void *pvt, int is_blocked) |
static void | my_set_needringing (void *pvt, int value) |
static void | my_set_new_owner (void *pvt, struct ast_channel *new_owner) |
static void | my_set_polarity (void *pvt, int value) |
static void | my_set_pulsedial (void *pvt, int flag) |
static void | my_set_rdnis (void *pvt, const char *rdnis) |
static void | my_set_remotelyblocked (void *pvt, int is_blocked) |
static void | my_set_ringtimeout (void *pvt, int ringt) |
static void | my_set_waitingfordt (void *pvt, struct ast_channel *ast) |
static int | my_ss7_play_tone (void *pvt, enum sig_ss7_tone tone) |
static void | my_ss7_set_loopback (void *pvt, int enable) |
static int | my_start (void *pvt) |
static int | my_start_cid_detect (void *pvt, int cid_signalling) |
static void | my_start_polarityswitch (void *pvt) |
static int | my_stop_callwait (void *pvt) |
static int | my_stop_cid_detect (void *pvt) |
static void | my_swap_subchannels (void *pvt, enum analog_sub a, struct ast_channel *ast_a, enum analog_sub b, struct ast_channel *ast_b) |
static int | my_train_echocanceller (void *pvt) |
static int | my_unallocate_sub (void *pvt, enum analog_sub analogsub) |
static void | my_unlock_private (void *pvt) |
static int | my_wait_event (void *pvt) |
static int | my_wink (void *pvt, enum analog_sub sub) |
static void | notify_message (char *mailbox_full, int thereornot) |
Send MWI state change. | |
static int | parse_buffers_policy (const char *parse, int *num_buffers, int *policy) |
static unsigned int | parse_pointcode (const char *pcstring) |
static char * | parse_spanchan (char *chanstr, char **subdir) |
static int | prepare_pri (struct dahdi_pri *pri) |
static int | pri_create_spanmap (int span, int trunkgroup, int logicalspan) |
static int | pri_create_trunkgroup (int trunkgroup, int *channels) |
static int | pri_resolve_span (int *span, int channel, int offset, struct dahdi_spaninfo *si) |
static int | process_dahdi (struct dahdi_chan_conf *confp, const char *cat, struct ast_variable *v, int reload, int options) |
static void | process_echocancel (struct dahdi_chan_conf *confp, const char *data, unsigned int line) |
static int | reload (void) |
static int | reset_conf (struct dahdi_pvt *p) |
static int | restart_monitor (void) |
static int | restore_conference (struct dahdi_pvt *p) |
static int | restore_gains (struct dahdi_pvt *p) |
static int | revert_fax_buffers (struct dahdi_pvt *p, struct ast_channel *ast) |
static int | save_conference (struct dahdi_pvt *p) |
static int | send_callerid (struct dahdi_pvt *p) |
static int | send_cwcidspill (struct dahdi_pvt *p) |
static int | set_actual_gain (int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law) |
static int | set_actual_rxgain (int fd, float gain, float drc, int law) |
static int | set_actual_txgain (int fd, float gain, float drc, int law) |
static int | setup_dahdi (int reload) |
static int | setup_dahdi_int (int reload, struct dahdi_chan_conf *base_conf, struct dahdi_chan_conf *conf) |
static int | sig_pri_tone_to_dahditone (enum sig_pri_tone tone) |
static int | sig_ss7_tone_to_dahditone (enum sig_ss7_tone tone) |
static int | sigtype_to_signalling (int sigtype) |
static struct dahdi_ss7 * | ss7_resolve_linkset (int linkset) |
static void | string_replace (char *str, int char1, int char2) |
static void | swap_subs (struct dahdi_pvt *p, int a, int b) |
static int | unalloc_sub (struct dahdi_pvt *p, int x) |
static int | unload_module (void) |
static int | update_conf (struct dahdi_pvt *p) |
static void | wakeup_sub (struct dahdi_pvt *p, int a) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = tdesc , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_smdi", } |
struct { | |
int alarm | |
char * name | |
} | alarms [] |
static struct dahdi_ring_cadence | AS_RP_cadence = {{250, 10000}} |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct dahdi_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 [] = "chan_dahdi.conf" |
static int | cur_adjpointcode = -1 |
static int | cur_cicbeginswith = -1 |
static int | cur_defaultdpc = -1 |
static int | cur_linkset = -1 |
static int | cur_networkindicator = -1 |
static int | cur_pointcode = -1 |
static int | cur_ss7type = -1 |
static const char *const | dahdi_accept_r2_call_app = "DAHDIAcceptR2Call" |
static struct analog_callback | dahdi_analog_callbacks |
static struct ast_data_handler | dahdi_channels_data_provider |
static struct ast_cli_entry | dahdi_cli [] |
static struct ast_data_entry | dahdi_data_providers [] |
static struct ast_cli_entry | dahdi_mfcr2_cli [] |
static struct sig_pri_callback | dahdi_pri_callbacks |
static struct ast_cli_entry | dahdi_pri_cli [] |
static struct dahdi_parms_pseudo | dahdi_pseudo_parms |
static openr2_event_interface_t | dahdi_r2_event_iface |
static openr2_transcoder_interface_t | dahdi_r2_transcode_iface |
static char * | dahdi_send_callrerouting_facility_app = "DAHDISendCallreroutingFacility" |
static char * | dahdi_send_keypad_facility_app = "DAHDISendKeypadFacility" |
static struct sig_ss7_callback | dahdi_ss7_callbacks |
static struct ast_cli_entry | dahdi_ss7_cli [] |
static struct ast_data_handler | dahdi_status_data_provider |
static struct ast_channel_tech | dahdi_tech |
static struct ast_data_handler | dahdi_version_data_provider |
static struct ast_jb_conf | default_jbconf |
static char | defaultcic [64] = "" |
static char | defaultozz [64] = "" |
static int | distinctiveringaftercid = 0 |
static int | dtmfcid_level = 256 |
static const char *const | 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 dahdi_pvt * | ifend = NULL |
static struct dahdi_pvt * | iflist = NULL |
static ast_mutex_t | iflock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } |
Protect the interface list (of dahdi_pvt's). | |
static const char *const | lbostr [] |
static struct dahdi_ss7 | linksets [NUM_SPANS] |
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 ast_mutex_t | monlock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
static int | mwilevel = 512 |
static char | mwimonitornotify [PATH_MAX] = "" |
static int | num_cadence = 4 |
static int | num_restart_pending = 0 |
static int | numbufs = 4 |
static char | parkinglot [AST_MAX_EXTENSION] = "" |
static int | pridebugfd = -1 |
static ast_mutex_t | pridebugfdlock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } |
static char | pridebugfilename [1024] = "" |
static struct dahdi_pri | pris [NUM_SPANS] |
static char | progzone [10] = "" |
static struct dahdi_mfcr2 ** | r2links |
static int | r2links_count = 0 |
static int | report_alarms = REPORT_CHANNEL_ALARMS |
static ast_mutex_t | restart_lock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } |
static int | ringt_base = DEFAULT_RINGT |
Configured ring timeout base. | |
static struct dahdi_pvt * | round_robin [32] |
static ast_cond_t | ss_thread_complete |
static int | ss_thread_count = 0 |
static ast_mutex_t | ss_thread_lock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } |
static const char *const | subnames [] |
static const char | tdesc [] |
static int | usedistinctiveringdetection = 0 |
static int | user_has_defined_cadences = 0 |
You need to install libraries before you attempt to compile and install the DAHDI channel.
Definition in file chan_dahdi.c.
#define ASCII_BYTES_PER_CHAR 80 |
Referenced by dahdi_sendtext().
#define AST_LAW | ( | p | ) | (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW) |
Definition at line 292 of file chan_dahdi.c.
Referenced by analog_ss_thread(), dahdi_callwait(), dahdi_sendtext(), mwi_send_init(), mwi_thread(), my_callwait(), my_get_callerid(), my_send_callerid(), and send_cwcidspill().
#define CALLPROGRESS_FAX (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING) |
Definition at line 359 of file chan_dahdi.c.
Referenced by dahdi_handle_dtmf(), and my_handle_dtmf().
#define CALLPROGRESS_FAX_INCOMING 4 |
#define CALLPROGRESS_FAX_OUTGOING 2 |
#define CALLPROGRESS_PROGRESS 1 |
#define CALLWAITING_REPEAT_SAMPLES ((10000 * 8) / READ_SIZE) |
10,000 ms
Definition at line 496 of file chan_dahdi.c.
Referenced by dahdi_callwait(), and my_callwait().
#define CALLWAITING_SILENT_SAMPLES ((300 * 8) / READ_SIZE) |
300 ms
Definition at line 495 of file chan_dahdi.c.
#define CALLWAITING_SUPPRESS_SAMPLES ((100 * 8) / READ_SIZE) |
#define CANBUSYDETECT | ( | p | ) | (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */) |
#define CANPROGRESSDETECT | ( | p | ) | (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */) |
Definition at line 390 of file chan_dahdi.c.
Referenced by dahdi_handle_event(), dahdi_new(), and my_set_waitingfordt().
#define CHAN_PSEUDO -2 |
Definition at line 354 of file chan_dahdi.c.
Referenced by build_channels(), create_channel_name(), dahdi_new(), dahdi_new_pri_nobch_channel(), dahdi_request(), determine_starting_point(), enable_dtmf_detect(), my_dsp_set_digitmode(), and my_set_polarity().
#define CHAN_TAG "Chan " |
Referenced by dahdi_r2_on_chan_log().
#define CIDCW_EXPIRE_SAMPLES ((500 * 8) / READ_SIZE) |
#define CONF_USER_REAL (1 << 0) |
Definition at line 632 of file chan_dahdi.c.
#define CONF_USER_THIRDCALL (1 << 1) |
Definition at line 633 of file chan_dahdi.c.
#define CONTEXT_TAG "Context - " |
Referenced by dahdi_r2_on_context_log().
#define dahdi_get_index | ( | ast, | |||
p, | |||||
nullok | ) | _dahdi_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__) |
Definition at line 3599 of file chan_dahdi.c.
Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_answer(), dahdi_bridge(), dahdi_digit_begin(), dahdi_digit_end(), dahdi_handle_event(), dahdi_hangup(), dahdi_indicate(), dahdi_read(), dahdi_sendtext(), dahdi_setoption(), and dahdi_write().
#define DATA_EXPORT_DAHDI_PVT | ( | MEMBER | ) |
Definition at line 1224 of file chan_dahdi.c.
#define DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID.
Definition at line 290 of file chan_dahdi.c.
Referenced by dahdi_chan_conf_default().
#define DEFAULT_RINGT ((8000 * 8) / READ_SIZE) |
8,000 ms
Definition at line 500 of file chan_dahdi.c.
#define END_SILENCE_LEN 400 |
Referenced by dahdi_sendtext().
#define FORMAT "%-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n" |
#define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" |
#define FORMAT "%4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n" |
#define FORMAT "%4s %40s\n" |
Referenced by __iax2_show_peers(), _sip_show_peers(), alias_show(), dahdi_show_status(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), gtalk_show_channels(), handle_cli_core_show_channeltypes(), handle_cli_core_show_file_formats(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_registry(), handle_cli_iax2_show_users(), handle_cli_keys_show(), handle_core_show_image_formats(), handle_manager_show_settings(), handle_mfcr2_show_channels(), handle_mfcr2_show_variants(), handle_show_calendar(), handle_show_calendars(), handle_show_routes(), handle_show_version_files(), jingle_show_channels(), show_channels_cb(), show_chanstats_cb(), sip_show_domains(), sip_show_inuse(), sip_show_mwi(), sip_show_registry(), sip_show_tcp(), and sip_show_users().
#define FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n" |
#define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" |
Referenced by __iax2_show_peers(), _sip_show_peers(), dahdi_show_channels(), dahdi_show_status(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), handle_cli_core_show_file_formats(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_registry(), handle_cli_iax2_show_users(), handle_core_show_image_formats(), handle_manager_show_settings(), handle_show_calendar(), sip_show_channels(), sip_show_channelstats(), sip_show_inuse(), sip_show_registry(), and sip_show_tcp().
#define GET_CHANNEL | ( | p | ) | ((p)->channel) |
#define HANGUP 1 |
Definition at line 15420 of file chan_dahdi.c.
Referenced by action_transferhangup(), and dahdi_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_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_suspend(), build_suspend_acknowledge(), build_suspend_reject(), build_user_information(), dahdi_sendtext(), parse_alerting(), parse_connect(), parse_disconnect(), parse_facility(), parse_proceeding(), parse_progress(), parse_release(), parse_release_complete(), parse_restart(), parse_setup(), and parse_setup_acknowledge().
#define HEADER_MS 50 |
Referenced by dahdi_sendtext().
#define ISTRUNK | ( | p | ) |
Value:
Definition at line 386 of file chan_dahdi.c.
Referenced by __analog_ss_thread(), analog_ss_thread(), and dahdi_indicate().
#define MASK_AVAIL (1 << 0) |
Channel available for PRI use
Definition at line 492 of file chan_dahdi.c.
#define MASK_INUSE (1 << 1) |
Channel currently in use
Definition at line 493 of file chan_dahdi.c.
#define MAX_CHANLIST_LEN 80 |
The length of the parameters list of 'dahdichan'.
Definition at line 16379 of file chan_dahdi.c.
Referenced by process_dahdi().
#define MAX_SLAVES 4 |
Definition at line 635 of file chan_dahdi.c.
Referenced by isslavenative(), and my_complete_conference_update().
#define MIN_MS_SINCE_FLASH ((2000) ) |
2000 ms
Definition at line 499 of file chan_dahdi.c.
Referenced by __analog_handle_event(), and dahdi_handle_event().
#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 296 of file chan_dahdi.c.
Referenced by analog_ss_thread(), and dahdi_new().
#define NUM_CADENCE_MAX 25 |
Definition at line 361 of file chan_dahdi.c.
#define NUM_SPANS 32 |
Definition at line 351 of file chan_dahdi.c.
Referenced by destroy_all_channels(), pri_create_trunkgroup(), pri_resolve_span(), and ss7_resolve_linkset().
#define POLARITY_IDLE 0 |
Definition at line 592 of file chan_dahdi.c.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_hangup(), dahdi_handle_event(), dahdi_hangup(), and unalloc_sub().
#define POLARITY_REV 1 |
Definition at line 593 of file chan_dahdi.c.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_handle_init_event(), dahdi_handle_event(), and handle_init_event().
#define PROC_DAHDI_OPT_NOCHAN (1 << 0) |
process_dahdi() - ignore keyword 'channel' and similar
Definition at line 16433 of file chan_dahdi.c.
Referenced by process_dahdi(), and setup_dahdi_int().
#define PROC_DAHDI_OPT_NOWARN (1 << 1) |
process_dahdi() - No warnings on non-existing cofiguration keywords
Definition at line 16435 of file chan_dahdi.c.
Referenced by setup_dahdi_int().
#define R2_LINK_CAPACITY 10 |
#define READ_SIZE 160 |
Chunk size to read -- we use 20ms chunks to make things happy.
Definition at line 490 of file chan_dahdi.c.
Referenced by dahdi_callwait(), dahdi_open(), dahdi_read(), dahdi_sendtext(), dahdi_setoption(), my_callwait(), my_dahdi_write(), my_send_callerid(), and send_cwcidspill().
#define REPORT_CHANNEL_ALARMS 1 |
Definition at line 413 of file chan_dahdi.c.
Referenced by handle_alarms(), and handle_clear_alarms().
#define REPORT_SPAN_ALARMS 2 |
Definition at line 414 of file chan_dahdi.c.
Referenced by handle_alarms(), and handle_clear_alarms().
#define sig2str dahdi_sig2str |
Definition at line 4525 of file chan_dahdi.c.
Referenced by action_dahdishowchannels(), build_channels(), dahdi_handle_event(), dahdi_show_channel(), and handle_init_event().
#define SIG_BRI (0x2000000 | DAHDI_SIG_CLEAR) |
Definition at line 337 of file chan_dahdi.c.
Referenced by dahdi_sig2str(), and sig_pri_start_pri().
#define SIG_BRI_PTMP (0X4000000 | DAHDI_SIG_CLEAR) |
Definition at line 338 of file chan_dahdi.c.
Referenced by dahdi_sig2str(), pri_dchannel(), sig_pri_cc_generic_check(), and sig_pri_start_pri().
#define SIG_E911 (0x1000000 | DAHDI_SIG_EM) |
Definition at line 326 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_EM DAHDI_SIG_EM |
Definition at line 321 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_EM_E1 DAHDI_SIG_EM_E1 |
Definition at line 346 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_EMWINK (0x0100000 | DAHDI_SIG_EM) |
Definition at line 322 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_FEATB (0x0800000 | DAHDI_SIG_EM) |
Definition at line 325 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_FEATD (0x0200000 | DAHDI_SIG_EM) |
Definition at line 323 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_FEATDMF (0x0400000 | DAHDI_SIG_EM) |
Definition at line 324 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_FEATDMF_TA (0x2000000 | DAHDI_SIG_EM) |
Definition at line 327 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_FGC_CAMA (0x4000000 | DAHDI_SIG_EM) |
Definition at line 328 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_FGC_CAMAMF (0x8000000 | DAHDI_SIG_EM) |
Definition at line 329 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_FXOGS DAHDI_SIG_FXOGS |
Definition at line 334 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_hangup(), dahdi_new(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_FXOKS DAHDI_SIG_FXOKS |
Definition at line 335 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_hangup(), dahdi_new(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_FXOLS DAHDI_SIG_FXOLS |
Definition at line 333 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_hangup(), dahdi_new(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_FXSGS DAHDI_SIG_FXSGS |
Definition at line 331 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_hangup(), dahdi_indicate(), dahdi_sig2str(), dahdisig_to_analogsig(), do_monitor(), handle_init_event(), and my_is_off_hook().
#define SIG_FXSKS DAHDI_SIG_FXSKS |
Definition at line 332 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_hangup(), dahdi_indicate(), dahdi_sig2str(), dahdisig_to_analogsig(), do_monitor(), handle_init_event(), and my_is_off_hook().
#define SIG_FXSLS DAHDI_SIG_FXSLS |
Definition at line 330 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_hangup(), dahdi_indicate(), dahdi_sig2str(), dahdisig_to_analogsig(), do_monitor(), and handle_init_event().
#define SIG_MFCR2 DAHDI_SIG_CAS |
Definition at line 340 of file chan_dahdi.c.
Referenced by dahdi_answer(), dahdi_call(), dahdi_handle_event(), dahdi_hangup(), dahdi_sig2str(), do_monitor(), handle_mfcr2_call_files(), handle_mfcr2_set_blocked(), handle_mfcr2_set_debug(), handle_mfcr2_set_idle(), and handle_mfcr2_show_channels().
#define SIG_MFCR2_MAX_CHANNELS 672 |
No more than a DS3 per trunk group
Definition at line 83 of file chan_dahdi.c.
#define SIG_PRI DAHDI_SIG_CLEAR |
#define SIG_PRI_LIB_HANDLE_CASES |
Value:
SIG_PRI: \ case SIG_BRI: \ case SIG_BRI_PTMP
Definition at line 1519 of file chan_dahdi.c.
Referenced by available(), dahdi_answer(), dahdi_bridge(), dahdi_confmute(), dahdi_digit_begin(), dahdi_enable_ec(), dahdi_func_read(), dahdi_handle_event(), dahdi_hangup(), dahdi_indicate(), dahdi_new(), dahdi_request(), dahdi_send_callrerouting_facility_exec(), dahdi_sig_pri_lib_handles(), destroy_dahdi_pvt(), handle_init_event(), and my_new_pri_ast_channel().
#define SIG_SF DAHDI_SIG_SF |
Definition at line 341 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_SF_FEATB (0x0800000 | DAHDI_SIG_SF) |
Definition at line 345 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_SF_FEATD (0x0200000 | DAHDI_SIG_SF) |
Definition at line 343 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_SF_FEATDMF (0x0400000 | DAHDI_SIG_SF) |
Definition at line 344 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_SFWINK (0x0100000 | DAHDI_SIG_SF) |
Definition at line 342 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), and handle_init_event().
#define SIG_SS7 (0x1000000 | DAHDI_SIG_CLEAR) |
Definition at line 339 of file chan_dahdi.c.
Referenced by available(), dahdi_answer(), dahdi_call(), dahdi_confmute(), dahdi_enable_ec(), dahdi_handle_event(), dahdi_hangup(), dahdi_indicate(), dahdi_new(), dahdi_request(), dahdi_sig2str(), destroy_dahdi_pvt(), and handle_init_event().
#define SMDI_MD_WAIT_TIMEOUT 1500 |
#define SUB_CALLWAIT 1 |
Call-Waiting call on hold
Definition at line 588 of file chan_dahdi.c.
Referenced by _dahdi_get_index(), analog_ss_thread(), analogsub_to_dahdisub(), dahdi_bridge(), dahdi_handle_event(), dahdi_hangup(), dahdi_read(), dahdi_request(), and dahdi_show_channel().
#define SUB_REAL 0 |
Active call
Definition at line 587 of file chan_dahdi.c.
Referenced by __dahdi_exception(), _dahdi_get_index(), analog_ss_thread(), analogsub_to_dahdisub(), attempt_transfer(), build_device(), bump_gains(), check_for_conference(), close_call(), close_client(), dahdi_answer(), dahdi_bridge(), dahdi_call(), dahdi_confmute(), dahdi_destroy_channel_bynum(), dahdi_digit_begin(), dahdi_digit_end(), dahdi_disable_ec(), dahdi_enable_ec(), dahdi_func_write(), dahdi_handle_event(), dahdi_hangup(), dahdi_indicate(), dahdi_new(), dahdi_r2_on_call_accepted(), dahdi_r2_on_call_answered(), dahdi_r2_on_call_disconnect(), dahdi_r2_on_call_offered(), dahdi_read(), dahdi_request(), dahdi_ring_phone(), dahdi_set_hwgain(), dahdi_set_swgain(), dahdi_setoption(), dahdi_show_channel(), dahdi_train_ec(), dahdi_unlink(), destroy_dahdi_pvt(), disable_dtmf_detect(), do_monitor(), duplicate_pseudo(), enable_dtmf_detect(), find_subchannel_by_name(), get_alarms(), handle_init_event(), HandleCallIncoming(), HandleCallOutgoing(), key_call(), key_dial_page(), mfcr2_monitor(), mwi_send_init(), mwi_send_process_buffer(), mwi_send_process_event(), mwi_thread(), my_all_subchannels_hungup(), my_complete_conference_update(), my_flash(), my_get_callerid(), my_get_event(), my_is_off_hook(), my_new_pri_ast_channel(), my_new_ss7_ast_channel(), my_off_hook(), my_pri_fixup_chans(), my_pri_open_media(), my_pri_play_tone(), my_set_cadence(), my_set_needringing(), my_set_polarity(), my_ss7_play_tone(), my_ss7_set_loopback(), my_start(), my_start_cid_detect(), my_stop_cid_detect(), my_wait_event(), my_wink(), process_request(), rcv_mac_addr(), reset_conf(), restore_conference(), restore_gains(), revert_fax_buffers(), save_conference(), send_callerid(), TransferCallStep1(), unistim_do_senddigit(), unistim_hangup(), and unistim_senddigit_end().
#define SUB_THREEWAY 2 |
Three-way call
Definition at line 589 of file chan_dahdi.c.
Referenced by _dahdi_get_index(), analog_ss_thread(), analogsub_to_dahdisub(), attempt_transfer(), close_call(), dahdi_bridge(), dahdi_handle_event(), dahdi_hangup(), dahdi_show_channel(), HandleCallOutgoing(), TransferCallStep1(), unistim_answer(), and unistim_hangup().
#define TRAILER_MS 5 |
Referenced by dahdi_sendtext().
#define TRANSFER 0 |
Definition at line 15419 of file chan_dahdi.c.
Referenced by action_transfer(), and dahdi_fake_event().
enum DAHDI_IFLIST |
Specify the lists dahdi_pvt can be put in.
DAHDI_IFLIST_NONE | The dahdi_pvt is not in any list. |
DAHDI_IFLIST_MAIN | The dahdi_pvt is in the main interface list |
DAHDI_IFLIST_NO_B_CHAN | The dahdi_pvt is in a no B channel interface list |
Definition at line 656 of file chan_dahdi.c.
00656 { 00657 DAHDI_IFLIST_NONE, /*!< The dahdi_pvt is not in any list. */ 00658 DAHDI_IFLIST_MAIN, /*!< The dahdi_pvt is in the main interface list */ 00659 #if defined(HAVE_PRI) 00660 DAHDI_IFLIST_NO_B_CHAN, /*!< The dahdi_pvt is in a no B channel interface list */ 00661 #endif /* defined(HAVE_PRI) */ 00662 };
enum mwisend_states |
MWI_SEND_NULL | |
MWI_SEND_SA | |
MWI_SEND_SA_WAIT | |
MWI_SEND_PAUSE | |
MWI_SEND_SPILL | |
MWI_SEND_CLEANUP | |
MWI_SEND_DONE |
Definition at line 640 of file chan_dahdi.c.
00640 { 00641 MWI_SEND_NULL = 0, 00642 MWI_SEND_SA, 00643 MWI_SEND_SA_WAIT, 00644 MWI_SEND_PAUSE, 00645 MWI_SEND_SPILL, 00646 MWI_SEND_CLEANUP, 00647 MWI_SEND_DONE, 00648 } mwisend_states;
static struct ast_frame* __dahdi_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 8512 of file chan_dahdi.c.
References ast_bridged_channel(), AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_set_hangupsource(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_tv(), ast_tvnow(), ast_verb, dahdi_pvt::channel, dahdi_disable_ec(), dahdi_enable_ec(), dahdi_get_event(), dahdi_get_index, dahdi_handle_event(), dahdi_ring_phone(), dahdi_set_hook(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, event2str(), dahdi_subchannel::f, f, dahdi_pvt::fake_event, ast_channel::fds, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::mallocd, ast_channel::name, dahdi_subchannel::needunhold, ast_frame::offset, dahdi_pvt::oprmode, dahdi_subchannel::owner, dahdi_pvt::owner, ast_frame::ptr, dahdi_pvt::radio, ast_frame::samples, ast_frame::src, SUB_REAL, ast_frame::subclass, dahdi_pvt::subs, ast_channel::tech_pvt, and update_conf().
Referenced by dahdi_exception(), and dahdi_read().
08513 { 08514 int res; 08515 int idx; 08516 struct ast_frame *f; 08517 int usedindex = -1; 08518 struct dahdi_pvt *p = ast->tech_pvt; 08519 08520 idx = dahdi_get_index(ast, p, 1); 08521 08522 p->subs[idx].f.frametype = AST_FRAME_NULL; 08523 p->subs[idx].f.datalen = 0; 08524 p->subs[idx].f.samples = 0; 08525 p->subs[idx].f.mallocd = 0; 08526 p->subs[idx].f.offset = 0; 08527 p->subs[idx].f.subclass.integer = 0; 08528 p->subs[idx].f.delivery = ast_tv(0,0); 08529 p->subs[idx].f.src = "dahdi_exception"; 08530 p->subs[idx].f.data.ptr = NULL; 08531 08532 08533 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) { 08534 /* If nobody owns us, absorb the event appropriately, otherwise 08535 we loop indefinitely. This occurs when, during call waiting, the 08536 other end hangs up our channel so that it no longer exists, but we 08537 have neither FLASH'd nor ONHOOK'd to signify our desire to 08538 change to the other channel. */ 08539 if (p->fake_event) { 08540 res = p->fake_event; 08541 p->fake_event = 0; 08542 } else 08543 res = dahdi_get_event(p->subs[SUB_REAL].dfd); 08544 /* Switch to real if there is one and this isn't something really silly... */ 08545 if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) && 08546 (res != DAHDI_EVENT_HOOKCOMPLETE)) { 08547 ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res); 08548 p->owner = p->subs[SUB_REAL].owner; 08549 if (p->owner && ast_bridged_channel(p->owner)) 08550 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08551 p->subs[SUB_REAL].needunhold = 1; 08552 } 08553 switch (res) { 08554 case DAHDI_EVENT_ONHOOK: 08555 dahdi_disable_ec(p); 08556 if (p->owner) { 08557 ast_verb(3, "Channel %s still has call, ringing phone\n", p->owner->name); 08558 dahdi_ring_phone(p); 08559 p->callwaitingrepeat = 0; 08560 p->cidcwexpire = 0; 08561 p->cid_suppress_expire = 0; 08562 } else 08563 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 08564 update_conf(p); 08565 break; 08566 case DAHDI_EVENT_RINGOFFHOOK: 08567 dahdi_enable_ec(p); 08568 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 08569 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 08570 p->subs[SUB_REAL].needanswer = 1; 08571 p->dialing = 0; 08572 } 08573 break; 08574 case DAHDI_EVENT_HOOKCOMPLETE: 08575 case DAHDI_EVENT_RINGERON: 08576 case DAHDI_EVENT_RINGEROFF: 08577 /* Do nothing */ 08578 break; 08579 case DAHDI_EVENT_WINKFLASH: 08580 p->flashtime = ast_tvnow(); 08581 if (p->owner) { 08582 ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 08583 if (p->owner->_state != AST_STATE_UP) { 08584 /* Answer if necessary */ 08585 usedindex = dahdi_get_index(p->owner, p, 0); 08586 if (usedindex > -1) { 08587 p->subs[usedindex].needanswer = 1; 08588 } 08589 ast_setstate(p->owner, AST_STATE_UP); 08590 } 08591 p->callwaitingrepeat = 0; 08592 p->cidcwexpire = 0; 08593 p->cid_suppress_expire = 0; 08594 if (ast_bridged_channel(p->owner)) 08595 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08596 p->subs[SUB_REAL].needunhold = 1; 08597 } else 08598 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 08599 update_conf(p); 08600 break; 08601 default: 08602 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 08603 } 08604 f = &p->subs[idx].f; 08605 return f; 08606 } 08607 if (!(p->radio || (p->oprmode < 0))) 08608 ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 08609 /* If it's not us, return NULL immediately */ 08610 if (ast != p->owner) { 08611 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 08612 f = &p->subs[idx].f; 08613 return f; 08614 } 08615 f = dahdi_handle_event(ast); 08616 08617 /* tell the cdr this zap device hung up */ 08618 if (f == NULL) { 08619 ast_set_hangupsource(ast, ast->name, 0); 08620 } 08621 08622 return f; 08623 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 18173 of file chan_dahdi.c.
static int __unload_module | ( | void | ) | [static] |
Definition at line 16179 of file chan_dahdi.c.
References ARRAY_LEN, ast_cc_agent_unregister(), ast_cc_monitor_unregister(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_destroy, ast_data_unregister, ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_unregister_application(), dahdi_cli, dahdi_close_pri_fd(), dahdi_close_ss7_fd(), dahdi_mfcr2_cli, dahdi_pri_cli, dahdi_r2_destroy_links(), dahdi_ss7_cli, dahdi_tech, destroy_all_channels(), iflist, sig_ss7_linkset::master, sig_pri_span::master, monitor_thread, monlock, dahdi_pvt::next, dahdi_pvt::owner, dahdi_pvt::pri, sig_pri_stop_pri(), sig_pri_unload(), dahdi_pvt::ss7, and ss_thread_complete.
Referenced by load_module(), and unload_module().
16180 { 16181 struct dahdi_pvt *p; 16182 #if defined(HAVE_PRI) || defined(HAVE_SS7) 16183 int i, j; 16184 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 16185 16186 #ifdef HAVE_PRI 16187 for (i = 0; i < NUM_SPANS; i++) { 16188 if (pris[i].pri.master != AST_PTHREADT_NULL) 16189 pthread_cancel(pris[i].pri.master); 16190 } 16191 ast_cli_unregister_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli)); 16192 ast_unregister_application(dahdi_send_keypad_facility_app); 16193 #ifdef HAVE_PRI_PROG_W_CAUSE 16194 ast_unregister_application(dahdi_send_callrerouting_facility_app); 16195 #endif 16196 #endif 16197 #if defined(HAVE_SS7) 16198 for (i = 0; i < NUM_SPANS; i++) { 16199 if (linksets[i].ss7.master != AST_PTHREADT_NULL) 16200 pthread_cancel(linksets[i].ss7.master); 16201 } 16202 ast_cli_unregister_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli)); 16203 #endif /* defined(HAVE_SS7) */ 16204 #if defined(HAVE_OPENR2) 16205 dahdi_r2_destroy_links(); 16206 ast_cli_unregister_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli)); 16207 ast_unregister_application(dahdi_accept_r2_call_app); 16208 #endif 16209 16210 ast_cli_unregister_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli)); 16211 ast_manager_unregister("DAHDIDialOffhook"); 16212 ast_manager_unregister("DAHDIHangup"); 16213 ast_manager_unregister("DAHDITransfer"); 16214 ast_manager_unregister("DAHDIDNDoff"); 16215 ast_manager_unregister("DAHDIDNDon"); 16216 ast_manager_unregister("DAHDIShowChannels"); 16217 ast_manager_unregister("DAHDIRestart"); 16218 ast_data_unregister(NULL); 16219 ast_channel_unregister(&dahdi_tech); 16220 16221 /* Hangup all interfaces if they have an owner */ 16222 ast_mutex_lock(&iflock); 16223 for (p = iflist; p; p = p->next) { 16224 if (p->owner) 16225 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 16226 } 16227 ast_mutex_unlock(&iflock); 16228 16229 ast_mutex_lock(&monlock); 16230 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 16231 pthread_cancel(monitor_thread); 16232 pthread_kill(monitor_thread, SIGURG); 16233 pthread_join(monitor_thread, NULL); 16234 } 16235 monitor_thread = AST_PTHREADT_STOP; 16236 ast_mutex_unlock(&monlock); 16237 16238 destroy_all_channels(); 16239 16240 #if defined(HAVE_PRI) 16241 for (i = 0; i < NUM_SPANS; i++) { 16242 if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) 16243 pthread_join(pris[i].pri.master, NULL); 16244 for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) { 16245 dahdi_close_pri_fd(&(pris[i]), j); 16246 } 16247 sig_pri_stop_pri(&pris[i].pri); 16248 } 16249 #if defined(HAVE_PRI_CCSS) 16250 ast_cc_agent_unregister(&dahdi_pri_cc_agent_callbacks); 16251 ast_cc_monitor_unregister(&dahdi_pri_cc_monitor_callbacks); 16252 #endif /* defined(HAVE_PRI_CCSS) */ 16253 sig_pri_unload(); 16254 #endif 16255 16256 #if defined(HAVE_SS7) 16257 for (i = 0; i < NUM_SPANS; i++) { 16258 if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) 16259 pthread_join(linksets[i].ss7.master, NULL); 16260 for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) { 16261 dahdi_close_ss7_fd(&(linksets[i]), j); 16262 } 16263 } 16264 #endif /* defined(HAVE_SS7) */ 16265 ast_cond_destroy(&ss_thread_complete); 16266 return 0; 16267 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 18173 of file chan_dahdi.c.
static int _dahdi_get_index | ( | struct ast_channel * | ast, | |
struct dahdi_pvt * | p, | |||
int | nullok, | |||
const char * | fname, | |||
unsigned long | line | |||
) | [static] |
Definition at line 3600 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, LOG_WARNING, ast_channel::name, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, and dahdi_pvt::subs.
03601 { 03602 int res; 03603 if (p->subs[SUB_REAL].owner == ast) 03604 res = 0; 03605 else if (p->subs[SUB_CALLWAIT].owner == ast) 03606 res = 1; 03607 else if (p->subs[SUB_THREEWAY].owner == ast) 03608 res = 2; 03609 else { 03610 res = -1; 03611 if (!nullok) 03612 ast_log(LOG_WARNING, 03613 "Unable to get index for '%s' on channel %d (%s(), line %lu)\n", 03614 ast ? ast->name : "", p->channel, fname, line); 03615 } 03616 return res; 03617 }
static int action_dahdidialoffhook | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 15528 of file chan_dahdi.c.
References AST_FRAME_DTMF, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_queue_frame(), f, find_channel(), and dahdi_pvt::owner.
Referenced by load_module().
15529 { 15530 struct dahdi_pvt *p = NULL; 15531 const char *channel = astman_get_header(m, "DAHDIChannel"); 15532 const char *number = astman_get_header(m, "Number"); 15533 int i; 15534 15535 if (ast_strlen_zero(channel)) { 15536 astman_send_error(s, m, "No channel specified"); 15537 return 0; 15538 } 15539 if (ast_strlen_zero(number)) { 15540 astman_send_error(s, m, "No number specified"); 15541 return 0; 15542 } 15543 p = find_channel(atoi(channel)); 15544 if (!p) { 15545 astman_send_error(s, m, "No such channel"); 15546 return 0; 15547 } 15548 if (!p->owner) { 15549 astman_send_error(s, m, "Channel does not have it's owner"); 15550 return 0; 15551 } 15552 for (i = 0; i < strlen(number); i++) { 15553 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = number[i] }; 15554 dahdi_queue_frame(p, &f); 15555 } 15556 astman_send_ack(s, m, "DAHDIDialOffhook"); 15557 return 0; 15558 }
static int action_dahdidndoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 15471 of file chan_dahdi.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_dnd(), and find_channel().
Referenced by load_module().
15472 { 15473 struct dahdi_pvt *p = NULL; 15474 const char *channel = astman_get_header(m, "DAHDIChannel"); 15475 15476 if (ast_strlen_zero(channel)) { 15477 astman_send_error(s, m, "No channel specified"); 15478 return 0; 15479 } 15480 p = find_channel(atoi(channel)); 15481 if (!p) { 15482 astman_send_error(s, m, "No such channel"); 15483 return 0; 15484 } 15485 dahdi_dnd(p, 0); 15486 astman_send_ack(s, m, "DND Disabled"); 15487 return 0; 15488 }
static int action_dahdidndon | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 15452 of file chan_dahdi.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_dnd(), and find_channel().
Referenced by load_module().
15453 { 15454 struct dahdi_pvt *p = NULL; 15455 const char *channel = astman_get_header(m, "DAHDIChannel"); 15456 15457 if (ast_strlen_zero(channel)) { 15458 astman_send_error(s, m, "No channel specified"); 15459 return 0; 15460 } 15461 p = find_channel(atoi(channel)); 15462 if (!p) { 15463 astman_send_error(s, m, "No such channel"); 15464 return 0; 15465 } 15466 dahdi_dnd(p, 1); 15467 astman_send_ack(s, m, "DND Enabled"); 15468 return 0; 15469 }
static int action_dahdirestart | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 14760 of file chan_dahdi.c.
References astman_send_ack(), astman_send_error(), and dahdi_restart().
Referenced by load_module().
14761 { 14762 if (dahdi_restart() != 0) { 14763 astman_send_error(s, m, "Failed rereading DAHDI configuration"); 14764 return 1; 14765 } 14766 astman_send_ack(s, m, "DAHDIRestart: Success"); 14767 return 0; 14768 }
static int action_dahdishowchannels | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 15560 of file chan_dahdi.c.
References ast_channel::accountcode, alarm2str(), ast_mutex_lock, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), dahdi_pvt::channel, channels, dahdi_pvt::context, dahdi_dnd(), get_alarms(), iflist, ast_channel::name, dahdi_pvt::next, dahdi_pvt::owner, dahdi_pvt::sig, sig2str, and ast_channel::uniqueid.
Referenced by load_module().
15561 { 15562 struct dahdi_pvt *tmp = NULL; 15563 const char *id = astman_get_header(m, "ActionID"); 15564 const char *dahdichannel = astman_get_header(m, "DAHDIChannel"); 15565 char idText[256] = ""; 15566 int channels = 0; 15567 int dahdichanquery = -1; 15568 if (!ast_strlen_zero(dahdichannel)) { 15569 dahdichanquery = atoi(dahdichannel); 15570 } 15571 15572 astman_send_ack(s, m, "DAHDI channel status will follow"); 15573 if (!ast_strlen_zero(id)) 15574 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 15575 15576 ast_mutex_lock(&iflock); 15577 15578 for (tmp = iflist; tmp; tmp = tmp->next) { 15579 if (tmp->channel > 0) { 15580 int alm; 15581 15582 /* If a specific channel is queried for, only deliver status for that channel */ 15583 if (dahdichanquery > 0 && tmp->channel != dahdichanquery) 15584 continue; 15585 15586 alm = get_alarms(tmp); 15587 channels++; 15588 if (tmp->owner) { 15589 /* Add data if we have a current call */ 15590 astman_append(s, 15591 "Event: DAHDIShowChannels\r\n" 15592 "DAHDIChannel: %d\r\n" 15593 "Channel: %s\r\n" 15594 "Uniqueid: %s\r\n" 15595 "AccountCode: %s\r\n" 15596 "Signalling: %s\r\n" 15597 "SignallingCode: %d\r\n" 15598 "Context: %s\r\n" 15599 "DND: %s\r\n" 15600 "Alarm: %s\r\n" 15601 "%s" 15602 "\r\n", 15603 tmp->channel, 15604 tmp->owner->name, 15605 tmp->owner->uniqueid, 15606 tmp->owner->accountcode, 15607 sig2str(tmp->sig), 15608 tmp->sig, 15609 tmp->context, 15610 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled", 15611 alarm2str(alm), idText); 15612 } else { 15613 astman_append(s, 15614 "Event: DAHDIShowChannels\r\n" 15615 "DAHDIChannel: %d\r\n" 15616 "Signalling: %s\r\n" 15617 "SignallingCode: %d\r\n" 15618 "Context: %s\r\n" 15619 "DND: %s\r\n" 15620 "Alarm: %s\r\n" 15621 "%s" 15622 "\r\n", 15623 tmp->channel, sig2str(tmp->sig), tmp->sig, 15624 tmp->context, 15625 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled", 15626 alarm2str(alm), idText); 15627 } 15628 } 15629 } 15630 15631 ast_mutex_unlock(&iflock); 15632 15633 astman_append(s, 15634 "Event: DAHDIShowChannelsComplete\r\n" 15635 "%s" 15636 "Items: %d\r\n" 15637 "\r\n", 15638 idText, 15639 channels); 15640 return 0; 15641 }
static int action_transfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 15490 of file chan_dahdi.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_fake_event(), find_channel(), and TRANSFER.
Referenced by load_module().
15491 { 15492 struct dahdi_pvt *p = NULL; 15493 const char *channel = astman_get_header(m, "DAHDIChannel"); 15494 15495 if (ast_strlen_zero(channel)) { 15496 astman_send_error(s, m, "No channel specified"); 15497 return 0; 15498 } 15499 p = find_channel(atoi(channel)); 15500 if (!p) { 15501 astman_send_error(s, m, "No such channel"); 15502 return 0; 15503 } 15504 dahdi_fake_event(p,TRANSFER); 15505 astman_send_ack(s, m, "DAHDITransfer"); 15506 return 0; 15507 }
static int action_transferhangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 15509 of file chan_dahdi.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_fake_event(), find_channel(), and HANGUP.
Referenced by load_module().
15510 { 15511 struct dahdi_pvt *p = NULL; 15512 const char *channel = astman_get_header(m, "DAHDIChannel"); 15513 15514 if (ast_strlen_zero(channel)) { 15515 astman_send_error(s, m, "No channel specified"); 15516 return 0; 15517 } 15518 p = find_channel(atoi(channel)); 15519 if (!p) { 15520 astman_send_error(s, m, "No such channel"); 15521 return 0; 15522 } 15523 dahdi_fake_event(p,HANGUP); 15524 astman_send_ack(s, m, "DAHDIHangup"); 15525 return 0; 15526 }
static char* alarm2str | ( | int | alm | ) | [static] |
Definition at line 4442 of file chan_dahdi.c.
References alarm, alarms, and ARRAY_LEN.
Referenced by action_dahdishowchannels(), and handle_alarms().
04443 { 04444 int x; 04445 for (x = 0; x < ARRAY_LEN(alarms); x++) { 04446 if (alarms[x].alarm & alm) 04447 return alarms[x].name; 04448 } 04449 return alm ? "Unknown Alarm" : "No Alarm"; 04450 }
static int alloc_sub | ( | struct dahdi_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 4246 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_pvt::buf_no, dahdi_pvt::buf_policy, dahdi_subchannel::chan, dahdi_pvt::channel, dahdi_close_sub(), dahdi_open(), dahdi_subchannel::dfd, errno, LOG_WARNING, subnames, and dahdi_pvt::subs.
Referenced by analog_ss_thread(), build_device(), dahdi_handle_event(), HandleCallOutgoing(), my_allocate_sub(), and rcv_mac_addr().
04247 { 04248 struct dahdi_bufferinfo bi; 04249 int res; 04250 if (p->subs[x].dfd >= 0) { 04251 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel); 04252 return -1; 04253 } 04254 04255 p->subs[x].dfd = dahdi_open("/dev/dahdi/pseudo"); 04256 if (p->subs[x].dfd <= -1) { 04257 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 04258 return -1; 04259 } 04260 04261 res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi); 04262 if (!res) { 04263 bi.txbufpolicy = p->buf_policy; 04264 bi.rxbufpolicy = p->buf_policy; 04265 bi.numbufs = p->buf_no; 04266 res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi); 04267 if (res < 0) { 04268 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno)); 04269 } 04270 } else 04271 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno)); 04272 04273 if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) { 04274 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno)); 04275 dahdi_close_sub(p, x); 04276 p->subs[x].dfd = -1; 04277 return -1; 04278 } 04279 ast_debug(1, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan); 04280 return 0; 04281 }
static int analog_lib_handles | ( | int | signalling, | |
int | radio, | |||
int | oprmode | |||
) | [static] |
Definition at line 4527 of file chan_dahdi.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_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, and SIG_SFWINK.
Referenced by available(), dahdi_answer(), dahdi_call(), dahdi_dnd(), dahdi_exception(), dahdi_hangup(), dahdi_new(), dahdi_read(), dahdi_request(), destroy_dahdi_pvt(), do_monitor(), and mwi_thread().
04528 { 04529 switch (signalling) { 04530 case SIG_FXOLS: 04531 case SIG_FXOGS: 04532 case SIG_FXOKS: 04533 case SIG_FXSLS: 04534 case SIG_FXSGS: 04535 case SIG_FXSKS: 04536 case SIG_EMWINK: 04537 case SIG_EM: 04538 case SIG_EM_E1: 04539 case SIG_FEATD: 04540 case SIG_FEATDMF: 04541 case SIG_E911: 04542 case SIG_FGC_CAMA: 04543 case SIG_FGC_CAMAMF: 04544 case SIG_FEATB: 04545 case SIG_SFWINK: 04546 case SIG_SF: 04547 case SIG_SF_FEATD: 04548 case SIG_SF_FEATDMF: 04549 case SIG_FEATDMF_TA: 04550 case SIG_SF_FEATB: 04551 break; 04552 default: 04553 /* The rest of the function should cover the remainder of signalling types */ 04554 return 0; 04555 } 04556 04557 if (radio) 04558 return 0; 04559 04560 if (oprmode) 04561 return 0; 04562 04563 return 1; 04564 }
static void * analog_ss_thread | ( | void * | data | ) | [static] |
Definition at line 9565 of file chan_dahdi.c.
References ast_channel::_state, alloc_sub(), ARRAY_LEN, ast_bridged_channel(), ast_canmatch_extension(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_dsp_digitreset(), ast_dsp_free(), ast_dsp_set_digitmode(), ast_exists_extension(), AST_FLAG_END_DTMF_ONLY, 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_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), ast_party_name_free(), ast_party_name_init(), ast_party_number_free(), ast_party_number_init(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_read(), ast_safe_sleep(), ast_set_callerid(), ast_set_flag, ast_setstate(), ast_smdi_md_message_wait(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_verb, ast_waitfor(), ast_waitfordigit(), ast_waitstream(), bump_gains(), dahdi_pvt::call_forward, ast_channel::caller, callerid_feed(), callerid_feed_jp(), callerid_free(), callerid_get(), callerid_get_dtmf(), callerid_new(), ast_smdi_md_message::calling_st, dahdi_pvt::callreturn, dahdi_pvt::callwaiting, dahdi_pvt::cancallforward, dahdi_pvt::canpark, dahdi_pvt::channel, dahdi_pvt::cid_name, dahdi_pvt::cid_num, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, dahdi_pvt::cid_signalling, dahdi_pvt::cid_start, CID_START_DTMF_NOALERT, CID_START_POLARITY, CID_START_POLARITY_IN, dahdi_pvt::context, ast_channel::context, ringContextData::contextData, dahdi_pvt::cs, dahdi_dnd(), dahdi_enable_ec(), dahdi_get_event(), dahdi_get_index, dahdi_set_hook(), dahdi_setlinear(), dahdi_tech, dahdi_wait_event(), dahdi_wink(), dahdi_pvt::defcontext, dahdi_subchannel::dfd, dahdi_pvt::dop, dahdi_pvt::drings, dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, dahdi_pvt::dtmfrelax, errno, event2str(), ast_channel::exten, exten, f, firstdigittimeout, ast_smdi_md_message::fwd_st, gendigittimeout, dahdi_pvt::hardwaredtmf, dahdi_pvt::hidecallerid, ast_party_caller::id, dahdi_pvt::immediate, dahdi_pvt::inalarm, ISTRUNK, ast_channel::language, len(), dahdi_subchannel::linear, LOG_NOTICE, matchdigittimeout, my_getsigstr(), ast_party_id::name, ast_channel::name, name, NEED_MFDETECT, ast_party_id::number, dahdi_pvt::owner, dahdi_subchannel::owner, pbx_builtin_setvar_helper(), distRingData::range, restore_gains(), distRingData::ring, dahdi_distRings::ringContext, dahdi_distRings::ringnum, dahdi_pvt::ringt, dahdi_pvt::ringt_base, S_COR, S_OR, dahdi_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_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, dahdi_pvt::smdi_iface, SMDI_MD_WAIT_TIMEOUT, ss_thread_count, ss_thread_lock, ast_party_number::str, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, dahdi_pvt::subs, swap_subs(), ast_channel::tech, ast_channel::tech_pvt, dahdi_pvt::transfer, ast_smdi_md_message::type, unalloc_sub(), dahdi_pvt::use_callerid, dahdi_pvt::use_smdi, dahdi_pvt::usedistinctiveringdetection, and ast_party_number::valid.
Referenced by dahdi_handle_event(), handle_init_event(), and mwi_thread().
09566 { 09567 struct ast_channel *chan = data; 09568 struct dahdi_pvt *p = chan->tech_pvt; 09569 char exten[AST_MAX_EXTENSION] = ""; 09570 char exten2[AST_MAX_EXTENSION] = ""; 09571 unsigned char buf[256]; 09572 char dtmfcid[300]; 09573 char dtmfbuf[300]; 09574 struct callerid_state *cs = NULL; 09575 char *name = NULL, *number = NULL; 09576 int distMatches; 09577 int curRingData[3]; 09578 int receivedRingT; 09579 int counter1; 09580 int counter; 09581 int samples = 0; 09582 struct ast_smdi_md_message *smdi_msg = NULL; 09583 int flags = 0; 09584 int i; 09585 int timeout; 09586 int getforward = 0; 09587 char *s1, *s2; 09588 int len = 0; 09589 int res; 09590 int idx; 09591 09592 ast_mutex_lock(&ss_thread_lock); 09593 ss_thread_count++; 09594 ast_mutex_unlock(&ss_thread_lock); 09595 /* in the bizarre case where the channel has become a zombie before we 09596 even get started here, abort safely 09597 */ 09598 if (!p) { 09599 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 09600 ast_hangup(chan); 09601 goto quit; 09602 } 09603 ast_verb(3, "Starting simple switch on '%s'\n", chan->name); 09604 idx = dahdi_get_index(chan, p, 1); 09605 if (idx < 0) { 09606 ast_log(LOG_WARNING, "Huh?\n"); 09607 ast_hangup(chan); 09608 goto quit; 09609 } 09610 if (p->dsp) 09611 ast_dsp_digitreset(p->dsp); 09612 switch (p->sig) { 09613 case SIG_FEATD: 09614 case SIG_FEATDMF: 09615 case SIG_FEATDMF_TA: 09616 case SIG_E911: 09617 case SIG_FGC_CAMAMF: 09618 case SIG_FEATB: 09619 case SIG_EMWINK: 09620 case SIG_SF_FEATD: 09621 case SIG_SF_FEATDMF: 09622 case SIG_SF_FEATB: 09623 case SIG_SFWINK: 09624 if (dahdi_wink(p, idx)) 09625 goto quit; 09626 /* Fall through */ 09627 case SIG_EM: 09628 case SIG_EM_E1: 09629 case SIG_SF: 09630 case SIG_FGC_CAMA: 09631 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 09632 if (p->dsp) 09633 ast_dsp_digitreset(p->dsp); 09634 /* set digit mode appropriately */ 09635 if (p->dsp) { 09636 if (NEED_MFDETECT(p)) 09637 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 09638 else 09639 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 09640 } 09641 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 09642 /* Wait for the first digit only if immediate=no */ 09643 if (!p->immediate) 09644 /* Wait for the first digit (up to 5 seconds). */ 09645 res = ast_waitfordigit(chan, 5000); 09646 else 09647 res = 0; 09648 if (res > 0) { 09649 /* save first char */ 09650 dtmfbuf[0] = res; 09651 switch (p->sig) { 09652 case SIG_FEATD: 09653 case SIG_SF_FEATD: 09654 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 09655 if (res > 0) 09656 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 09657 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 09658 break; 09659 case SIG_FEATDMF_TA: 09660 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 09661 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 09662 if (dahdi_wink(p, idx)) goto quit; 09663 dtmfbuf[0] = 0; 09664 /* Wait for the first digit (up to 5 seconds). */ 09665 res = ast_waitfordigit(chan, 5000); 09666 if (res <= 0) break; 09667 dtmfbuf[0] = res; 09668 /* fall through intentionally */ 09669 case SIG_FEATDMF: 09670 case SIG_E911: 09671 case SIG_FGC_CAMAMF: 09672 case SIG_SF_FEATDMF: 09673 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 09674 /* if international caca, do it again to get real ANO */ 09675 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14)) 09676 { 09677 if (dahdi_wink(p, idx)) goto quit; 09678 dtmfbuf[0] = 0; 09679 /* Wait for the first digit (up to 5 seconds). */ 09680 res = ast_waitfordigit(chan, 5000); 09681 if (res <= 0) break; 09682 dtmfbuf[0] = res; 09683 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 09684 } 09685 if (res > 0) { 09686 /* if E911, take off hook */ 09687 if (p->sig == SIG_E911) 09688 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 09689 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 09690 } 09691 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 09692 break; 09693 case SIG_FEATB: 09694 case SIG_SF_FEATB: 09695 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 09696 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 09697 break; 09698 case SIG_EMWINK: 09699 /* if we received a '*', we are actually receiving Feature Group D 09700 dial syntax, so use that mode; otherwise, fall through to normal 09701 mode 09702 */ 09703 if (res == '*') { 09704 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 09705 if (res > 0) 09706 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 09707 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 09708 break; 09709 } 09710 default: 09711 /* If we got the first digit, get the rest */ 09712 len = 1; 09713 dtmfbuf[len] = '\0'; 09714 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 09715 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 09716 timeout = matchdigittimeout; 09717 } else { 09718 timeout = gendigittimeout; 09719 } 09720 res = ast_waitfordigit(chan, timeout); 09721 if (res < 0) { 09722 ast_debug(1, "waitfordigit returned < 0...\n"); 09723 ast_hangup(chan); 09724 goto quit; 09725 } else if (res) { 09726 dtmfbuf[len++] = res; 09727 dtmfbuf[len] = '\0'; 09728 } else { 09729 break; 09730 } 09731 } 09732 break; 09733 } 09734 } 09735 if (res == -1) { 09736 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 09737 ast_hangup(chan); 09738 goto quit; 09739 } else if (res < 0) { 09740 ast_debug(1, "Got hung up before digits finished\n"); 09741 ast_hangup(chan); 09742 goto quit; 09743 } 09744 09745 if (p->sig == SIG_FGC_CAMA) { 09746 char anibuf[100]; 09747 09748 if (ast_safe_sleep(chan,1000) == -1) { 09749 ast_hangup(chan); 09750 goto quit; 09751 } 09752 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 09753 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 09754 res = my_getsigstr(chan, anibuf, "#", 10000); 09755 if ((res > 0) && (strlen(anibuf) > 2)) { 09756 if (anibuf[strlen(anibuf) - 1] == '#') 09757 anibuf[strlen(anibuf) - 1] = 0; 09758 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 09759 } 09760 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 09761 } 09762 09763 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 09764 if (ast_strlen_zero(exten)) 09765 ast_copy_string(exten, "s", sizeof(exten)); 09766 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 09767 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 09768 if (exten[0] == '*') { 09769 char *stringp=NULL; 09770 ast_copy_string(exten2, exten, sizeof(exten2)); 09771 /* Parse out extension and callerid */ 09772 stringp=exten2 +1; 09773 s1 = strsep(&stringp, "*"); 09774 s2 = strsep(&stringp, "*"); 09775 if (s2) { 09776 if (!ast_strlen_zero(p->cid_num)) 09777 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 09778 else 09779 ast_set_callerid(chan, s1, NULL, s1); 09780 ast_copy_string(exten, s2, sizeof(exten)); 09781 } else 09782 ast_copy_string(exten, s1, sizeof(exten)); 09783 } else if (p->sig == SIG_FEATD) 09784 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 09785 } 09786 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 09787 if (exten[0] == '*') { 09788 char *stringp=NULL; 09789 ast_copy_string(exten2, exten, sizeof(exten2)); 09790 /* Parse out extension and callerid */ 09791 stringp=exten2 +1; 09792 s1 = strsep(&stringp, "#"); 09793 s2 = strsep(&stringp, "#"); 09794 if (s2) { 09795 if (!ast_strlen_zero(p->cid_num)) 09796 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 09797 else 09798 if (*(s1 + 2)) 09799 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 09800 ast_copy_string(exten, s2 + 1, sizeof(exten)); 09801 } else 09802 ast_copy_string(exten, s1 + 2, sizeof(exten)); 09803 } else 09804 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 09805 } 09806 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) { 09807 if (exten[0] == '*') { 09808 char *stringp=NULL; 09809 ast_copy_string(exten2, exten, sizeof(exten2)); 09810 /* Parse out extension and callerid */ 09811 stringp=exten2 +1; 09812 s1 = strsep(&stringp, "#"); 09813 s2 = strsep(&stringp, "#"); 09814 if (s2 && (*(s2 + 1) == '0')) { 09815 if (*(s2 + 2)) 09816 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 09817 } 09818 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 09819 else ast_copy_string(exten, "911", sizeof(exten)); 09820 } else 09821 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 09822 } 09823 if (p->sig == SIG_FEATB) { 09824 if (exten[0] == '*') { 09825 char *stringp=NULL; 09826 ast_copy_string(exten2, exten, sizeof(exten2)); 09827 /* Parse out extension and callerid */ 09828 stringp=exten2 +1; 09829 s1 = strsep(&stringp, "#"); 09830 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 09831 } else 09832 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 09833 } 09834 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 09835 dahdi_wink(p, idx); 09836 /* some switches require a minimum guard time between 09837 the last FGD wink and something that answers 09838 immediately. This ensures it */ 09839 if (ast_safe_sleep(chan,100)) goto quit; 09840 } 09841 dahdi_enable_ec(p); 09842 if (NEED_MFDETECT(p)) { 09843 if (p->dsp) { 09844 if (!p->hardwaredtmf) 09845 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 09846 else { 09847 ast_dsp_free(p->dsp); 09848 p->dsp = NULL; 09849 } 09850 } 09851 } 09852 09853 if (ast_exists_extension(chan, chan->context, exten, 1, 09854 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09855 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 09856 if (p->dsp) ast_dsp_digitreset(p->dsp); 09857 res = ast_pbx_run(chan); 09858 if (res) { 09859 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 09860 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 09861 } 09862 goto quit; 09863 } else { 09864 ast_verb(2, "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 09865 sleep(2); 09866 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_INFO); 09867 if (res < 0) 09868 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 09869 else 09870 sleep(1); 09871 res = ast_streamfile(chan, "ss-noservice", chan->language); 09872 if (res >= 0) 09873 ast_waitstream(chan, ""); 09874 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 09875 ast_hangup(chan); 09876 goto quit; 09877 } 09878 break; 09879 case SIG_FXOLS: 09880 case SIG_FXOGS: 09881 case SIG_FXOKS: 09882 /* Read the first digit */ 09883 timeout = firstdigittimeout; 09884 /* If starting a threeway call, never timeout on the first digit so someone 09885 can use flash-hook as a "hold" feature */ 09886 if (p->subs[SUB_THREEWAY].owner) 09887 timeout = 999999; 09888 while (len < AST_MAX_EXTENSION-1) { 09889 /* Read digit unless it's supposed to be immediate, in which case the 09890 only answer is 's' */ 09891 if (p->immediate) 09892 res = 's'; 09893 else 09894 res = ast_waitfordigit(chan, timeout); 09895 timeout = 0; 09896 if (res < 0) { 09897 ast_debug(1, "waitfordigit returned < 0...\n"); 09898 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 09899 ast_hangup(chan); 09900 goto quit; 09901 } else if (res) { 09902 ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout); 09903 exten[len++]=res; 09904 exten[len] = '\0'; 09905 } 09906 if (!ast_ignore_pattern(chan->context, exten)) 09907 tone_zone_play_tone(p->subs[idx].dfd, -1); 09908 else 09909 tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE); 09910 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && !ast_parking_ext_valid(exten, chan, chan->context)) { 09911 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 09912 if (getforward) { 09913 /* Record this as the forwarding extension */ 09914 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 09915 ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 09916 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 09917 if (res) 09918 break; 09919 usleep(500000); 09920 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 09921 sleep(1); 09922 memset(exten, 0, sizeof(exten)); 09923 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE); 09924 len = 0; 09925 getforward = 0; 09926 } else { 09927 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 09928 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 09929 if (!ast_strlen_zero(p->cid_num)) { 09930 if (!p->hidecallerid) 09931 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 09932 else 09933 ast_set_callerid(chan, NULL, NULL, p->cid_num); 09934 } 09935 if (!ast_strlen_zero(p->cid_name)) { 09936 if (!p->hidecallerid) 09937 ast_set_callerid(chan, NULL, p->cid_name, NULL); 09938 } 09939 ast_setstate(chan, AST_STATE_RING); 09940 dahdi_enable_ec(p); 09941 res = ast_pbx_run(chan); 09942 if (res) { 09943 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 09944 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 09945 } 09946 goto quit; 09947 } 09948 } else { 09949 /* It's a match, but they just typed a digit, and there is an ambiguous match, 09950 so just set the timeout to matchdigittimeout and wait some more */ 09951 timeout = matchdigittimeout; 09952 } 09953 } else if (res == 0) { 09954 ast_debug(1, "not enough digits (and no ambiguous match)...\n"); 09955 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 09956 dahdi_wait_event(p->subs[idx].dfd); 09957 ast_hangup(chan); 09958 goto quit; 09959 } else if (p->callwaiting && !strcmp(exten, "*70")) { 09960 ast_verb(3, "Disabling call waiting on %s\n", chan->name); 09961 /* Disable call waiting if enabled */ 09962 p->callwaiting = 0; 09963 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 09964 if (res) { 09965 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 09966 chan->name, strerror(errno)); 09967 } 09968 len = 0; 09969 ioctl(p->subs[idx].dfd,DAHDI_CONFDIAG,&len); 09970 memset(exten, 0, sizeof(exten)); 09971 timeout = firstdigittimeout; 09972 09973 } else if (!strcmp(exten,ast_pickup_ext())) { 09974 /* Scan all channels and see if there are any 09975 * ringing channels that have call groups 09976 * that equal this channels pickup group 09977 */ 09978 if (idx == SUB_REAL) { 09979 /* Switch us from Third call to Call Wait */ 09980 if (p->subs[SUB_THREEWAY].owner) { 09981 /* If you make a threeway call and the *8# a call, it should actually 09982 look like a callwait */ 09983 alloc_sub(p, SUB_CALLWAIT); 09984 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 09985 unalloc_sub(p, SUB_THREEWAY); 09986 } 09987 dahdi_enable_ec(p); 09988 if (ast_pickup_call(chan)) { 09989 ast_debug(1, "No call pickup possible...\n"); 09990 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 09991 dahdi_wait_event(p->subs[idx].dfd); 09992 } 09993 ast_hangup(chan); 09994 goto quit; 09995 } else { 09996 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 09997 ast_hangup(chan); 09998 goto quit; 09999 } 10000 10001 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 10002 ast_verb(3, "Disabling Caller*ID on %s\n", chan->name); 10003 /* Disable Caller*ID if enabled */ 10004 p->hidecallerid = 1; 10005 ast_party_number_free(&chan->caller.id.number); 10006 ast_party_number_init(&chan->caller.id.number); 10007 ast_party_name_free(&chan->caller.id.name); 10008 ast_party_name_init(&chan->caller.id.name); 10009 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10010 if (res) { 10011 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 10012 chan->name, strerror(errno)); 10013 } 10014 len = 0; 10015 memset(exten, 0, sizeof(exten)); 10016 timeout = firstdigittimeout; 10017 } else if (p->callreturn && !strcmp(exten, "*69")) { 10018 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10019 break; 10020 } else if (!strcmp(exten, "*78")) { 10021 dahdi_dnd(p, 1); 10022 /* Do not disturb */ 10023 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10024 getforward = 0; 10025 memset(exten, 0, sizeof(exten)); 10026 len = 0; 10027 } else if (!strcmp(exten, "*79")) { 10028 dahdi_dnd(p, 0); 10029 /* Do not disturb */ 10030 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10031 getforward = 0; 10032 memset(exten, 0, sizeof(exten)); 10033 len = 0; 10034 } else if (p->cancallforward && !strcmp(exten, "*72")) { 10035 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10036 getforward = 1; 10037 memset(exten, 0, sizeof(exten)); 10038 len = 0; 10039 } else if (p->cancallforward && !strcmp(exten, "*73")) { 10040 ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel); 10041 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10042 memset(p->call_forward, 0, sizeof(p->call_forward)); 10043 getforward = 0; 10044 memset(exten, 0, sizeof(exten)); 10045 len = 0; 10046 } else if ((p->transfer || p->canpark) && ast_parking_ext_valid(exten, chan, chan->context) && 10047 p->subs[SUB_THREEWAY].owner && 10048 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 10049 /* This is a three way call, the main call being a real channel, 10050 and we're parking the first call. */ 10051 ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL); 10052 ast_verb(3, "Parking call to '%s'\n", chan->name); 10053 break; 10054 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 10055 ast_verb(3, "Enabling Caller*ID on %s\n", chan->name); 10056 /* Enable Caller*ID if enabled */ 10057 p->hidecallerid = 0; 10058 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 10059 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10060 if (res) { 10061 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 10062 chan->name, strerror(errno)); 10063 } 10064 len = 0; 10065 memset(exten, 0, sizeof(exten)); 10066 timeout = firstdigittimeout; 10067 } else if (!strcmp(exten, "*0")) { 10068 struct ast_channel *nbridge = 10069 p->subs[SUB_THREEWAY].owner; 10070 struct dahdi_pvt *pbridge = NULL; 10071 /* set up the private struct of the bridged one, if any */ 10072 if (nbridge && ast_bridged_channel(nbridge)) 10073 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 10074 if (nbridge && pbridge && 10075 (nbridge->tech == &dahdi_tech) && 10076 (ast_bridged_channel(nbridge)->tech == &dahdi_tech) && 10077 ISTRUNK(pbridge)) { 10078 int func = DAHDI_FLASH; 10079 /* Clear out the dial buffer */ 10080 p->dop.dialstr[0] = '\0'; 10081 /* flash hookswitch */ 10082 if ((ioctl(pbridge->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 10083 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 10084 nbridge->name, strerror(errno)); 10085 } 10086 swap_subs(p, SUB_REAL, SUB_THREEWAY); 10087 unalloc_sub(p, SUB_THREEWAY); 10088 p->owner = p->subs[SUB_REAL].owner; 10089 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 10090 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 10091 ast_hangup(chan); 10092 goto quit; 10093 } else { 10094 tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10095 dahdi_wait_event(p->subs[idx].dfd); 10096 tone_zone_play_tone(p->subs[idx].dfd, -1); 10097 swap_subs(p, SUB_REAL, SUB_THREEWAY); 10098 unalloc_sub(p, SUB_THREEWAY); 10099 p->owner = p->subs[SUB_REAL].owner; 10100 ast_hangup(chan); 10101 goto quit; 10102 } 10103 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, 10104 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)) 10105 && ((exten[0] != '*') || (strlen(exten) > 2))) { 10106 ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, 10107 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<Unknown Caller>"), 10108 chan->context); 10109 break; 10110 } 10111 if (!timeout) 10112 timeout = gendigittimeout; 10113 if (len && !ast_ignore_pattern(chan->context, exten)) 10114 tone_zone_play_tone(p->subs[idx].dfd, -1); 10115 } 10116 break; 10117 case SIG_FXSLS: 10118 case SIG_FXSGS: 10119 case SIG_FXSKS: 10120 /* check for SMDI messages */ 10121 if (p->use_smdi && p->smdi_iface) { 10122 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT); 10123 10124 if (smdi_msg != NULL) { 10125 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 10126 10127 if (smdi_msg->type == 'B') 10128 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 10129 else if (smdi_msg->type == 'N') 10130 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 10131 10132 ast_debug(1, "Received SMDI message on %s\n", chan->name); 10133 } else { 10134 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 10135 } 10136 } 10137 10138 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 10139 number = smdi_msg->calling_st; 10140 10141 /* If we want caller id, we're in a prering state due to a polarity reversal 10142 * and we're set to use a polarity reversal to trigger the start of caller id, 10143 * grab the caller id and wait for ringing to start... */ 10144 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && 10145 (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_POLARITY_IN || p->cid_start == CID_START_DTMF_NOALERT))) { 10146 /* If set to use DTMF CID signalling, listen for DTMF */ 10147 if (p->cid_signalling == CID_SIG_DTMF) { 10148 int k = 0; 10149 cs = NULL; 10150 ast_debug(1, "Receiving DTMF cid on channel %s\n", chan->name); 10151 dahdi_setlinear(p->subs[idx].dfd, 0); 10152 /* 10153 * We are the only party interested in the Rx stream since 10154 * we have not answered yet. We don't need or even want DTMF 10155 * emulation. The DTMF digits can come so fast that emulation 10156 * can drop some of them. 10157 */ 10158 ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); 10159 res = 4000;/* This is a typical OFF time between rings. */ 10160 for (;;) { 10161 struct ast_frame *f; 10162 res = ast_waitfor(chan, res); 10163 if (res <= 0) { 10164 /* 10165 * We do not need to restore the dahdi_setlinear() 10166 * or AST_FLAG_END_DTMF_ONLY flag settings since we 10167 * are hanging up the channel. 10168 */ 10169 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 10170 "Exiting simple switch\n"); 10171 ast_hangup(chan); 10172 goto quit; 10173 } 10174 f = ast_read(chan); 10175 if (!f) 10176 break; 10177 if (f->frametype == AST_FRAME_DTMF) { 10178 if (k < ARRAY_LEN(dtmfbuf) - 1) { 10179 dtmfbuf[k++] = f->subclass.integer; 10180 } 10181 ast_debug(1, "CID got digit '%c'\n", f->subclass.integer); 10182 res = 4000;/* This is a typical OFF time between rings. */ 10183 } 10184 ast_frfree(f); 10185 if (chan->_state == AST_STATE_RING || 10186 chan->_state == AST_STATE_RINGING) 10187 break; /* Got ring */ 10188 } 10189 ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); 10190 dtmfbuf[k] = '\0'; 10191 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10192 /* Got cid and ring. */ 10193 ast_debug(1, "CID got string '%s'\n", dtmfbuf); 10194 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 10195 ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags); 10196 /* If first byte is NULL, we have no cid */ 10197 if (!ast_strlen_zero(dtmfcid)) 10198 number = dtmfcid; 10199 else 10200 number = NULL; 10201 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 10202 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 10203 cs = callerid_new(p->cid_signalling); 10204 if (cs) { 10205 samples = 0; 10206 #if 1 10207 bump_gains(p); 10208 #endif 10209 /* Take out of linear mode for Caller*ID processing */ 10210 dahdi_setlinear(p->subs[idx].dfd, 0); 10211 10212 /* First we wait and listen for the Caller*ID */ 10213 for (;;) { 10214 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10215 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10216 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10217 callerid_free(cs); 10218 ast_hangup(chan); 10219 goto quit; 10220 } 10221 if (i & DAHDI_IOMUX_SIGEVENT) { 10222 res = dahdi_get_event(p->subs[idx].dfd); 10223 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10224 if (res == DAHDI_EVENT_NOALARM) { 10225 p->inalarm = 0; 10226 } 10227 10228 if (p->cid_signalling == CID_SIG_V23_JP) { 10229 if (res == DAHDI_EVENT_RINGBEGIN) { 10230 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 10231 usleep(1); 10232 } 10233 } else { 10234 res = 0; 10235 break; 10236 } 10237 } else if (i & DAHDI_IOMUX_READ) { 10238 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10239 if (res < 0) { 10240 if (errno != ELAST) { 10241 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10242 callerid_free(cs); 10243 ast_hangup(chan); 10244 goto quit; 10245 } 10246 break; 10247 } 10248 samples += res; 10249 10250 if (p->cid_signalling == CID_SIG_V23_JP) { 10251 res = callerid_feed_jp(cs, buf, res, AST_LAW(p)); 10252 } else { 10253 res = callerid_feed(cs, buf, res, AST_LAW(p)); 10254 } 10255 if (res < 0) { 10256 /* 10257 * The previous diagnostic message output likely 10258 * explains why it failed. 10259 */ 10260 ast_log(LOG_WARNING, 10261 "Failed to decode CallerID on channel '%s'\n", 10262 chan->name); 10263 break; 10264 } else if (res) 10265 break; 10266 else if (samples > (8000 * 10)) 10267 break; 10268 } 10269 } 10270 if (res == 1) { 10271 callerid_get(cs, &name, &number, &flags); 10272 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 10273 } 10274 10275 if (p->cid_signalling == CID_SIG_V23_JP) { 10276 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 10277 usleep(1); 10278 } 10279 10280 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 10281 res = 4000;/* This is a typical OFF time between rings. */ 10282 for (;;) { 10283 struct ast_frame *f; 10284 res = ast_waitfor(chan, res); 10285 if (res <= 0) { 10286 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 10287 "Exiting simple switch\n"); 10288 ast_hangup(chan); 10289 goto quit; 10290 } 10291 if (!(f = ast_read(chan))) { 10292 ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n"); 10293 ast_hangup(chan); 10294 goto quit; 10295 } 10296 ast_frfree(f); 10297 if (chan->_state == AST_STATE_RING || 10298 chan->_state == AST_STATE_RINGING) 10299 break; /* Got ring */ 10300 } 10301 10302 /* We must have a ring by now, so, if configured, lets try to listen for 10303 * distinctive ringing */ 10304 if (p->usedistinctiveringdetection) { 10305 len = 0; 10306 distMatches = 0; 10307 /* Clear the current ring data array so we don't have old data in it. */ 10308 for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++) 10309 curRingData[receivedRingT] = 0; 10310 receivedRingT = 0; 10311 counter = 0; 10312 counter1 = 0; 10313 /* Check to see if context is what it should be, if not set to be. */ 10314 if (strcmp(p->context,p->defcontext) != 0) { 10315 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 10316 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 10317 } 10318 10319 for (;;) { 10320 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10321 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10322 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10323 callerid_free(cs); 10324 ast_hangup(chan); 10325 goto quit; 10326 } 10327 if (i & DAHDI_IOMUX_SIGEVENT) { 10328 res = dahdi_get_event(p->subs[idx].dfd); 10329 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10330 if (res == DAHDI_EVENT_NOALARM) { 10331 p->inalarm = 0; 10332 } 10333 res = 0; 10334 /* Let us detect distinctive ring */ 10335 10336 curRingData[receivedRingT] = p->ringt; 10337 10338 if (p->ringt < p->ringt_base/2) 10339 break; 10340 /* Increment the ringT counter so we can match it against 10341 values in chan_dahdi.conf for distinctive ring */ 10342 if (++receivedRingT == ARRAY_LEN(curRingData)) 10343 break; 10344 } else if (i & DAHDI_IOMUX_READ) { 10345 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10346 if (res < 0) { 10347 if (errno != ELAST) { 10348 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10349 callerid_free(cs); 10350 ast_hangup(chan); 10351 goto quit; 10352 } 10353 break; 10354 } 10355 if (p->ringt > 0) { 10356 if (!(--p->ringt)) { 10357 res = -1; 10358 break; 10359 } 10360 } 10361 } 10362 } 10363 /* this only shows up if you have n of the dring patterns filled in */ 10364 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 10365 for (counter = 0; counter < 3; counter++) { 10366 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this 10367 channel */ 10368 distMatches = 0; 10369 for (counter1 = 0; counter1 < 3; counter1++) { 10370 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 10371 if (p->drings.ringnum[counter].ring[counter1] == -1) { 10372 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 10373 curRingData[counter1]); 10374 distMatches++; 10375 } else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 10376 curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 10377 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 10378 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 10379 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 10380 distMatches++; 10381 } 10382 } 10383 10384 if (distMatches == 3) { 10385 /* The ring matches, set the context to whatever is for distinctive ring.. */ 10386 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 10387 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 10388 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 10389 break; 10390 } 10391 } 10392 } 10393 /* Restore linear mode (if appropriate) for Caller*ID processing */ 10394 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10395 #if 1 10396 restore_gains(p); 10397 #endif 10398 } else 10399 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 10400 } else { 10401 ast_log(LOG_WARNING, "Channel %s in prering " 10402 "state, but I have nothing to do. " 10403 "Terminating simple switch, should be " 10404 "restarted by the actual ring.\n", 10405 chan->name); 10406 ast_hangup(chan); 10407 goto quit; 10408 } 10409 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 10410 if (p->cid_signalling == CID_SIG_DTMF) { 10411 int k = 0; 10412 cs = NULL; 10413 dahdi_setlinear(p->subs[idx].dfd, 0); 10414 res = 2000; 10415 for (;;) { 10416 struct ast_frame *f; 10417 res = ast_waitfor(chan, res); 10418 if (res <= 0) { 10419 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 10420 "Exiting simple switch\n"); 10421 ast_hangup(chan); 10422 return NULL; 10423 } 10424 f = ast_read(chan); 10425 if (f->frametype == AST_FRAME_DTMF) { 10426 dtmfbuf[k++] = f->subclass.integer; 10427 ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass.integer); 10428 res = 2000; 10429 } 10430 ast_frfree(f); 10431 10432 if (p->ringt_base == p->ringt) 10433 break; 10434 } 10435 dtmfbuf[k] = '\0'; 10436 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10437 /* Got cid and ring. */ 10438 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 10439 ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 10440 dtmfcid, flags); 10441 /* If first byte is NULL, we have no cid */ 10442 if (!ast_strlen_zero(dtmfcid)) 10443 number = dtmfcid; 10444 else 10445 number = NULL; 10446 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 10447 } else { 10448 /* FSK Bell202 callerID */ 10449 cs = callerid_new(p->cid_signalling); 10450 if (cs) { 10451 #if 1 10452 bump_gains(p); 10453 #endif 10454 samples = 0; 10455 len = 0; 10456 distMatches = 0; 10457 /* Clear the current ring data array so we don't have old data in it. */ 10458 for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++) 10459 curRingData[receivedRingT] = 0; 10460 receivedRingT = 0; 10461 counter = 0; 10462 counter1 = 0; 10463 /* Check to see if context is what it should be, if not set to be. */ 10464 if (strcmp(p->context,p->defcontext) != 0) { 10465 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 10466 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 10467 } 10468 10469 /* Take out of linear mode for Caller*ID processing */ 10470 dahdi_setlinear(p->subs[idx].dfd, 0); 10471 for (;;) { 10472 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10473 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10474 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10475 callerid_free(cs); 10476 ast_hangup(chan); 10477 goto quit; 10478 } 10479 if (i & DAHDI_IOMUX_SIGEVENT) { 10480 res = dahdi_get_event(p->subs[idx].dfd); 10481 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10482 if (res == DAHDI_EVENT_NOALARM) { 10483 p->inalarm = 0; 10484 } 10485 /* If we get a PR event, they hung up while processing calerid */ 10486 if ( res == DAHDI_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) { 10487 ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel); 10488 p->polarity = POLARITY_IDLE; 10489 callerid_free(cs); 10490 ast_hangup(chan); 10491 goto quit; 10492 } 10493 res = 0; 10494 /* Let us detect callerid when the telco uses distinctive ring */ 10495 10496 curRingData[receivedRingT] = p->ringt; 10497 10498 if (p->ringt < p->ringt_base/2) 10499 break; 10500 /* Increment the ringT counter so we can match it against 10501 values in chan_dahdi.conf for distinctive ring */ 10502 if (++receivedRingT == ARRAY_LEN(curRingData)) 10503 break; 10504 } else if (i & DAHDI_IOMUX_READ) { 10505 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10506 if (res < 0) { 10507 if (errno != ELAST) { 10508 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10509 callerid_free(cs); 10510 ast_hangup(chan); 10511 goto quit; 10512 } 10513 break; 10514 } 10515 if (p->ringt > 0) { 10516 if (!(--p->ringt)) { 10517 res = -1; 10518 break; 10519 } 10520 } 10521 samples += res; 10522 res = callerid_feed(cs, buf, res, AST_LAW(p)); 10523 if (res < 0) { 10524 /* 10525 * The previous diagnostic message output likely 10526 * explains why it failed. 10527 */ 10528 ast_log(LOG_WARNING, 10529 "Failed to decode CallerID on channel '%s'\n", 10530 chan->name); 10531 break; 10532 } else if (res) 10533 break; 10534 else if (samples > (8000 * 10)) 10535 break; 10536 } 10537 } 10538 if (res == 1) { 10539 callerid_get(cs, &name, &number, &flags); 10540 ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 10541 } 10542 if (distinctiveringaftercid == 1) { 10543 /* Clear the current ring data array so we don't have old data in it. */ 10544 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) { 10545 curRingData[receivedRingT] = 0; 10546 } 10547 receivedRingT = 0; 10548 ast_verb(3, "Detecting post-CID distinctive ring\n"); 10549 for (;;) { 10550 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10551 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10552 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10553 callerid_free(cs); 10554 ast_hangup(chan); 10555 goto quit; 10556 } 10557 if (i & DAHDI_IOMUX_SIGEVENT) { 10558 res = dahdi_get_event(p->subs[idx].dfd); 10559 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10560 if (res == DAHDI_EVENT_NOALARM) { 10561 p->inalarm = 0; 10562 } 10563 res = 0; 10564 /* Let us detect callerid when the telco uses distinctive ring */ 10565 10566 curRingData[receivedRingT] = p->ringt; 10567 10568 if (p->ringt < p->ringt_base/2) 10569 break; 10570 /* Increment the ringT counter so we can match it against 10571 values in chan_dahdi.conf for distinctive ring */ 10572 if (++receivedRingT == ARRAY_LEN(curRingData)) 10573 break; 10574 } else if (i & DAHDI_IOMUX_READ) { 10575 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10576 if (res < 0) { 10577 if (errno != ELAST) { 10578 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10579 callerid_free(cs); 10580 ast_hangup(chan); 10581 goto quit; 10582 } 10583 break; 10584 } 10585 if (p->ringt > 0) { 10586 if (!(--p->ringt)) { 10587 res = -1; 10588 break; 10589 } 10590 } 10591 } 10592 } 10593 } 10594 if (p->usedistinctiveringdetection) { 10595 /* this only shows up if you have n of the dring patterns filled in */ 10596 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 10597 10598 for (counter = 0; counter < 3; counter++) { 10599 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this 10600 channel */ 10601 /* this only shows up if you have n of the dring patterns filled in */ 10602 ast_verb(3, "Checking %d,%d,%d\n", 10603 p->drings.ringnum[counter].ring[0], 10604 p->drings.ringnum[counter].ring[1], 10605 p->drings.ringnum[counter].ring[2]); 10606 distMatches = 0; 10607 for (counter1 = 0; counter1 < 3; counter1++) { 10608 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 10609 if (p->drings.ringnum[counter].ring[counter1] == -1) { 10610 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 10611 curRingData[counter1]); 10612 distMatches++; 10613 } 10614 else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 10615 curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 10616 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 10617 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 10618 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 10619 distMatches++; 10620 } 10621 } 10622 if (distMatches == 3) { 10623 /* The ring matches, set the context to whatever is for distinctive ring.. */ 10624 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 10625 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 10626 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 10627 break; 10628 } 10629 } 10630 } 10631 /* Restore linear mode (if appropriate) for Caller*ID processing */ 10632 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10633 #if 1 10634 restore_gains(p); 10635 #endif 10636 if (res < 0) { 10637 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 10638 } 10639 } else 10640 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 10641 } 10642 } else 10643 cs = NULL; 10644 10645 if (number) 10646 ast_shrink_phone_number(number); 10647 ast_set_callerid(chan, number, name, number); 10648 10649 if (smdi_msg) 10650 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 10651 10652 if (cs) 10653 callerid_free(cs); 10654 10655 my_handle_notify_message(chan, p, flags, -1); 10656 10657 ast_setstate(chan, AST_STATE_RING); 10658 chan->rings = 1; 10659 p->ringt = p->ringt_base; 10660 res = ast_pbx_run(chan); 10661 if (res) { 10662 ast_hangup(chan); 10663 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 10664 } 10665 goto quit; 10666 default: 10667 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 10668 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10669 if (res < 0) 10670 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 10671 } 10672 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10673 if (res < 0) 10674 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 10675 ast_hangup(chan); 10676 quit: 10677 ast_mutex_lock(&ss_thread_lock); 10678 ss_thread_count--; 10679 ast_cond_signal(&ss_thread_complete); 10680 ast_mutex_unlock(&ss_thread_lock); 10681 return NULL; 10682 }
static int analog_tone_to_dahditone | ( | enum analog_tone | tone | ) | [static] |
Definition at line 1600 of file chan_dahdi.c.
References ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALRECALL, ANALOG_TONE_DIALTONE, ANALOG_TONE_INFO, ANALOG_TONE_RINGTONE, and ANALOG_TONE_STUTTER.
Referenced by my_play_tone().
01601 { 01602 switch (tone) { 01603 case ANALOG_TONE_RINGTONE: 01604 return DAHDI_TONE_RINGTONE; 01605 case ANALOG_TONE_STUTTER: 01606 return DAHDI_TONE_STUTTER; 01607 case ANALOG_TONE_CONGESTION: 01608 return DAHDI_TONE_CONGESTION; 01609 case ANALOG_TONE_DIALTONE: 01610 return DAHDI_TONE_DIALTONE; 01611 case ANALOG_TONE_DIALRECALL: 01612 return DAHDI_TONE_DIALRECALL; 01613 case ANALOG_TONE_INFO: 01614 return DAHDI_TONE_INFO; 01615 default: 01616 return -1; 01617 } 01618 }
static int analogsub_to_dahdisub | ( | enum analog_sub | analogsub | ) | [static] |
Definition at line 1620 of file chan_dahdi.c.
References ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, ast_log(), LOG_ERROR, SUB_CALLWAIT, SUB_REAL, and SUB_THREEWAY.
Referenced by my_allocate_sub(), my_conf_add(), my_conf_del(), my_dial_digits(), my_get_sub_fd(), my_handle_dtmf(), my_is_dialing(), my_new_analog_ast_channel(), my_play_tone(), my_set_inthreeway(), my_set_linear_mode(), my_swap_subchannels(), my_unallocate_sub(), and my_wink().
01621 { 01622 int index; 01623 01624 switch (analogsub) { 01625 case ANALOG_SUB_REAL: 01626 index = SUB_REAL; 01627 break; 01628 case ANALOG_SUB_CALLWAIT: 01629 index = SUB_CALLWAIT; 01630 break; 01631 case ANALOG_SUB_THREEWAY: 01632 index = SUB_THREEWAY; 01633 break; 01634 default: 01635 ast_log(LOG_ERROR, "Unidentified sub!\n"); 01636 index = SUB_REAL; 01637 } 01638 01639 return index; 01640 }
AST_DATA_STRUCTURE | ( | dahdi_pvt | , | |
DATA_EXPORT_DAHDI_PVT | ||||
) |
static int attempt_transfer | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7420 of file chan_dahdi.c.
References ast_channel::_softhangup, ast_channel::_state, ast_bridged_channel(), ast_channel_masquerade(), ast_channel_unlock, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_debug, ast_indicate(), ast_log(), ast_queue_control(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_RINGING, dahdi_subchannel::dfd, ast_channel::name, dahdi_subchannel::owner, SUB_REAL, SUB_THREEWAY, dahdi_pvt::subs, swap_subs(), and unalloc_sub().
Referenced by close_call(), dahdi_handle_event(), handle_request(), and local_attended_transfer().
07421 { 07422 /* In order to transfer, we need at least one of the channels to 07423 actually be in a call bridge. We can't conference two applications 07424 together (but then, why would we want to?) */ 07425 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 07426 /* The three-way person we're about to transfer to could still be in MOH, so 07427 stop if now if appropriate */ 07428 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 07429 ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 07430 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 07431 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 07432 } 07433 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) { 07434 tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, DAHDI_TONE_RINGTONE); 07435 } 07436 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 07437 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 07438 ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name); 07439 return -1; 07440 } 07441 /* Orphan the channel after releasing the lock */ 07442 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 07443 unalloc_sub(p, SUB_THREEWAY); 07444 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 07445 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 07446 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 07447 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 07448 } 07449 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) { 07450 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 07451 } 07452 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 07453 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 07454 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name); 07455 return -1; 07456 } 07457 /* Three-way is now the REAL */ 07458 swap_subs(p, SUB_THREEWAY, SUB_REAL); 07459 ast_channel_unlock(p->subs[SUB_REAL].owner); 07460 unalloc_sub(p, SUB_THREEWAY); 07461 /* Tell the caller not to hangup */ 07462 return 1; 07463 } else { 07464 ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n", 07465 p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name); 07466 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 07467 return -1; 07468 } 07469 return 0; 07470 }
static int available | ( | struct dahdi_pvt ** | pvt, | |
int | is_specific_channel | |||
) | [static] |
Definition at line 12829 of file chan_dahdi.c.
References analog_available(), analog_lib_handles(), sig_pri_chan::chan_pvt, dahdi_pvt::inalarm, dahdi_pvt::locallyblocked, dahdi_pvt::mfcr2, dahdi_pvt::mfcr2call, dahdi_pvt::oprmode, dahdi_pvt::owner, dahdi_pvt::radio, dahdi_pvt::remotelyblocked, dahdi_pvt::sig, sig_pri_available(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, and sig_ss7_available().
Referenced by __ast_string_field_ptr_build_va(), ast_logger_register_level(), and dahdi_request().
12830 { 12831 struct dahdi_pvt *p = *pvt; 12832 12833 if (p->inalarm) 12834 return 0; 12835 12836 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) 12837 return analog_available(p->sig_pvt); 12838 12839 switch (p->sig) { 12840 #if defined(HAVE_PRI) 12841 case SIG_PRI_LIB_HANDLE_CASES: 12842 { 12843 struct sig_pri_chan *pvt_chan; 12844 int res; 12845 12846 pvt_chan = p->sig_pvt; 12847 res = sig_pri_available(&pvt_chan, is_specific_channel); 12848 *pvt = pvt_chan->chan_pvt; 12849 return res; 12850 } 12851 #endif /* defined(HAVE_PRI) */ 12852 #if defined(HAVE_SS7) 12853 case SIG_SS7: 12854 return sig_ss7_available(p->sig_pvt); 12855 #endif /* defined(HAVE_SS7) */ 12856 default: 12857 break; 12858 } 12859 12860 if (p->locallyblocked || p->remotelyblocked) { 12861 return 0; 12862 } 12863 12864 /* If no owner definitely available */ 12865 if (!p->owner) { 12866 #ifdef HAVE_OPENR2 12867 /* Trust MFC/R2 */ 12868 if (p->mfcr2) { 12869 if (p->mfcr2call) { 12870 return 0; 12871 } else { 12872 return 1; 12873 } 12874 } 12875 #endif 12876 return 1; 12877 } 12878 12879 return 0; 12880 }
static int build_channels | ( | struct dahdi_chan_conf * | conf, | |
const char * | value, | |||
int | reload, | |||
int | lineno, | |||
int * | found_pseudo | |||
) | [static] |
Definition at line 16308 of file chan_dahdi.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), ast_verb, dahdi_chan_conf::chan, CHAN_PSEUDO, device2chan(), dahdi_chan_conf::ignore_failed_channels, dahdi_chan_conf::is_sig_auto, mkintf(), parse_spanchan(), dahdi_pvt::sig, sig2str, and strsep().
Referenced by process_dahdi().
16309 { 16310 char *c, *chan; 16311 char *subdir; 16312 int x, start, finish; 16313 struct dahdi_pvt *tmp; 16314 16315 if ((reload == 0) && (conf->chan.sig < 0) && !conf->is_sig_auto) { 16316 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 16317 return -1; 16318 } 16319 16320 c = ast_strdupa(value); 16321 c = parse_spanchan(c, &subdir); 16322 16323 while ((chan = strsep(&c, ","))) { 16324 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) { 16325 /* Range */ 16326 } else if (sscanf(chan, "%30d", &start)) { 16327 /* Just one */ 16328 finish = start; 16329 } else if (!strcasecmp(chan, "pseudo")) { 16330 finish = start = CHAN_PSEUDO; 16331 if (found_pseudo) 16332 *found_pseudo = 1; 16333 } else { 16334 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan); 16335 return -1; 16336 } 16337 if (finish < start) { 16338 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 16339 x = finish; 16340 finish = start; 16341 start = x; 16342 } 16343 16344 for (x = start; x <= finish; x++) { 16345 char fn[PATH_MAX]; 16346 int real_channel = x; 16347 16348 if (!ast_strlen_zero(subdir)) { 16349 real_channel = device2chan(subdir, x, fn, sizeof(fn)); 16350 if (real_channel < 0) { 16351 if (conf->ignore_failed_channels) { 16352 ast_log(LOG_WARNING, "Failed configuring %s!%d, (got %d). But moving on to others.\n", 16353 subdir, x, real_channel); 16354 continue; 16355 } else { 16356 ast_log(LOG_ERROR, "Failed configuring %s!%d, (got %d).\n", 16357 subdir, x, real_channel); 16358 return -1; 16359 } 16360 } 16361 } 16362 tmp = mkintf(real_channel, conf, reload); 16363 16364 if (tmp) { 16365 ast_verb(3, "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", real_channel, sig2str(tmp->sig)); 16366 } else { 16367 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n", 16368 (reload == 1) ? "reconfigure" : "register", value); 16369 return -1; 16370 } 16371 } 16372 } 16373 16374 return 0; 16375 }
static int bump_gains | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4984 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::cid_rxgain, errno, dahdi_pvt::law, LOG_WARNING, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, set_actual_gain(), SUB_REAL, dahdi_pvt::subs, dahdi_pvt::txdrc, and dahdi_pvt::txgain.
Referenced by analog_ss_thread(), mwi_thread(), and my_start_cid_detect().
04985 { 04986 int res; 04987 04988 /* Bump receive gain by value stored in cid_rxgain */ 04989 res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain + p->cid_rxgain, p->txgain, p->rxdrc, p->txdrc, p->law); 04990 if (res) { 04991 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno)); 04992 return -1; 04993 } 04994 04995 return 0; 04996 }
static int calc_energy | ( | const unsigned char * | buf, | |
int | len, | |||
format_t | law | |||
) | [static] |
Definition at line 10690 of file chan_dahdi.c.
References AST_ALAW, AST_FORMAT_ULAW, and AST_MULAW.
Referenced by mwi_thread().
10691 { 10692 int x; 10693 int sum = 0; 10694 10695 if (!len) 10696 return 0; 10697 10698 for (x = 0; x < len; x++) 10699 sum += abs(law == AST_FORMAT_ULAW ? AST_MULAW(buf[x]) : AST_ALAW(buf[x])); 10700 10701 return sum / len; 10702 }
static int check_for_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7472 of file chan_dahdi.c.
References ast_log(), ast_verb, dahdi_pvt::channel, dahdi_pvt::confno, errno, dahdi_pvt::master, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_handle_event(), and my_check_for_conference().
07473 { 07474 struct dahdi_confinfo ci; 07475 /* Fine if we already have a master, etc */ 07476 if (p->master || (p->confno > -1)) 07477 return 0; 07478 memset(&ci, 0, sizeof(ci)); 07479 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) { 07480 ast_log(LOG_WARNING, "Failed to get conference info on channel %d: %s\n", p->channel, strerror(errno)); 07481 return 0; 07482 } 07483 /* If we have no master and don't have a confno, then 07484 if we're in a conference, it's probably a MeetMe room or 07485 some such, so don't let us 3-way out! */ 07486 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 07487 ast_verb(3, "Avoiding 3-way call when in an external conference\n"); 07488 return 1; 07489 } 07490 return 0; 07491 }
static char* complete_span_4 | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 13845 of file chan_dahdi.c.
References complete_span_helper().
Referenced by handle_pri_debug(), and handle_pri_show_span().
13846 { 13847 return complete_span_helper(line,word,pos,state,3); 13848 }
static char* complete_span_helper | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
int | rpos | |||
) | [static] |
Definition at line 13824 of file chan_dahdi.c.
References asprintf, ast_log(), errno, dahdi_pri::pri, and pris.
Referenced by complete_span_4().
13825 { 13826 int which, span; 13827 char *ret = NULL; 13828 13829 if (pos != rpos) 13830 return ret; 13831 13832 for (which = span = 0; span < NUM_SPANS; span++) { 13833 if (pris[span].pri.pri && ++which > state) { 13834 if (asprintf(&ret, "%d", span + 1) < 0) { /* user indexes start from 1 */ 13835 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 13836 } 13837 break; 13838 } 13839 } 13840 return ret; 13841 }
static int conf_add | ( | struct dahdi_pvt * | p, | |
struct dahdi_subchannel * | c, | |||
int | index, | |||
int | slavechannel | |||
) | [static] |
Definition at line 4566 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_pvt::confno, dahdi_subchannel::curconf, dahdi_subchannel::dfd, errno, and LOG_WARNING.
Referenced by my_complete_conference_update(), my_conf_add(), and update_conf().
04567 { 04568 /* If the conference already exists, and we're already in it 04569 don't bother doing anything */ 04570 struct dahdi_confinfo zi; 04571 04572 memset(&zi, 0, sizeof(zi)); 04573 zi.chan = 0; 04574 04575 if (slavechannel > 0) { 04576 /* If we have only one slave, do a digital mon */ 04577 zi.confmode = DAHDI_CONF_DIGITALMON; 04578 zi.confno = slavechannel; 04579 } else { 04580 if (!idx) { 04581 /* Real-side and pseudo-side both participate in conference */ 04582 zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER | 04583 DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER; 04584 } else 04585 zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER; 04586 zi.confno = p->confno; 04587 } 04588 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode)) 04589 return 0; 04590 if (c->dfd < 0) 04591 return 0; 04592 if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) { 04593 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno)); 04594 return -1; 04595 } 04596 if (slavechannel < 1) { 04597 p->confno = zi.confno; 04598 } 04599 c->curconf = zi; 04600 ast_debug(1, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno); 04601 return 0; 04602 }
static int conf_del | ( | struct dahdi_pvt * | p, | |
struct dahdi_subchannel * | c, | |||
int | index | |||
) | [static] |
Definition at line 4615 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_subchannel::curconf, dahdi_subchannel::dfd, errno, isourconf(), and LOG_WARNING.
Referenced by dahdi_unlink(), my_conf_del(), and update_conf().
04616 { 04617 struct dahdi_confinfo zi; 04618 if (/* Can't delete if there's no dfd */ 04619 (c->dfd < 0) || 04620 /* Don't delete from the conference if it's not our conference */ 04621 !isourconf(p, c) 04622 /* Don't delete if we don't think it's conferenced at all (implied) */ 04623 ) return 0; 04624 memset(&zi, 0, sizeof(zi)); 04625 if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) { 04626 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno)); 04627 return -1; 04628 } 04629 ast_debug(1, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno); 04630 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 04631 return 0; 04632 }
static struct ast_str* create_channel_name | ( | struct dahdi_pvt * | i, | |
int | is_outgoing, | |||
char * | address | |||
) | [static] |
Definition at line 9233 of file chan_dahdi.c.
References ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strlen_zero(), and CHAN_PSEUDO.
Referenced by dahdi_cc_callback(), and dahdi_new().
09237 { 09238 struct ast_str *chan_name; 09239 int x, y; 09240 09241 /* Create the new channel name tail. */ 09242 if (!(chan_name = ast_str_create(32))) { 09243 return NULL; 09244 } 09245 if (i->channel == CHAN_PSEUDO) { 09246 ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random()); 09247 #if defined(HAVE_PRI) 09248 } else if (i->pri) { 09249 ast_mutex_lock(&i->pri->lock); 09250 y = ++i->pri->new_chan_seq; 09251 if (is_outgoing) { 09252 ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, address, y); 09253 address[0] = '\0'; 09254 } else if (ast_strlen_zero(i->cid_subaddr)) { 09255 /* Put in caller-id number only since there is no subaddress. */ 09256 ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, i->cid_num, y); 09257 } else { 09258 /* Put in caller-id number and subaddress. */ 09259 ast_str_set(&chan_name, 0, "i%d/%s:%s-%x", i->pri->span, i->cid_num, 09260 i->cid_subaddr, y); 09261 } 09262 ast_mutex_unlock(&i->pri->lock); 09263 #endif /* defined(HAVE_PRI) */ 09264 } else { 09265 y = 1; 09266 do { 09267 ast_str_set(&chan_name, 0, "%d-%d", i->channel, y); 09268 for (x = 0; x < 3; ++x) { 09269 if (i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name), 09270 i->subs[x].owner->name + 6)) { 09271 break; 09272 } 09273 } 09274 ++y; 09275 } while (x < 3); 09276 } 09277 return chan_name; 09278 }
static int dahdi_accept_r2_call_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 5841 of file chan_dahdi.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_strlen_zero(), dahdi_tech, f, LOG_DEBUG, parse(), and ast_channel::tech.
Referenced by load_module().
05842 { 05843 /* data is whether to accept with charge or no charge */ 05844 openr2_call_mode_t accept_mode; 05845 int res, timeout, maxloops; 05846 struct ast_frame *f; 05847 struct dahdi_pvt *p; 05848 char *parse; 05849 AST_DECLARE_APP_ARGS(args, 05850 AST_APP_ARG(charge); 05851 ); 05852 05853 if (ast_strlen_zero(data)) { 05854 ast_log(LOG_DEBUG, "No data sent to application!\n"); 05855 return -1; 05856 } 05857 05858 if (chan->tech != &dahdi_tech) { 05859 ast_log(LOG_DEBUG, "Only DAHDI technology accepted!\n"); 05860 return -1; 05861 } 05862 05863 p = (struct dahdi_pvt *)chan->tech_pvt; 05864 if (!p) { 05865 ast_log(LOG_DEBUG, "Unable to find technology private!\n"); 05866 return -1; 05867 } 05868 05869 parse = ast_strdupa(data); 05870 AST_STANDARD_APP_ARGS(args, parse); 05871 05872 if (ast_strlen_zero(args.charge)) { 05873 ast_log(LOG_WARNING, "DAHDIAcceptR2Call requires 'yes' or 'no' for the charge parameter\n"); 05874 return -1; 05875 } 05876 05877 ast_mutex_lock(&p->lock); 05878 if (!p->mfcr2 || !p->mfcr2call) { 05879 ast_mutex_unlock(&p->lock); 05880 ast_log(LOG_DEBUG, "Channel %s does not seems to be an R2 active channel!\n", chan->name); 05881 return -1; 05882 } 05883 05884 if (p->mfcr2_call_accepted) { 05885 ast_mutex_unlock(&p->lock); 05886 ast_log(LOG_DEBUG, "MFC/R2 call already accepted on channel %s!\n", chan->name); 05887 return 0; 05888 } 05889 accept_mode = ast_true(args.charge) ? OR2_CALL_WITH_CHARGE : OR2_CALL_NO_CHARGE; 05890 if (openr2_chan_accept_call(p->r2chan, accept_mode)) { 05891 ast_mutex_unlock(&p->lock); 05892 ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n"); 05893 return -1; 05894 } 05895 ast_mutex_unlock(&p->lock); 05896 05897 res = 0; 05898 timeout = 100; 05899 maxloops = 50; /* wait up to 5 seconds */ 05900 /* we need to read() until the call is accepted */ 05901 while (maxloops > 0) { 05902 maxloops--; 05903 if (ast_check_hangup(chan)) { 05904 break; 05905 } 05906 res = ast_waitfor(chan, timeout); 05907 if (res < 0) { 05908 ast_log(LOG_DEBUG, "ast_waitfor failed on channel %s, going out ...\n", chan->name); 05909 res = -1; 05910 break; 05911 } 05912 if (res == 0) { 05913 continue; 05914 } 05915 f = ast_read(chan); 05916 if (!f) { 05917 ast_log(LOG_DEBUG, "No frame read on channel %s, going out ...\n", chan->name); 05918 res = -1; 05919 break; 05920 } 05921 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) { 05922 ast_log(LOG_DEBUG, "Got HANGUP frame on channel %s, going out ...\n", chan->name); 05923 ast_frfree(f); 05924 res = -1; 05925 break; 05926 } 05927 ast_frfree(f); 05928 ast_mutex_lock(&p->lock); 05929 if (p->mfcr2_call_accepted) { 05930 ast_mutex_unlock(&p->lock); 05931 ast_log(LOG_DEBUG, "Accepted MFC/R2 call!\n"); 05932 break; 05933 } 05934 ast_mutex_unlock(&p->lock); 05935 } 05936 if (res == -1) { 05937 ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n"); 05938 } 05939 return res; 05940 }
static int dahdi_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 6396 of file chan_dahdi.c.
References analog_answer(), analog_lib_handles(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_UP, dahdi_pvt::channel, dahdi_get_index, dahdi_r2_answer(), dahdi_pvt::lock, LOG_DEBUG, LOG_WARNING, dahdi_pvt::mfcr2_answer_pending, dahdi_pvt::mfcr2_call_accepted, dahdi_pvt::mfcr2_charge_calls, dahdi_pvt::oprmode, dahdi_pvt::r2chan, dahdi_pvt::radio, dahdi_pvt::sig, SIG_MFCR2, sig_pri_answer(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, sig_ss7_answer(), SUB_REAL, and ast_channel::tech_pvt.
06397 { 06398 struct dahdi_pvt *p = ast->tech_pvt; 06399 int res = 0; 06400 int idx; 06401 ast_setstate(ast, AST_STATE_UP);/*! \todo XXX this is redundantly set by the analog and PRI submodules! */ 06402 ast_mutex_lock(&p->lock); 06403 idx = dahdi_get_index(ast, p, 0); 06404 if (idx < 0) 06405 idx = SUB_REAL; 06406 /* nothing to do if a radio channel */ 06407 if ((p->radio || (p->oprmode < 0))) { 06408 ast_mutex_unlock(&p->lock); 06409 return 0; 06410 } 06411 06412 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 06413 res = analog_answer(p->sig_pvt, ast); 06414 ast_mutex_unlock(&p->lock); 06415 return res; 06416 } 06417 06418 switch (p->sig) { 06419 #if defined(HAVE_PRI) 06420 case SIG_PRI_LIB_HANDLE_CASES: 06421 res = sig_pri_answer(p->sig_pvt, ast); 06422 break; 06423 #endif /* defined(HAVE_PRI) */ 06424 #if defined(HAVE_SS7) 06425 case SIG_SS7: 06426 res = sig_ss7_answer(p->sig_pvt, ast); 06427 break; 06428 #endif /* defined(HAVE_SS7) */ 06429 #ifdef HAVE_OPENR2 06430 case SIG_MFCR2: 06431 if (!p->mfcr2_call_accepted) { 06432 /* The call was not accepted on offer nor the user, so it must be accepted now before answering, 06433 openr2_chan_answer_call will be called when the callback on_call_accepted is executed */ 06434 p->mfcr2_answer_pending = 1; 06435 if (p->mfcr2_charge_calls) { 06436 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with charge before answering on chan %d\n", p->channel); 06437 openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE); 06438 } else { 06439 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with no charge before answering on chan %d\n", p->channel); 06440 openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE); 06441 } 06442 } else { 06443 ast_log(LOG_DEBUG, "Answering MFC/R2 call on chan %d\n", p->channel); 06444 dahdi_r2_answer(p); 06445 } 06446 break; 06447 #endif 06448 case 0: 06449 ast_mutex_unlock(&p->lock); 06450 return 0; 06451 default: 06452 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 06453 res = -1; 06454 break; 06455 } 06456 ast_mutex_unlock(&p->lock); 06457 return res; 06458 }
static openr2_call_disconnect_cause_t dahdi_ast_cause_to_r2_cause | ( | int | cause | ) | [static] |
Definition at line 5942 of file chan_dahdi.c.
References AST_CAUSE_CALL_REJECTED, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_INTERWORKING, AST_CAUSE_NETWORK_OUT_OF_ORDER, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, ast_log(), and LOG_DEBUG.
Referenced by dahdi_hangup().
05943 { 05944 openr2_call_disconnect_cause_t r2cause = OR2_CAUSE_NORMAL_CLEARING; 05945 switch (cause) { 05946 case AST_CAUSE_USER_BUSY: 05947 case AST_CAUSE_CALL_REJECTED: 05948 case AST_CAUSE_INTERWORKING: /* I don't know wtf is this but is used sometimes when ekiga rejects a call */ 05949 r2cause = OR2_CAUSE_BUSY_NUMBER; 05950 break; 05951 05952 case AST_CAUSE_NORMAL_CIRCUIT_CONGESTION: 05953 case AST_CAUSE_SWITCH_CONGESTION: 05954 r2cause = OR2_CAUSE_NETWORK_CONGESTION; 05955 break; 05956 05957 case AST_CAUSE_UNALLOCATED: 05958 r2cause = OR2_CAUSE_UNALLOCATED_NUMBER; 05959 break; 05960 05961 case AST_CAUSE_NETWORK_OUT_OF_ORDER: 05962 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 05963 r2cause = OR2_CAUSE_OUT_OF_ORDER; 05964 break; 05965 05966 case AST_CAUSE_NO_ANSWER: 05967 case AST_CAUSE_NO_USER_RESPONSE: 05968 r2cause = OR2_CAUSE_NO_ANSWER; 05969 break; 05970 05971 default: 05972 r2cause = OR2_CAUSE_NORMAL_CLEARING; 05973 break; 05974 } 05975 ast_log(LOG_DEBUG, "ast cause %d resulted in openr2 cause %d/%s\n", 05976 cause, r2cause, openr2_proto_get_disconnect_string(r2cause)); 05977 return r2cause; 05978 }
static enum ast_bridge_result dahdi_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 6997 of file chan_dahdi.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_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_debug, 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_verb, ast_waitfor_n(), ast_write(), sig_pri_chan::call, dahdi_pvt::callwaiting, dahdi_pvt::callwaitingcallerid, dahdi_pvt::channel, CHANNEL_DEADLOCK_AVOIDANCE, dahdi_disable_ec(), dahdi_enable_ec(), dahdi_get_index, dahdi_link(), dahdi_sig_pri_lib_handles(), dahdi_unlink(), dahdi_subchannel::dfd, disable_dtmf_detect(), dahdi_pvt::echocanbridged, enable_dtmf_detect(), f, ast_channel::fds, dahdi_pvt::inconference, dahdi_subchannel::inthreeway, sig_pri_span::lock, dahdi_pvt::lock, LOG_NOTICE, ast_channel::name, dahdi_subchannel::owner, dahdi_pvt::owner, dahdi_pvt::pri, dahdi_pvt::pulsedial, dahdi_pvt::sig, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, subnames, dahdi_pvt::subs, t1, ast_channel::tech_pvt, sig_pri_span::transfer, and update_conf().
06998 { 06999 struct ast_channel *who; 07000 struct dahdi_pvt *p0, *p1, *op0, *op1; 07001 struct dahdi_pvt *master = NULL, *slave = NULL; 07002 struct ast_frame *f; 07003 int inconf = 0; 07004 int nothingok = 1; 07005 int ofd0, ofd1; 07006 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 07007 int os0 = -1, os1 = -1; 07008 int priority = 0; 07009 struct ast_channel *oc0, *oc1; 07010 enum ast_bridge_result res; 07011 #ifdef PRI_2BCT 07012 int triedtopribridge = 0; 07013 q931_call *q931c0; 07014 q931_call *q931c1; 07015 #endif 07016 07017 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 07018 There is code below to handle it properly until DTMF is actually seen, 07019 but due to currently unresolved issues it's ignored... 07020 */ 07021 07022 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 07023 return AST_BRIDGE_FAILED_NOWARN; 07024 07025 ast_channel_lock(c0); 07026 while (ast_channel_trylock(c1)) { 07027 CHANNEL_DEADLOCK_AVOIDANCE(c0); 07028 } 07029 07030 p0 = c0->tech_pvt; 07031 p1 = c1->tech_pvt; 07032 /* cant do pseudo-channels here */ 07033 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 07034 ast_channel_unlock(c0); 07035 ast_channel_unlock(c1); 07036 return AST_BRIDGE_FAILED_NOWARN; 07037 } 07038 07039 oi0 = dahdi_get_index(c0, p0, 0); 07040 oi1 = dahdi_get_index(c1, p1, 0); 07041 if ((oi0 < 0) || (oi1 < 0)) { 07042 ast_channel_unlock(c0); 07043 ast_channel_unlock(c1); 07044 return AST_BRIDGE_FAILED; 07045 } 07046 07047 op0 = p0 = c0->tech_pvt; 07048 op1 = p1 = c1->tech_pvt; 07049 ofd0 = c0->fds[0]; 07050 ofd1 = c1->fds[0]; 07051 oc0 = p0->owner; 07052 oc1 = p1->owner; 07053 07054 if (ast_mutex_trylock(&p0->lock)) { 07055 /* Don't block, due to potential for deadlock */ 07056 ast_channel_unlock(c0); 07057 ast_channel_unlock(c1); 07058 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 07059 return AST_BRIDGE_RETRY; 07060 } 07061 if (ast_mutex_trylock(&p1->lock)) { 07062 /* Don't block, due to potential for deadlock */ 07063 ast_mutex_unlock(&p0->lock); 07064 ast_channel_unlock(c0); 07065 ast_channel_unlock(c1); 07066 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 07067 return AST_BRIDGE_RETRY; 07068 } 07069 07070 if ((p0->callwaiting && p0->callwaitingcallerid) 07071 || (p1->callwaiting && p1->callwaitingcallerid)) { 07072 /* 07073 * Call Waiting Caller ID requires DTMF detection to know if it 07074 * can send the CID spill. 07075 * 07076 * For now, don't attempt to native bridge if either channel 07077 * needs DTMF detection. There is code below to handle it 07078 * properly until DTMF is actually seen, but due to currently 07079 * unresolved issues it's ignored... 07080 */ 07081 ast_mutex_unlock(&p0->lock); 07082 ast_mutex_unlock(&p1->lock); 07083 ast_channel_unlock(c0); 07084 ast_channel_unlock(c1); 07085 return AST_BRIDGE_FAILED_NOWARN; 07086 } 07087 07088 #if defined(HAVE_PRI) 07089 if ((dahdi_sig_pri_lib_handles(p0->sig) 07090 && ((struct sig_pri_chan *) p0->sig_pvt)->no_b_channel) 07091 || (dahdi_sig_pri_lib_handles(p1->sig) 07092 && ((struct sig_pri_chan *) p1->sig_pvt)->no_b_channel)) { 07093 /* 07094 * PRI nobch channels (hold and call waiting) are equivalent to 07095 * pseudo channels and cannot be done here. 07096 */ 07097 ast_mutex_unlock(&p0->lock); 07098 ast_mutex_unlock(&p1->lock); 07099 ast_channel_unlock(c0); 07100 ast_channel_unlock(c1); 07101 return AST_BRIDGE_FAILED_NOWARN; 07102 } 07103 #endif /* defined(HAVE_PRI) */ 07104 07105 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 07106 if (p0->owner && p1->owner) { 07107 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 07108 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 07109 master = p0; 07110 slave = p1; 07111 inconf = 1; 07112 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 07113 master = p1; 07114 slave = p0; 07115 inconf = 1; 07116 } else { 07117 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 07118 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 07119 p0->channel, 07120 oi0, (p0->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0, 07121 p0->subs[SUB_REAL].inthreeway, p0->channel, 07122 oi0, (p1->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0, 07123 p1->subs[SUB_REAL].inthreeway); 07124 } 07125 nothingok = 0; 07126 } 07127 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 07128 if (p1->subs[SUB_THREEWAY].inthreeway) { 07129 master = p1; 07130 slave = p0; 07131 nothingok = 0; 07132 } 07133 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 07134 if (p0->subs[SUB_THREEWAY].inthreeway) { 07135 master = p0; 07136 slave = p1; 07137 nothingok = 0; 07138 } 07139 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 07140 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 07141 don't put us in anything */ 07142 if (p1->subs[SUB_CALLWAIT].inthreeway) { 07143 master = p1; 07144 slave = p0; 07145 nothingok = 0; 07146 } 07147 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 07148 /* Same as previous */ 07149 if (p0->subs[SUB_CALLWAIT].inthreeway) { 07150 master = p0; 07151 slave = p1; 07152 nothingok = 0; 07153 } 07154 } 07155 ast_debug(1, "master: %d, slave: %d, nothingok: %d\n", 07156 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 07157 if (master && slave) { 07158 /* Stop any tones, or play ringtone as appropriate. If they're bridged 07159 in an active threeway call with a channel that is ringing, we should 07160 indicate ringing. */ 07161 if ((oi1 == SUB_THREEWAY) && 07162 p1->subs[SUB_THREEWAY].inthreeway && 07163 p1->subs[SUB_REAL].owner && 07164 p1->subs[SUB_REAL].inthreeway && 07165 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 07166 ast_debug(1, 07167 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n", 07168 p0->channel, oi0, c0->name, p1->channel, oi1, c1->name); 07169 tone_zone_play_tone(p0->subs[oi0].dfd, DAHDI_TONE_RINGTONE); 07170 os1 = p1->subs[SUB_REAL].owner->_state; 07171 } else { 07172 ast_debug(1, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n", 07173 p0->channel, oi0, c0->name, p1->channel, oi1, c1->name); 07174 tone_zone_play_tone(p0->subs[oi0].dfd, -1); 07175 } 07176 if ((oi0 == SUB_THREEWAY) && 07177 p0->subs[SUB_THREEWAY].inthreeway && 07178 p0->subs[SUB_REAL].owner && 07179 p0->subs[SUB_REAL].inthreeway && 07180 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 07181 ast_debug(1, 07182 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n", 07183 p1->channel, oi1, c1->name, p0->channel, oi0, c0->name); 07184 tone_zone_play_tone(p1->subs[oi1].dfd, DAHDI_TONE_RINGTONE); 07185 os0 = p0->subs[SUB_REAL].owner->_state; 07186 } else { 07187 ast_debug(1, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n", 07188 p1->channel, oi1, c1->name, p0->channel, oi0, c0->name); 07189 tone_zone_play_tone(p1->subs[oi1].dfd, -1); 07190 } 07191 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 07192 if (!p0->echocanbridged || !p1->echocanbridged) { 07193 /* Disable echo cancellation if appropriate */ 07194 dahdi_disable_ec(p0); 07195 dahdi_disable_ec(p1); 07196 } 07197 } 07198 dahdi_link(slave, master); 07199 master->inconference = inconf; 07200 } else if (!nothingok) 07201 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 07202 07203 update_conf(p0); 07204 update_conf(p1); 07205 t0 = p0->subs[SUB_REAL].inthreeway; 07206 t1 = p1->subs[SUB_REAL].inthreeway; 07207 07208 ast_mutex_unlock(&p0->lock); 07209 ast_mutex_unlock(&p1->lock); 07210 07211 ast_channel_unlock(c0); 07212 ast_channel_unlock(c1); 07213 07214 /* Native bridge failed */ 07215 if ((!master || !slave) && !nothingok) { 07216 dahdi_enable_ec(p0); 07217 dahdi_enable_ec(p1); 07218 return AST_BRIDGE_FAILED; 07219 } 07220 07221 ast_verb(3, "Native bridging %s and %s\n", c0->name, c1->name); 07222 07223 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 07224 disable_dtmf_detect(op0); 07225 07226 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 07227 disable_dtmf_detect(op1); 07228 07229 for (;;) { 07230 struct ast_channel *c0_priority[2] = {c0, c1}; 07231 struct ast_channel *c1_priority[2] = {c1, c0}; 07232 07233 /* Here's our main loop... Start by locking things, looking for private parts, 07234 and then balking if anything is wrong */ 07235 07236 ast_channel_lock(c0); 07237 while (ast_channel_trylock(c1)) { 07238 CHANNEL_DEADLOCK_AVOIDANCE(c0); 07239 } 07240 07241 p0 = c0->tech_pvt; 07242 p1 = c1->tech_pvt; 07243 07244 if (op0 == p0) 07245 i0 = dahdi_get_index(c0, p0, 1); 07246 if (op1 == p1) 07247 i1 = dahdi_get_index(c1, p1, 1); 07248 07249 ast_channel_unlock(c0); 07250 ast_channel_unlock(c1); 07251 07252 if (!timeoutms || 07253 (op0 != p0) || 07254 (op1 != p1) || 07255 (ofd0 != c0->fds[0]) || 07256 (ofd1 != c1->fds[0]) || 07257 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 07258 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 07259 (oc0 != p0->owner) || 07260 (oc1 != p1->owner) || 07261 (t0 != p0->subs[SUB_REAL].inthreeway) || 07262 (t1 != p1->subs[SUB_REAL].inthreeway) || 07263 (oi0 != i0) || 07264 (oi1 != i1)) { 07265 ast_debug(1, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 07266 op0->channel, oi0, op1->channel, oi1); 07267 res = AST_BRIDGE_RETRY; 07268 goto return_from_bridge; 07269 } 07270 07271 #ifdef PRI_2BCT 07272 if (!triedtopribridge) { 07273 triedtopribridge = 1; 07274 if (p0->pri && p0->pri == p1->pri && p0->pri->transfer) { 07275 ast_mutex_lock(&p0->pri->lock); 07276 switch (p0->sig) { 07277 case SIG_PRI_LIB_HANDLE_CASES: 07278 q931c0 = ((struct sig_pri_chan *) (p0->sig_pvt))->call; 07279 break; 07280 default: 07281 q931c0 = NULL; 07282 break; 07283 } 07284 switch (p1->sig) { 07285 case SIG_PRI_LIB_HANDLE_CASES: 07286 q931c1 = ((struct sig_pri_chan *) (p1->sig_pvt))->call; 07287 break; 07288 default: 07289 q931c1 = NULL; 07290 break; 07291 } 07292 if (q931c0 && q931c1) { 07293 pri_channel_bridge(q931c0, q931c1); 07294 } 07295 ast_mutex_unlock(&p0->pri->lock); 07296 } 07297 } 07298 #endif 07299 07300 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms); 07301 if (!who) { 07302 ast_debug(1, "Ooh, empty read...\n"); 07303 continue; 07304 } 07305 f = ast_read(who); 07306 if (!f || (f->frametype == AST_FRAME_CONTROL)) { 07307 *fo = f; 07308 *rc = who; 07309 res = AST_BRIDGE_COMPLETE; 07310 goto return_from_bridge; 07311 } 07312 if (f->frametype == AST_FRAME_DTMF) { 07313 if ((who == c0) && p0->pulsedial) { 07314 ast_write(c1, f); 07315 } else if ((who == c1) && p1->pulsedial) { 07316 ast_write(c0, f); 07317 } else { 07318 *fo = f; 07319 *rc = who; 07320 res = AST_BRIDGE_COMPLETE; 07321 goto return_from_bridge; 07322 } 07323 } 07324 ast_frfree(f); 07325 07326 /* Swap who gets priority */ 07327 priority = !priority; 07328 } 07329 07330 return_from_bridge: 07331 if (op0 == p0) 07332 dahdi_enable_ec(p0); 07333 07334 if (op1 == p1) 07335 dahdi_enable_ec(p1); 07336 07337 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 07338 enable_dtmf_detect(op0); 07339 07340 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 07341 enable_dtmf_detect(op1); 07342 07343 dahdi_unlink(slave, master, 1); 07344 07345 return res; 07346 }
static int dahdi_call | ( | struct ast_channel * | ast, | |
char * | rdest, | |||
int | timeout | |||
) | [static] |
Definition at line 5218 of file chan_dahdi.c.
References ast_channel::_state, analog_call(), analog_lib_handles(), ast_copy_string(), ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_UP, ast_channel::caller, dahdi_pvt::callwaitrings, dahdi_pvt::channel, dahdi_r2_get_channel_category(), dahdi_sig_pri_lib_handles(), dahdi_pvt::dialdest, dahdi_pvt::dialednone, dahdi_pvt::dialing, errno, dahdi_pvt::hidecallerid, ast_party_caller::id, IS_DIGITAL, dahdi_pvt::law, dahdi_pvt::lock, LOG_ERROR, LOG_WARNING, dahdi_pvt::mfcr2, dahdi_pvt::mfcr2_call_accepted, dahdi_pvt::mfcr2_progress, ast_channel::name, dahdi_subchannel::needbusy, ast_party_id::number, dahdi_pvt::oprmode, dahdi_pvt::outgoing, dahdi_pvt::outsigmod, dahdi_pvt::r2chan, dahdi_pvt::radio, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, set_actual_gain(), dahdi_pvt::sig, SIG_MFCR2, sig_pri_call(), dahdi_pvt::sig_pvt, SIG_SS7, sig_ss7_call(), ast_party_number::str, dahdi_pvt::stripmsd, SUB_REAL, dahdi_pvt::subs, ast_channel::tech_pvt, ast_channel::transfercapability, dahdi_pvt::txdrc, dahdi_pvt::txgain, ast_party_number::valid, and dahdi_pvt::waitingfordt.
05219 { 05220 struct dahdi_pvt *p = ast->tech_pvt; 05221 int x, res, mysig; 05222 char dest[256]; /* must be same length as p->dialdest */ 05223 05224 ast_mutex_lock(&p->lock); 05225 ast_copy_string(dest, rdest, sizeof(dest)); 05226 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 05227 if ((ast->_state == AST_STATE_BUSY)) { 05228 p->subs[SUB_REAL].needbusy = 1; 05229 ast_mutex_unlock(&p->lock); 05230 return 0; 05231 } 05232 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 05233 ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast->name); 05234 ast_mutex_unlock(&p->lock); 05235 return -1; 05236 } 05237 p->waitingfordt.tv_sec = 0; 05238 p->dialednone = 0; 05239 if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */ 05240 { 05241 /* Special pseudo -- automatically up */ 05242 ast_setstate(ast, AST_STATE_UP); 05243 ast_mutex_unlock(&p->lock); 05244 return 0; 05245 } 05246 x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE; 05247 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x); 05248 if (res) 05249 ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno)); 05250 p->outgoing = 1; 05251 05252 if (IS_DIGITAL(ast->transfercapability)){ 05253 set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, p->rxdrc, p->txdrc, p->law); 05254 } else { 05255 set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law); 05256 } 05257 05258 #ifdef HAVE_PRI 05259 if (dahdi_sig_pri_lib_handles(p->sig)) { 05260 res = sig_pri_call(p->sig_pvt, ast, rdest, timeout, 05261 (p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW); 05262 ast_mutex_unlock(&p->lock); 05263 return res; 05264 } 05265 #endif 05266 05267 #if defined(HAVE_SS7) 05268 if (p->sig == SIG_SS7) { 05269 res = sig_ss7_call(p->sig_pvt, ast, rdest); 05270 ast_mutex_unlock(&p->lock); 05271 return res; 05272 } 05273 #endif /* defined(HAVE_SS7) */ 05274 05275 /* If this is analog signalling we can exit here */ 05276 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 05277 p->callwaitrings = 0; 05278 res = analog_call(p->sig_pvt, ast, rdest, timeout); 05279 ast_mutex_unlock(&p->lock); 05280 return res; 05281 } 05282 05283 mysig = p->outsigmod > -1 ? p->outsigmod : p->sig; 05284 switch (mysig) { 05285 case 0: 05286 /* Special pseudo -- automatically up*/ 05287 ast_setstate(ast, AST_STATE_UP); 05288 break; 05289 case SIG_MFCR2: 05290 break; 05291 default: 05292 ast_debug(1, "not yet implemented\n"); 05293 ast_mutex_unlock(&p->lock); 05294 return -1; 05295 } 05296 05297 #ifdef HAVE_OPENR2 05298 if (p->mfcr2) { 05299 openr2_calling_party_category_t chancat; 05300 int callres = 0; 05301 char *c, *l; 05302 05303 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ 05304 p->dialdest[0] = '\0'; 05305 05306 c = strchr(dest, '/'); 05307 if (c) { 05308 c++; 05309 } else { 05310 c = ""; 05311 } 05312 if (!p->hidecallerid) { 05313 l = ast->caller.id.number.valid ? ast->caller.id.number.str : NULL; 05314 } else { 05315 l = NULL; 05316 } 05317 if (strlen(c) < p->stripmsd) { 05318 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 05319 ast_mutex_unlock(&p->lock); 05320 return -1; 05321 } 05322 p->dialing = 1; 05323 chancat = dahdi_r2_get_channel_category(ast); 05324 callres = openr2_chan_make_call(p->r2chan, l, (c + p->stripmsd), chancat); 05325 if (-1 == callres) { 05326 ast_mutex_unlock(&p->lock); 05327 ast_log(LOG_ERROR, "unable to make new MFC/R2 call!\n"); 05328 return -1; 05329 } 05330 p->mfcr2_call_accepted = 0; 05331 p->mfcr2_progress = 0; 05332 ast_setstate(ast, AST_STATE_DIALING); 05333 } 05334 #endif /* HAVE_OPENR2 */ 05335 ast_mutex_unlock(&p->lock); 05336 return 0; 05337 }
static int dahdi_callwait | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 5185 of file chan_dahdi.c.
References ast_free, ast_gen_cas(), AST_LAW, ast_log(), ast_malloc, dahdi_pvt::callwaitcas, CALLWAITING_REPEAT_SAMPLES, dahdi_pvt::callwaitingcallerid, dahdi_pvt::callwaitingrepeat, dahdi_pvt::callwaitrings, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, LOG_WARNING, READ_SIZE, save_conference(), send_callerid(), and ast_channel::tech_pvt.
Referenced by dahdi_read().
05186 { 05187 struct dahdi_pvt *p = ast->tech_pvt; 05188 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 05189 if (p->cidspill) { 05190 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 05191 ast_free(p->cidspill); 05192 } 05193 05194 /* 05195 * SAS: Subscriber Alert Signal, 440Hz for 300ms 05196 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves 05197 */ 05198 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 05199 return -1; 05200 save_conference(p); 05201 /* Silence */ 05202 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 05203 if (!p->callwaitrings && p->callwaitingcallerid) { 05204 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 05205 p->callwaitcas = 1; 05206 p->cidlen = 2400 + 680 + READ_SIZE * 4; 05207 } else { 05208 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 05209 p->callwaitcas = 0; 05210 p->cidlen = 2400 + READ_SIZE * 4; 05211 } 05212 p->cidpos = 0; 05213 send_callerid(p); 05214 05215 return 0; 05216 }
static int dahdi_cc_callback | ( | struct ast_channel * | inbound, | |
const char * | dest, | |||
ast_cc_callback_fn | callback | |||
) | [static] |
Callback made when dial failed to get a channel out of dahdi_request().
inbound | Incoming asterisk channel. | |
dest | Same dial string passed to dahdi_request(). | |
callback | Callback into CC core to announce a busy channel available for CC. |
0 | on success. | |
-1 | on error. |
Definition at line 13475 of file chan_dahdi.c.
References AST_CC_GENERIC_MONITOR_TYPE, AST_CC_MONITOR_ALWAYS, AST_CC_MONITOR_GENERIC, AST_CC_MONITOR_NATIVE, AST_CC_MONITOR_NEVER, AST_CHANNEL_NAME, ast_free, ast_get_cc_monitor_policy(), ast_mutex_lock, ast_mutex_unlock, ast_str_buffer(), dahdi_pvt::cc_params, sig_pri_span::cc_params, dahdi_starting_point::channelmatch, create_channel_name(), dahdi_sig_pri_lib_handles(), determine_starting_point(), dahdi_starting_point::groupmatch, iflock, is_group_or_channel_match(), dahdi_pvt::pri, and dahdi_starting_point::span.
13476 { 13477 struct dahdi_pvt *p; 13478 struct dahdi_pvt *exitpvt; 13479 struct dahdi_starting_point start; 13480 int groupmatched = 0; 13481 int channelmatched = 0; 13482 13483 ast_mutex_lock(&iflock); 13484 p = determine_starting_point(dest, &start); 13485 if (!p) { 13486 ast_mutex_unlock(&iflock); 13487 return -1; 13488 } 13489 exitpvt = p; 13490 for (;;) { 13491 if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)) { 13492 /* We found a potential match. call the callback */ 13493 struct ast_str *device_name; 13494 char *dash; 13495 const char *monitor_type; 13496 char dialstring[AST_CHANNEL_NAME]; 13497 char full_device_name[AST_CHANNEL_NAME]; 13498 13499 switch (ast_get_cc_monitor_policy(p->cc_params)) { 13500 case AST_CC_MONITOR_NEVER: 13501 break; 13502 case AST_CC_MONITOR_NATIVE: 13503 case AST_CC_MONITOR_ALWAYS: 13504 case AST_CC_MONITOR_GENERIC: 13505 #if defined(HAVE_PRI) 13506 if (dahdi_sig_pri_lib_handles(p->sig)) { 13507 /* 13508 * ISDN is in a trunk busy condition so we need to monitor 13509 * the span congestion device state. 13510 */ 13511 snprintf(full_device_name, sizeof(full_device_name), 13512 "DAHDI/I%d/congestion", p->pri->span); 13513 } else 13514 #endif /* defined(HAVE_PRI) */ 13515 { 13516 #if defined(HAVE_PRI) 13517 device_name = create_channel_name(p, 1, ""); 13518 #else 13519 device_name = create_channel_name(p); 13520 #endif /* defined(HAVE_PRI) */ 13521 snprintf(full_device_name, sizeof(full_device_name), "DAHDI/%s", 13522 device_name ? ast_str_buffer(device_name) : ""); 13523 ast_free(device_name); 13524 /* 13525 * The portion after the '-' in the channel name is either a random 13526 * number, a sequence number, or a subchannel number. None are 13527 * necessary so strip them off. 13528 */ 13529 dash = strrchr(full_device_name, '-'); 13530 if (dash) { 13531 *dash = '\0'; 13532 } 13533 } 13534 snprintf(dialstring, sizeof(dialstring), "DAHDI/%s", dest); 13535 13536 /* 13537 * Analog can only do generic monitoring. 13538 * ISDN is in a trunk busy condition and any "device" is going 13539 * to be busy until a B channel becomes available. The generic 13540 * monitor can do this task. 13541 */ 13542 monitor_type = AST_CC_GENERIC_MONITOR_TYPE; 13543 callback(inbound, 13544 #if defined(HAVE_PRI) 13545 p->pri ? p->pri->cc_params : p->cc_params, 13546 #else 13547 p->cc_params, 13548 #endif /* defined(HAVE_PRI) */ 13549 monitor_type, full_device_name, dialstring, NULL); 13550 break; 13551 } 13552 } 13553 p = start.backwards ? p->prev : p->next; 13554 if (!p) { 13555 p = start.backwards ? ifend : iflist; 13556 } 13557 if (p == exitpvt) { 13558 break; 13559 } 13560 } 13561 ast_mutex_unlock(&iflock); 13562 return 0; 13563 }
static struct dahdi_chan_conf dahdi_chan_conf_default | ( | void | ) | [static] |
returns a new dahdi_chan_conf with default values (by-value)
Definition at line 1343 of file chan_dahdi.c.
References ast_cc_config_params_init, CID_SIG_BELL, CID_START_RING, DAHDI_CHAN_MAPPING_PHYSICAL, DEFAULT_CIDRINGS, sig_pri_span::nsf, dahdi_pri::pri, and dahdi_chan_conf::pri.
Referenced by setup_dahdi().
01344 { 01345 /* recall that if a field is not included here it is initialized 01346 * to 0 or equivalent 01347 */ 01348 struct dahdi_chan_conf conf = { 01349 #ifdef HAVE_PRI 01350 .pri.pri = { 01351 .nsf = PRI_NSF_NONE, 01352 .switchtype = PRI_SWITCH_NI2, 01353 .dialplan = PRI_UNKNOWN + 1, 01354 .localdialplan = PRI_NATIONAL_ISDN + 1, 01355 .nodetype = PRI_CPE, 01356 .qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL, 01357 01358 #if defined(HAVE_PRI_CCSS) 01359 .cc_ptmp_recall_mode = 1,/* specificRecall */ 01360 .cc_qsig_signaling_link_req = 1,/* retain */ 01361 .cc_qsig_signaling_link_rsp = 1,/* retain */ 01362 #endif /* defined(HAVE_PRI_CCSS) */ 01363 01364 .minunused = 2, 01365 .idleext = "", 01366 .idledial = "", 01367 .internationalprefix = "", 01368 .nationalprefix = "", 01369 .localprefix = "", 01370 .privateprefix = "", 01371 .unknownprefix = "", 01372 .resetinterval = -1, 01373 }, 01374 #endif 01375 #if defined(HAVE_SS7) 01376 .ss7.ss7 = { 01377 .called_nai = SS7_NAI_NATIONAL, 01378 .calling_nai = SS7_NAI_NATIONAL, 01379 .internationalprefix = "", 01380 .nationalprefix = "", 01381 .subscriberprefix = "", 01382 .unknownprefix = "" 01383 }, 01384 #endif /* defined(HAVE_SS7) */ 01385 #ifdef HAVE_OPENR2 01386 .mfcr2 = { 01387 .variant = OR2_VAR_ITU, 01388 .mfback_timeout = -1, 01389 .metering_pulse_timeout = -1, 01390 .max_ani = 10, 01391 .max_dnis = 4, 01392 .get_ani_first = -1, 01393 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 01394 .skip_category_request = -1, 01395 #endif 01396 .call_files = 0, 01397 .allow_collect_calls = 0, 01398 .charge_calls = 1, 01399 .accept_on_offer = 1, 01400 .forced_release = 0, 01401 .double_answer = 0, 01402 .immediate_accept = -1, 01403 .logdir = "", 01404 .r2proto_file = "", 01405 .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING, 01406 .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER 01407 }, 01408 #endif 01409 .chan = { 01410 .context = "default", 01411 .cid_num = "", 01412 .cid_name = "", 01413 .cid_tag = "", 01414 .mohinterpret = "default", 01415 .mohsuggest = "", 01416 .parkinglot = "", 01417 .transfertobusy = 1, 01418 01419 .cid_signalling = CID_SIG_BELL, 01420 .cid_start = CID_START_RING, 01421 .dahditrcallerid = 0, 01422 .use_callerid = 1, 01423 .sig = -1, 01424 .outsigmod = -1, 01425 01426 .cid_rxgain = +5.0, 01427 01428 .tonezone = -1, 01429 01430 .echocancel.head.tap_length = 1, 01431 01432 .busycount = 3, 01433 .busycompare = 0, 01434 .busytonelength = 0, 01435 .busyquietlength = 0, 01436 .busyfuzziness = 0, 01437 .silencethreshold = 0, 01438 01439 .accountcode = "", 01440 01441 .mailbox = "", 01442 01443 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 01444 .mwisend_fsk = 1, 01445 #endif 01446 .polarityonanswerdelay = 600, 01447 01448 .sendcalleridafter = DEFAULT_CIDRINGS, 01449 01450 .buf_policy = DAHDI_POLICY_IMMEDIATE, 01451 .buf_no = numbufs, 01452 .usefaxbuffers = 0, 01453 .cc_params = ast_cc_config_params_init(), 01454 }, 01455 .timing = { 01456 .prewinktime = -1, 01457 .preflashtime = -1, 01458 .winktime = -1, 01459 .flashtime = -1, 01460 .starttime = -1, 01461 .rxwinktime = -1, 01462 .rxflashtime = -1, 01463 .debouncetime = -1 01464 }, 01465 .is_sig_auto = 1, 01466 .smdi_port = "/dev/ttyS0", 01467 }; 01468 01469 return conf; 01470 }
static int dahdi_channels_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 17891 of file chan_dahdi.c.
References ast_data_add_node(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_mutex_lock, ast_mutex_unlock, iflist, and dahdi_pvt::next.
17893 { 17894 struct dahdi_pvt *tmp; 17895 struct ast_data *data_channel; 17896 17897 ast_mutex_lock(&iflock); 17898 for (tmp = iflist; tmp; tmp = tmp->next) { 17899 data_channel = ast_data_add_node(data_root, "channel"); 17900 if (!data_channel) { 17901 continue; 17902 } 17903 17904 ast_data_add_structure(dahdi_pvt, data_channel, tmp); 17905 17906 /* if this channel doesn't match remove it. */ 17907 if (!ast_data_search_match(search, data_channel)) { 17908 ast_data_remove_node(data_root, data_channel); 17909 } 17910 } 17911 ast_mutex_unlock(&iflock); 17912 17913 return 0; 17914 }
static void dahdi_close | ( | int | fd | ) | [static] |
Definition at line 4212 of file chan_dahdi.c.
Referenced by dahdi_close_pri_fd(), dahdi_close_ss7_fd(), and dahdi_close_sub().
static void dahdi_close_pri_fd | ( | struct dahdi_pri * | pri, | |
int | fd_num | |||
) | [static] |
Definition at line 4225 of file chan_dahdi.c.
References dahdi_close(), sig_pri_span::fds, and dahdi_pri::pri.
Referenced by __unload_module(), and prepare_pri().
04226 { 04227 dahdi_close(pri->pri.fds[fd_num]); 04228 pri->pri.fds[fd_num] = -1; 04229 }
static void dahdi_close_ss7_fd | ( | struct dahdi_ss7 * | ss7, | |
int | fd_num | |||
) | [static] |
Definition at line 4233 of file chan_dahdi.c.
References dahdi_close(), sig_ss7_linkset::fds, and dahdi_ss7::ss7.
Referenced by __unload_module(), and linkset_addsigchan().
04234 { 04235 dahdi_close(ss7->ss7.fds[fd_num]); 04236 ss7->ss7.fds[fd_num] = -1; 04237 }
static void dahdi_close_sub | ( | struct dahdi_pvt * | chan_pvt, | |
int | sub_num | |||
) | [static] |
Definition at line 4218 of file chan_dahdi.c.
References dahdi_close(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
Referenced by alloc_sub(), destroy_dahdi_pvt(), and unalloc_sub().
04219 { 04220 dahdi_close(chan_pvt->subs[sub_num].dfd); 04221 chan_pvt->subs[sub_num].dfd = -1; 04222 }
static int dahdi_confmute | ( | struct dahdi_pvt * | p, | |
int | muted | |||
) | [inline, static] |
Definition at line 5028 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, errno, LOG_WARNING, dahdi_pvt::sig, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_handle_dtmf(), dahdi_handle_event(), dahdi_hangup(), dahdi_new(), dahdi_read(), my_confmute(), and my_handle_dtmf().
05029 { 05030 int x, res; 05031 05032 x = muted; 05033 #if defined(HAVE_PRI) || defined(HAVE_SS7) 05034 switch (p->sig) { 05035 #if defined(HAVE_PRI) 05036 case SIG_PRI_LIB_HANDLE_CASES: 05037 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 05038 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */ 05039 break; 05040 } 05041 /* Fall through */ 05042 #endif /* defined(HAVE_PRI) */ 05043 #if defined(HAVE_SS7) 05044 case SIG_SS7: 05045 #endif /* defined(HAVE_SS7) */ 05046 { 05047 int y = 1; 05048 05049 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y); 05050 if (res) 05051 ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n", 05052 p->channel, strerror(errno)); 05053 } 05054 break; 05055 default: 05056 break; 05057 } 05058 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 05059 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x); 05060 if (res < 0) 05061 ast_log(LOG_WARNING, "DAHDI confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno)); 05062 return res; 05063 }
static char* dahdi_destroy_channel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14575 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_destroy_channel_bynum(), RESULT_SUCCESS, and ast_cli_entry::usage.
14576 { 14577 int channel; 14578 int ret; 14579 switch (cmd) { 14580 case CLI_INIT: 14581 e->command = "dahdi destroy channel"; 14582 e->usage = 14583 "Usage: dahdi destroy channel <chan num>\n" 14584 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n"; 14585 return NULL; 14586 case CLI_GENERATE: 14587 return NULL; 14588 } 14589 if (a->argc != 4) 14590 return CLI_SHOWUSAGE; 14591 14592 channel = atoi(a->argv[3]); 14593 ret = dahdi_destroy_channel_bynum(channel); 14594 return ( RESULT_SUCCESS == ret ) ? CLI_SUCCESS : CLI_FAILURE; 14595 }
static int dahdi_destroy_channel_bynum | ( | int | channel | ) | [static] |
Definition at line 11044 of file chan_dahdi.c.
References ast_module_unref(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, destroy_channel(), iflist, iflock, dahdi_pvt::next, RESULT_SUCCESS, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_destroy_channel().
11045 { 11046 struct dahdi_pvt *cur; 11047 11048 ast_mutex_lock(&iflock); 11049 for (cur = iflist; cur; cur = cur->next) { 11050 if (cur->channel == channel) { 11051 int x = DAHDI_FLASH; 11052 11053 /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */ 11054 ioctl(cur->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 11055 11056 destroy_channel(cur, 1); 11057 ast_mutex_unlock(&iflock); 11058 ast_module_unref(ast_module_info->self); 11059 return RESULT_SUCCESS; 11060 } 11061 } 11062 ast_mutex_unlock(&iflock); 11063 return RESULT_FAILURE; 11064 }
static int dahdi_devicestate | ( | void * | data | ) | [static] |
Definition at line 13413 of file chan_dahdi.c.
References AST_DEVICE_UNKNOWN, sig_pri_span::congestion_devstate, dahdi_pri::pri, and pris.
13414 { 13415 #if defined(HAVE_PRI) 13416 char *device; 13417 unsigned span; 13418 int res; 13419 13420 device = data; 13421 13422 if (*device != 'I') { 13423 /* The request is not for an ISDN span device. */ 13424 return AST_DEVICE_UNKNOWN; 13425 } 13426 res = sscanf(device, "I%30u", &span); 13427 if (res != 1 || !span || NUM_SPANS < span) { 13428 /* Bad format for ISDN span device name. */ 13429 return AST_DEVICE_UNKNOWN; 13430 } 13431 device = strchr(device, '/'); 13432 if (!device) { 13433 /* Bad format for ISDN span device name. */ 13434 return AST_DEVICE_UNKNOWN; 13435 } 13436 13437 /* 13438 * Since there are currently no other span devstate's defined, 13439 * it must be congestion. 13440 */ 13441 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER) 13442 ++device; 13443 if (!strcmp(device, "congestion")) 13444 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */ 13445 { 13446 return pris[span - 1].pri.congestion_devstate; 13447 } 13448 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER) 13449 else if (!strcmp(device, "threshold")) { 13450 return pris[span - 1].pri.threshold_devstate; 13451 } 13452 return AST_DEVICE_UNKNOWN; 13453 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */ 13454 #else 13455 return AST_DEVICE_UNKNOWN; 13456 #endif /* defined(HAVE_PRI) */ 13457 }
static int dahdi_digit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 4316 of file chan_dahdi.c.
References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::begindigit, dahdi_get_index, dahdi_pvt::dialing, digit_to_dtmfindex(), errno, dahdi_pvt::lock, LOG_WARNING, dahdi_pvt::owner, dahdi_pvt::pulse, dahdi_pvt::sig, sig_pri_digit_begin(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SUB_REAL, dahdi_pvt::subs, and ast_channel::tech_pvt.
04317 { 04318 struct dahdi_pvt *pvt; 04319 int idx; 04320 int dtmf = -1; 04321 int res; 04322 04323 pvt = chan->tech_pvt; 04324 04325 ast_mutex_lock(&pvt->lock); 04326 04327 idx = dahdi_get_index(chan, pvt, 0); 04328 04329 if ((idx != SUB_REAL) || !pvt->owner) 04330 goto out; 04331 04332 #ifdef HAVE_PRI 04333 switch (pvt->sig) { 04334 case SIG_PRI_LIB_HANDLE_CASES: 04335 res = sig_pri_digit_begin(pvt->sig_pvt, chan, digit); 04336 if (!res) 04337 goto out; 04338 break; 04339 default: 04340 break; 04341 } 04342 #endif 04343 if ((dtmf = digit_to_dtmfindex(digit)) == -1) 04344 goto out; 04345 04346 if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) { 04347 struct dahdi_dialoperation zo = { 04348 .op = DAHDI_DIAL_OP_APPEND, 04349 }; 04350 04351 zo.dialstr[0] = 'T'; 04352 zo.dialstr[1] = digit; 04353 zo.dialstr[2] = '\0'; 04354 if ((res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo))) 04355 ast_log(LOG_WARNING, "Couldn't dial digit %c: %s\n", digit, strerror(errno)); 04356 else 04357 pvt->dialing = 1; 04358 } else { 04359 ast_debug(1, "Started VLDTMF digit '%c'\n", digit); 04360 pvt->dialing = 1; 04361 pvt->begindigit = digit; 04362 } 04363 04364 out: 04365 ast_mutex_unlock(&pvt->lock); 04366 04367 return 0; 04368 }
static int dahdi_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 4370 of file chan_dahdi.c.
References ast_debug, ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::begindigit, dahdi_get_index, dahdi_sig_pri_lib_handles(), dahdi_pvt::dialing, dahdi_pvt::lock, dahdi_pvt::owner, dahdi_pvt::pulse, dahdi_pvt::sig, SUB_REAL, dahdi_pvt::subs, and ast_channel::tech_pvt.
04371 { 04372 struct dahdi_pvt *pvt; 04373 int res = 0; 04374 int idx; 04375 int x; 04376 04377 pvt = chan->tech_pvt; 04378 04379 ast_mutex_lock(&pvt->lock); 04380 04381 idx = dahdi_get_index(chan, pvt, 0); 04382 04383 if ((idx != SUB_REAL) || !pvt->owner || pvt->pulse) 04384 goto out; 04385 04386 #ifdef HAVE_PRI 04387 /* This means that the digit was already sent via PRI signalling */ 04388 if (dahdi_sig_pri_lib_handles(pvt->sig) && !pvt->begindigit) { 04389 goto out; 04390 } 04391 #endif 04392 04393 if (pvt->begindigit) { 04394 x = -1; 04395 ast_debug(1, "Ending VLDTMF digit '%c'\n", digit); 04396 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x); 04397 pvt->dialing = 0; 04398 pvt->begindigit = 0; 04399 } 04400 04401 out: 04402 ast_mutex_unlock(&pvt->lock); 04403 04404 return res; 04405 }
static void dahdi_disable_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4820 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_pvt::channel, dahdi_pvt::echocanon, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.
Referenced by __dahdi_exception(), dahdi_bridge(), dahdi_func_write(), dahdi_handle_event(), dahdi_hangup(), dahdi_setoption(), handle_init_event(), and my_set_echocanceller().
04821 { 04822 int res; 04823 04824 if (p->echocanon) { 04825 struct dahdi_echocanparams ecp = { .tap_length = 0 }; 04826 04827 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &ecp); 04828 04829 if (res) 04830 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno)); 04831 else 04832 ast_debug(1, "Disabled echo cancellation on channel %d\n", p->channel); 04833 } 04834 04835 p->echocanon = 0; 04836 }
static int dahdi_dnd | ( | struct dahdi_pvt * | dahdichan, | |
int | flag | |||
) | [static] |
enable or disable the chan_dahdi Do-Not-Disturb mode for a DAHDI channel
dahdichan | "Physical" DAHDI channel (e.g: DAHDI/5) | |
flag | on 1 to enable, 0 to disable, -1 return dnd value |
Definition at line 9542 of file chan_dahdi.c.
References analog_dnd(), analog_lib_handles(), ast_verb, dahdi_pvt::channel, dahdi_pvt::dnd, EVENT_FLAG_SYSTEM, manager_event, dahdi_pvt::oprmode, dahdi_pvt::radio, dahdi_pvt::sig, and dahdi_pvt::sig_pvt.
Referenced by action_dahdidndoff(), action_dahdidndon(), action_dahdishowchannels(), analog_ss_thread(), dahdi_set_dnd(), and dahdi_show_channel().
09543 { 09544 if (analog_lib_handles(dahdichan->sig, dahdichan->radio, dahdichan->oprmode)) { 09545 return analog_dnd(dahdichan->sig_pvt, flag); 09546 } 09547 09548 if (flag == -1) { 09549 return dahdichan->dnd; 09550 } 09551 09552 /* Do not disturb */ 09553 dahdichan->dnd = flag; 09554 ast_verb(3, "%s DND on channel %d\n", 09555 flag? "Enabled" : "Disabled", 09556 dahdichan->channel); 09557 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 09558 "Channel: DAHDI/%d\r\n" 09559 "Status: %s\r\n", dahdichan->channel, 09560 flag? "enabled" : "disabled"); 09561 09562 return 0; 09563 }
static void dahdi_enable_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4748 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_pvt::channel, dahdi_pvt::digital, dahdi_pvt::echocancel, dahdi_pvt::echocanon, errno, dahdi_pvt::head, LOG_WARNING, dahdi_pvt::sig, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, SUB_REAL, and dahdi_pvt::subs.
Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_bridge(), dahdi_func_write(), dahdi_handle_event(), dahdi_r2_on_call_accepted(), dahdi_setoption(), handle_init_event(), and my_set_echocanceller().
04749 { 04750 int res; 04751 if (!p) 04752 return; 04753 if (p->echocanon) { 04754 ast_debug(1, "Echo cancellation already on\n"); 04755 return; 04756 } 04757 if (p->digital) { 04758 ast_debug(1, "Echo cancellation isn't required on digital connection\n"); 04759 return; 04760 } 04761 if (p->echocancel.head.tap_length) { 04762 #if defined(HAVE_PRI) || defined(HAVE_SS7) 04763 switch (p->sig) { 04764 #if defined(HAVE_PRI) 04765 case SIG_PRI_LIB_HANDLE_CASES: 04766 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 04767 /* 04768 * PRI nobch pseudo channel. Does not need ec anyway. 04769 * Does not handle ioctl(DAHDI_AUDIOMODE) 04770 */ 04771 return; 04772 } 04773 /* Fall through */ 04774 #endif /* defined(HAVE_PRI) */ 04775 #if defined(HAVE_SS7) 04776 case SIG_SS7: 04777 #endif /* defined(HAVE_SS7) */ 04778 { 04779 int x = 1; 04780 04781 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x); 04782 if (res) 04783 ast_log(LOG_WARNING, 04784 "Unable to enable audio mode on channel %d (%s)\n", 04785 p->channel, strerror(errno)); 04786 } 04787 break; 04788 default: 04789 break; 04790 } 04791 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 04792 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &p->echocancel); 04793 if (res) { 04794 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno)); 04795 } else { 04796 p->echocanon = 1; 04797 ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel); 04798 } 04799 } else 04800 ast_debug(1, "No echo cancellation requested\n"); 04801 }
static struct ast_frame * dahdi_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 8625 of file chan_dahdi.c.
References __dahdi_exception(), analog_exception(), analog_lib_handles(), ast_mutex_lock, ast_mutex_unlock, f, dahdi_pvt::lock, dahdi_pvt::oprmode, dahdi_pvt::radio, dahdi_pvt::sig, dahdi_pvt::sig_pvt, and ast_channel::tech_pvt.
08626 { 08627 struct dahdi_pvt *p = ast->tech_pvt; 08628 struct ast_frame *f; 08629 ast_mutex_lock(&p->lock); 08630 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 08631 struct analog_pvt *analog_p = p->sig_pvt; 08632 f = analog_exception(analog_p, ast); 08633 } else { 08634 f = __dahdi_exception(ast); 08635 } 08636 ast_mutex_unlock(&p->lock); 08637 return f; 08638 }
static int dahdi_fake_event | ( | struct dahdi_pvt * | p, | |
int | mode | |||
) | [static] |
Definition at line 15422 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::fake_event, HANGUP, ast_channel::name, dahdi_pvt::owner, and TRANSFER.
Referenced by action_transfer(), and action_transferhangup().
15423 { 15424 if (p) { 15425 switch (mode) { 15426 case TRANSFER: 15427 p->fake_event = DAHDI_EVENT_WINKFLASH; 15428 break; 15429 case HANGUP: 15430 p->fake_event = DAHDI_EVENT_ONHOOK; 15431 break; 15432 default: 15433 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name); 15434 } 15435 } 15436 return 0; 15437 }
static int dahdi_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 7348 of file chan_dahdi.c.
References ast_debug, ast_mutex_lock, dahdi_pvt::channel, dahdi_unlink(), dahdi_pvt::lock, ast_channel::name, dahdi_subchannel::owner, dahdi_pvt::owner, dahdi_pvt::subs, and ast_channel::tech_pvt.
07349 { 07350 struct dahdi_pvt *p = newchan->tech_pvt; 07351 int x; 07352 07353 ast_mutex_lock(&p->lock); 07354 07355 ast_debug(1, "New owner for channel %d is %s\n", p->channel, newchan->name); 07356 if (p->owner == oldchan) { 07357 p->owner = newchan; 07358 } 07359 for (x = 0; x < 3; x++) { 07360 if (p->subs[x].owner == oldchan) { 07361 if (!x) { 07362 dahdi_unlink(NULL, p, 0); 07363 } 07364 p->subs[x].owner = newchan; 07365 } 07366 } 07367 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 07368 analog_fixup(oldchan, newchan, p->sig_pvt); 07369 #if defined(HAVE_PRI) 07370 } else if (dahdi_sig_pri_lib_handles(p->sig)) { 07371 sig_pri_fixup(oldchan, newchan, p->sig_pvt); 07372 #endif /* defined(HAVE_PRI) */ 07373 #if defined(HAVE_SS7) 07374 } else if (p->sig == SIG_SS7) { 07375 sig_ss7_fixup(oldchan, newchan, p->sig_pvt); 07376 #endif /* defined(HAVE_SS7) */ 07377 } 07378 update_conf(p); 07379 07380 ast_mutex_unlock(&p->lock); 07381 07382 if (newchan->_state == AST_STATE_RINGING) { 07383 dahdi_indicate(newchan, AST_CONTROL_RINGING, NULL, 0); 07384 } 07385 return 0; 07386 }
static int dahdi_func_read | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 6751 of file chan_dahdi.c.
References ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::lock, dahdi_pvt::rxgain, dahdi_pvt::sig, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, ast_channel::tech_pvt, and dahdi_pvt::txgain.
06752 { 06753 struct dahdi_pvt *p = chan->tech_pvt; 06754 int res = 0; 06755 06756 if (!strcasecmp(data, "rxgain")) { 06757 ast_mutex_lock(&p->lock); 06758 snprintf(buf, len, "%f", p->rxgain); 06759 ast_mutex_unlock(&p->lock); 06760 } else if (!strcasecmp(data, "txgain")) { 06761 ast_mutex_lock(&p->lock); 06762 snprintf(buf, len, "%f", p->txgain); 06763 ast_mutex_unlock(&p->lock); 06764 #if defined(HAVE_PRI) 06765 #if defined(HAVE_PRI_REVERSE_CHARGE) 06766 } else if (!strcasecmp(data, "reversecharge")) { 06767 ast_mutex_lock(&p->lock); 06768 switch (p->sig) { 06769 case SIG_PRI_LIB_HANDLE_CASES: 06770 snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->reverse_charging_indication); 06771 break; 06772 default: 06773 *buf = '\0'; 06774 res = -1; 06775 break; 06776 } 06777 ast_mutex_unlock(&p->lock); 06778 #endif 06779 #if defined(HAVE_PRI_SETUP_KEYPAD) 06780 } else if (!strcasecmp(data, "keypad_digits")) { 06781 ast_mutex_lock(&p->lock); 06782 switch (p->sig) { 06783 case SIG_PRI_LIB_HANDLE_CASES: 06784 ast_copy_string(buf, ((struct sig_pri_chan *) p->sig_pvt)->keypad_digits, 06785 len); 06786 break; 06787 default: 06788 *buf = '\0'; 06789 res = -1; 06790 break; 06791 } 06792 ast_mutex_unlock(&p->lock); 06793 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 06794 } else if (!strcasecmp(data, "no_media_path")) { 06795 ast_mutex_lock(&p->lock); 06796 switch (p->sig) { 06797 case SIG_PRI_LIB_HANDLE_CASES: 06798 /* 06799 * TRUE if the call is on hold or is call waiting because 06800 * there is no media path available. 06801 */ 06802 snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel); 06803 break; 06804 default: 06805 *buf = '\0'; 06806 res = -1; 06807 break; 06808 } 06809 ast_mutex_unlock(&p->lock); 06810 #endif /* defined(HAVE_PRI) */ 06811 } else { 06812 *buf = '\0'; 06813 res = -1; 06814 } 06815 06816 return res; 06817 }
static int dahdi_func_write | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 6849 of file chan_dahdi.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::bufferoverrideinuse, dahdi_pvt::bufsize, dahdi_pvt::channel, dahdi_disable_ec(), dahdi_enable_ec(), dahdi_pvt::echocanon, errno, dahdi_pvt::lock, LOG_WARNING, parse_buffers_policy(), SUB_REAL, dahdi_pvt::subs, and ast_channel::tech_pvt.
06850 { 06851 struct dahdi_pvt *p = chan->tech_pvt; 06852 int res = 0; 06853 06854 if (!strcasecmp(data, "buffers")) { 06855 int num_bufs, policy; 06856 06857 if (!(parse_buffers_policy(value, &num_bufs, &policy))) { 06858 struct dahdi_bufferinfo bi = { 06859 .txbufpolicy = policy, 06860 .rxbufpolicy = policy, 06861 .bufsize = p->bufsize, 06862 .numbufs = num_bufs, 06863 }; 06864 int bpres; 06865 06866 if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 06867 ast_log(LOG_WARNING, "Channel '%d' unable to override buffer policy: %s\n", p->channel, strerror(errno)); 06868 } else { 06869 p->bufferoverrideinuse = 1; 06870 } 06871 } else { 06872 res = -1; 06873 } 06874 } else if (!strcasecmp(data, "echocan_mode")) { 06875 if (!strcasecmp(value, "on")) { 06876 ast_mutex_lock(&p->lock); 06877 dahdi_enable_ec(p); 06878 ast_mutex_unlock(&p->lock); 06879 } else if (!strcasecmp(value, "off")) { 06880 ast_mutex_lock(&p->lock); 06881 dahdi_disable_ec(p); 06882 ast_mutex_unlock(&p->lock); 06883 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 06884 } else if (!strcasecmp(value, "fax")) { 06885 int blah = 1; 06886 06887 ast_mutex_lock(&p->lock); 06888 if (!p->echocanon) { 06889 dahdi_enable_ec(p); 06890 } 06891 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) { 06892 ast_log(LOG_WARNING, "Unable to place echocan into fax mode on channel %d: %s\n", p->channel, strerror(errno)); 06893 } 06894 ast_mutex_unlock(&p->lock); 06895 } else if (!strcasecmp(value, "voice")) { 06896 int blah = 0; 06897 06898 ast_mutex_lock(&p->lock); 06899 if (!p->echocanon) { 06900 dahdi_enable_ec(p); 06901 } 06902 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) { 06903 ast_log(LOG_WARNING, "Unable to place echocan into voice mode on channel %d: %s\n", p->channel, strerror(errno)); 06904 } 06905 ast_mutex_unlock(&p->lock); 06906 #endif 06907 } else { 06908 ast_log(LOG_WARNING, "Unsupported value '%s' provided for '%s' item.\n", value, data); 06909 res = -1; 06910 } 06911 } else { 06912 res = -1; 06913 } 06914 06915 return res; 06916 }
static int dahdi_get_event | ( | int | fd | ) | [inline, static] |
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition at line 469 of file chan_dahdi.c.
Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_handle_event(), mwi_thread(), my_distinctive_ring(), my_get_callerid(), and my_get_event().
00470 { 00471 int j; 00472 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1) 00473 return -1; 00474 return j; 00475 }
static void dahdi_handle_dtmf | ( | struct ast_channel * | ast, | |
int | idx, | |||
struct ast_frame ** | dest | |||
) | [static] |
Definition at line 7525 of file chan_dahdi.c.
References ast_async_goto(), ast_channel_lock, ast_channel_unlock, AST_CONTROL_ANSWER, ast_debug, ast_dsp_set_features(), ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verb, dahdi_pvt::bufferoverrideinuse, dahdi_pvt::bufsize, ast_channel::caller, dahdi_pvt::callprogress, CALLPROGRESS_FAX, dahdi_pvt::callwaitcas, dahdi_pvt::cidspill, dahdi_pvt::confirmanswer, ast_channel::context, dahdi_confmute(), dahdi_subchannel::dfd, dahdi_pvt::dsp, DSP_FEATURE_FAX_DETECT, dahdi_pvt::dsp_features, errno, ast_channel::exten, dahdi_subchannel::f, f, dahdi_pvt::faxbuf_no, dahdi_pvt::faxbuf_policy, dahdi_pvt::faxhandled, ast_frame::frametype, ast_party_caller::id, ast_frame_subclass::integer, dahdi_pvt::lock, LOG_NOTICE, ast_channel::macrocontext, ast_channel::name, ast_party_id::number, pbx_builtin_setvar_helper(), S_COR, S_OR, send_cwcidspill(), ast_party_number::str, ast_frame::subclass, dahdi_pvt::subs, ast_channel::tech_pvt, dahdi_pvt::usefaxbuffers, and ast_party_number::valid.
Referenced by dahdi_handle_event(), and dahdi_read().
07526 { 07527 struct dahdi_pvt *p = ast->tech_pvt; 07528 struct ast_frame *f = *dest; 07529 07530 ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n", 07531 f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End", 07532 f->subclass.integer, f->subclass.integer, ast->name); 07533 07534 if (p->confirmanswer) { 07535 if (f->frametype == AST_FRAME_DTMF_END) { 07536 ast_debug(1, "Confirm answer on %s!\n", ast->name); 07537 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 07538 of a DTMF digit */ 07539 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 07540 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 07541 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 07542 p->confirmanswer = 0; 07543 } else { 07544 p->subs[idx].f.frametype = AST_FRAME_NULL; 07545 p->subs[idx].f.subclass.integer = 0; 07546 } 07547 *dest = &p->subs[idx].f; 07548 } else if (p->callwaitcas) { 07549 if (f->frametype == AST_FRAME_DTMF_END) { 07550 if ((f->subclass.integer == 'A') || (f->subclass.integer == 'D')) { 07551 ast_debug(1, "Got some DTMF, but it's for the CAS\n"); 07552 ast_free(p->cidspill); 07553 p->cidspill = NULL; 07554 send_cwcidspill(p); 07555 } 07556 p->callwaitcas = 0; 07557 } 07558 p->subs[idx].f.frametype = AST_FRAME_NULL; 07559 p->subs[idx].f.subclass.integer = 0; 07560 *dest = &p->subs[idx].f; 07561 } else if (f->subclass.integer == 'f') { 07562 if (f->frametype == AST_FRAME_DTMF_END) { 07563 /* Fax tone -- Handle and return NULL */ 07564 if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) { 07565 /* If faxbuffers are configured, use them for the fax transmission */ 07566 if (p->usefaxbuffers && !p->bufferoverrideinuse) { 07567 struct dahdi_bufferinfo bi = { 07568 .txbufpolicy = p->faxbuf_policy, 07569 .bufsize = p->bufsize, 07570 .numbufs = p->faxbuf_no 07571 }; 07572 int res; 07573 07574 if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 07575 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast->name, strerror(errno)); 07576 } else { 07577 p->bufferoverrideinuse = 1; 07578 } 07579 } 07580 p->faxhandled = 1; 07581 if (p->dsp) { 07582 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 07583 ast_dsp_set_features(p->dsp, p->dsp_features); 07584 ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast->name); 07585 } 07586 if (strcmp(ast->exten, "fax")) { 07587 const char *target_context = S_OR(ast->macrocontext, ast->context); 07588 07589 /* We need to unlock 'ast' here because ast_exists_extension has the 07590 * potential to start autoservice on the channel. Such action is prone 07591 * to deadlock. 07592 */ 07593 ast_mutex_unlock(&p->lock); 07594 ast_channel_unlock(ast); 07595 if (ast_exists_extension(ast, target_context, "fax", 1, 07596 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 07597 ast_channel_lock(ast); 07598 ast_mutex_lock(&p->lock); 07599 ast_verb(3, "Redirecting %s to fax extension\n", ast->name); 07600 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 07601 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 07602 if (ast_async_goto(ast, target_context, "fax", 1)) 07603 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 07604 } else { 07605 ast_channel_lock(ast); 07606 ast_mutex_lock(&p->lock); 07607 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 07608 } 07609 } else { 07610 ast_debug(1, "Already in a fax extension, not redirecting\n"); 07611 } 07612 } else { 07613 ast_debug(1, "Fax already handled\n"); 07614 } 07615 dahdi_confmute(p, 0); 07616 } 07617 p->subs[idx].f.frametype = AST_FRAME_NULL; 07618 p->subs[idx].f.subclass.integer = 0; 07619 *dest = &p->subs[idx].f; 07620 } 07621 }
static struct ast_frame* dahdi_handle_event | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 7644 of file chan_dahdi.c.
References ast_channel::_softhangup, ast_channel::_state, alloc_sub(), analog_ss_thread(), ast_party_caller::ani, ast_party_caller::ani2, dahdi_pvt::answeronpolarityswitch, ast_bridged_channel(), AST_CAUSE_NO_ANSWER, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached, ast_queue_control(), ast_queue_control_data(), ast_queue_hangup_with_cause(), 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_tvdiff_ms(), ast_tvnow(), ast_verb, attempt_transfer(), ast_channel::caller, CALLPROGRESS_PROGRESS, dahdi_pvt::callwaitcas, CANPROGRESSDETECT, dahdi_pvt::channel, CHANNEL_DEADLOCK_AVOIDANCE, check_for_conference(), dahdi_pvt::cid_name, cid_name, dahdi_pvt::cid_num, cid_num, dahdi_pvt::cidspill, dahdi_pvt::confirmanswer, dahdi_confmute(), dahdi_disable_ec(), dahdi_enable_ec(), dahdi_get_event(), dahdi_get_index, dahdi_handle_dtmf(), dahdi_new(), DAHDI_OVERLAPDIAL_INCOMING, dahdi_ring_phone(), dahdi_set_hook(), dahdi_sig_pri_lib_handles(), dahdi_train_ec(), dahdi_pvt::dahditrcallerid, ast_frame::data, ast_frame::datalen, dahdi_subchannel::dfd, dahdi_pvt::dialdest, dahdi_pvt::dialing, DLA_LOCK, DLA_UNLOCK, dahdi_pvt::dop, dahdi_pvt::echobreak, dahdi_pvt::echocanon, dahdi_pvt::echorest, dahdi_pvt::echotraining, errno, event2str(), dahdi_subchannel::f, f, dahdi_pvt::fake_event, dahdi_pvt::finaldial, dahdi_pvt::flashtime, ast_frame::frametype, get_alarms(), handle_alarms(), handle_clear_alarms(), dahdi_pvt::hanguponpolarityswitch, has_voicemail(), ast_party_caller::id, dahdi_pvt::inalarm, ast_frame_subclass::integer, dahdi_subchannel::inthreeway, dahdi_pvt::lock, LOG_DEBUG, LOG_NOTICE, ast_frame::mallocd, MIN_MS_SINCE_FLASH, dahdi_pvt::mohsuggest, ast_party_id::name, ast_channel::name, dahdi_subchannel::needflash, dahdi_subchannel::needhold, dahdi_subchannel::needringing, dahdi_subchannel::needunhold, ast_party_id::number, ast_frame::offset, dahdi_pvt::oprmode, dahdi_pvt::oprpeer, dahdi_pvt::origcid_name, dahdi_pvt::origcid_num, dahdi_pvt::outgoing, dahdi_pvt::outsigmod, sig_pri_span::overlapdial, dahdi_subchannel::owner, dahdi_pvt::owner, ast_channel::pbx, dahdi_pvt::polarity, POLARITY_IDLE, POLARITY_REV, dahdi_pvt::polaritydelaytv, dahdi_pvt::polarityonanswerdelay, sig_pri_span::pri, dahdi_pvt::pri, ast_frame::ptr, dahdi_pvt::pulsedial, dahdi_pvt::r2chan, dahdi_pvt::radio, restore_conference(), ast_channel::rings, dahdi_pvt::ringt, dahdi_pvt::ringt_base, S_COR, S_OR, ast_frame::samples, save_conference(), dahdi_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_MFCR2, sig_pri_chan_alarm_notify(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, SIG_SS7, sig_ss7_set_alarm(), ast_frame::src, ast_party_name::str, ast_party_number::str, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, dahdi_pvt::subs, swap_subs(), ast_channel::tech_pvt, dahdi_pvt::threewaycalling, dahdi_pvt::transfer, dahdi_pvt::transfertobusy, unalloc_sub(), update_conf(), ast_party_name::valid, ast_party_number::valid, dahdi_pvt::waitingfordt, and dahdi_pvt::whichwink.
Referenced by __dahdi_exception().
07645 { 07646 int res, x; 07647 int idx, mysig; 07648 char *c; 07649 struct dahdi_pvt *p = ast->tech_pvt; 07650 pthread_t threadid; 07651 struct ast_channel *chan; 07652 struct ast_frame *f; 07653 07654 idx = dahdi_get_index(ast, p, 0); 07655 mysig = p->sig; 07656 if (p->outsigmod > -1) 07657 mysig = p->outsigmod; 07658 p->subs[idx].f.frametype = AST_FRAME_NULL; 07659 p->subs[idx].f.subclass.integer = 0; 07660 p->subs[idx].f.datalen = 0; 07661 p->subs[idx].f.samples = 0; 07662 p->subs[idx].f.mallocd = 0; 07663 p->subs[idx].f.offset = 0; 07664 p->subs[idx].f.src = "dahdi_handle_event"; 07665 p->subs[idx].f.data.ptr = NULL; 07666 f = &p->subs[idx].f; 07667 07668 if (idx < 0) 07669 return &p->subs[idx].f; 07670 if (p->fake_event) { 07671 res = p->fake_event; 07672 p->fake_event = 0; 07673 } else 07674 res = dahdi_get_event(p->subs[idx].dfd); 07675 07676 ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, idx); 07677 07678 if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) { 07679 p->pulsedial = (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0; 07680 ast_debug(1, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 07681 #if defined(HAVE_PRI) 07682 if (dahdi_sig_pri_lib_handles(p->sig) 07683 && !((struct sig_pri_chan *) p->sig_pvt)->proceeding 07684 && p->pri 07685 && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 07686 /* absorb event */ 07687 } else 07688 #endif /* defined(HAVE_PRI) */ 07689 { 07690 /* Unmute conference */ 07691 dahdi_confmute(p, 0); 07692 p->subs[idx].f.frametype = AST_FRAME_DTMF_END; 07693 p->subs[idx].f.subclass.integer = res & 0xff; 07694 dahdi_handle_dtmf(ast, idx, &f); 07695 } 07696 return f; 07697 } 07698 07699 if (res & DAHDI_EVENT_DTMFDOWN) { 07700 ast_debug(1, "DTMF Down '%c'\n", res & 0xff); 07701 #if defined(HAVE_PRI) 07702 if (dahdi_sig_pri_lib_handles(p->sig) 07703 && !((struct sig_pri_chan *) p->sig_pvt)->proceeding 07704 && p->pri 07705 && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 07706 /* absorb event */ 07707 } else 07708 #endif /* defined(HAVE_PRI) */ 07709 { 07710 /* Mute conference */ 07711 dahdi_confmute(p, 1); 07712 p->subs[idx].f.frametype = AST_FRAME_DTMF_BEGIN; 07713 p->subs[idx].f.subclass.integer = res & 0xff; 07714 dahdi_handle_dtmf(ast, idx, &f); 07715 } 07716 return &p->subs[idx].f; 07717 } 07718 07719 switch (res) { 07720 case DAHDI_EVENT_EC_DISABLED: 07721 ast_verb(3, "Channel %d echo canceler disabled.\n", p->channel); 07722 p->echocanon = 0; 07723 break; 07724 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 07725 case DAHDI_EVENT_TX_CED_DETECTED: 07726 ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel); 07727 break; 07728 case DAHDI_EVENT_RX_CED_DETECTED: 07729 ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel); 07730 break; 07731 case DAHDI_EVENT_EC_NLP_DISABLED: 07732 ast_verb(3, "Channel %d echo canceler disabled its NLP.\n", p->channel); 07733 break; 07734 case DAHDI_EVENT_EC_NLP_ENABLED: 07735 ast_verb(3, "Channel %d echo canceler enabled its NLP.\n", p->channel); 07736 break; 07737 #endif 07738 case DAHDI_EVENT_BITSCHANGED: 07739 #ifdef HAVE_OPENR2 07740 if (p->sig != SIG_MFCR2) { 07741 ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig)); 07742 } else { 07743 ast_log(LOG_DEBUG, "bits changed in chan %d\n", p->channel); 07744 openr2_chan_handle_cas(p->r2chan); 07745 } 07746 #else 07747 ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig)); 07748 #endif 07749 case DAHDI_EVENT_PULSE_START: 07750 /* Stop tone if there's a pulse start and the PBX isn't started */ 07751 if (!ast->pbx) 07752 tone_zone_play_tone(p->subs[idx].dfd, -1); 07753 break; 07754 case DAHDI_EVENT_DIALCOMPLETE: 07755 #ifdef HAVE_OPENR2 07756 if ((p->sig & SIG_MFCR2) && p->r2chan && ast->_state != AST_STATE_UP) { 07757 /* we don't need to do anything for this event for R2 signaling 07758 if the call is being setup */ 07759 break; 07760 } 07761 #endif 07762 if (p->inalarm) break; 07763 if ((p->radio || (p->oprmode < 0))) break; 07764 if (ioctl(p->subs[idx].dfd,DAHDI_DIALING,&x) == -1) { 07765 ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed on %s: %s\n",ast->name, strerror(errno)); 07766 return NULL; 07767 } 07768 if (!x) { /* if not still dialing in driver */ 07769 dahdi_enable_ec(p); 07770 if (p->echobreak) { 07771 dahdi_train_ec(p); 07772 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 07773 p->dop.op = DAHDI_DIAL_OP_REPLACE; 07774 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 07775 p->echobreak = 0; 07776 } else { 07777 p->dialing = 0; 07778 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) { 07779 /* if thru with dialing after offhook */ 07780 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 07781 ast_setstate(ast, AST_STATE_UP); 07782 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 07783 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 07784 break; 07785 } else { /* if to state wait for offhook to dial rest */ 07786 /* we now wait for off hook */ 07787 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 07788 } 07789 } 07790 if (ast->_state == AST_STATE_DIALING) { 07791 if ((p->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 07792 ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n"); 07793 } else if (p->confirmanswer || (!p->dialednone 07794 && ((mysig == SIG_EM) || (mysig == SIG_EM_E1) 07795 || (mysig == SIG_EMWINK) || (mysig == SIG_FEATD) 07796 || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF) 07797 || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) 07798 || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB) 07799 || (mysig == SIG_SF) || (mysig == SIG_SFWINK) 07800 || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF) 07801 || (mysig == SIG_SF_FEATB)))) { 07802 ast_setstate(ast, AST_STATE_RINGING); 07803 } else if (!p->answeronpolarityswitch) { 07804 ast_setstate(ast, AST_STATE_UP); 07805 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 07806 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 07807 /* If aops=0 and hops=1, this is necessary */ 07808 p->polarity = POLARITY_REV; 07809 } else { 07810 /* Start clean, so we can catch the change to REV polarity when party answers */ 07811 p->polarity = POLARITY_IDLE; 07812 } 07813 } 07814 } 07815 } 07816 break; 07817 case DAHDI_EVENT_ALARM: 07818 switch (p->sig) { 07819 #if defined(HAVE_PRI) 07820 case SIG_PRI_LIB_HANDLE_CASES: 07821 sig_pri_chan_alarm_notify(p->sig_pvt, 0); 07822 break; 07823 #endif /* defined(HAVE_PRI) */ 07824 #if defined(HAVE_SS7) 07825 case SIG_SS7: 07826 sig_ss7_set_alarm(p->sig_pvt, 1); 07827 break; 07828 #endif /* defined(HAVE_SS7) */ 07829 default: 07830 p->inalarm = 1; 07831 break; 07832 } 07833 res = get_alarms(p); 07834 handle_alarms(p, res); 07835 #ifdef HAVE_PRI 07836 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 07837 /* fall through intentionally */ 07838 } else { 07839 break; 07840 } 07841 #endif 07842 #if defined(HAVE_SS7) 07843 if (p->sig == SIG_SS7) 07844 break; 07845 #endif /* defined(HAVE_SS7) */ 07846 #ifdef HAVE_OPENR2 07847 if (p->sig == SIG_MFCR2) 07848 break; 07849 #endif 07850 case DAHDI_EVENT_ONHOOK: 07851 if (p->radio) { 07852 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 07853 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_UNKEY; 07854 break; 07855 } 07856 if (p->oprmode < 0) 07857 { 07858 if (p->oprmode != -1) break; 07859 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 07860 { 07861 /* Make sure it starts ringing */ 07862 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 07863 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RING); 07864 save_conference(p->oprpeer); 07865 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 07866 } 07867 break; 07868 } 07869 switch (p->sig) { 07870 case SIG_FXOLS: 07871 case SIG_FXOGS: 07872 case SIG_FXOKS: 07873 /* Check for some special conditions regarding call waiting */ 07874 if (idx == SUB_REAL) { 07875 /* The normal line was hung up */ 07876 if (p->subs[SUB_CALLWAIT].owner) { 07877 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 07878 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 07879 ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel); 07880 unalloc_sub(p, SUB_CALLWAIT); 07881 #if 0 07882 p->subs[idx].needanswer = 0; 07883 p->subs[idx].needringing = 0; 07884 #endif 07885 p->callwaitingrepeat = 0; 07886 p->cidcwexpire = 0; 07887 p->cid_suppress_expire = 0; 07888 p->owner = NULL; 07889 /* Don't start streaming audio yet if the incoming call isn't up yet */ 07890 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 07891 p->dialing = 1; 07892 dahdi_ring_phone(p); 07893 } else if (p->subs[SUB_THREEWAY].owner) { 07894 unsigned int mssinceflash; 07895 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 07896 the private structure -- not especially easy or clean */ 07897 while (p->subs[SUB_THREEWAY].owner && ast_channel_trylock(p->subs[SUB_THREEWAY].owner)) { 07898 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 07899 DLA_UNLOCK(&p->lock); 07900 CHANNEL_DEADLOCK_AVOIDANCE(ast); 07901 /* We can grab ast and p in that order, without worry. We should make sure 07902 nothing seriously bad has happened though like some sort of bizarre double 07903 masquerade! */ 07904 DLA_LOCK(&p->lock); 07905 if (p->owner != ast) { 07906 ast_log(LOG_WARNING, "This isn't good...\n"); 07907 return NULL; 07908 } 07909 } 07910 if (!p->subs[SUB_THREEWAY].owner) { 07911 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 07912 return NULL; 07913 } 07914 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 07915 ast_debug(1, "Last flash was %d ms ago\n", mssinceflash); 07916 if (mssinceflash < MIN_MS_SINCE_FLASH) { 07917 /* It hasn't been long enough since the last flashook. This is probably a bounce on 07918 hanging up. Hangup both channels now */ 07919 if (p->subs[SUB_THREEWAY].owner) 07920 ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY].owner, AST_CAUSE_NO_ANSWER); 07921 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 07922 ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 07923 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 07924 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 07925 if (p->transfer) { 07926 /* In any case this isn't a threeway call anymore */ 07927 p->subs[SUB_REAL].inthreeway = 0; 07928 p->subs[SUB_THREEWAY].inthreeway = 0; 07929 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 07930 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 07931 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 07932 /* Swap subs and dis-own channel */ 07933 swap_subs(p, SUB_THREEWAY, SUB_REAL); 07934 p->owner = NULL; 07935 /* Ring the phone */ 07936 dahdi_ring_phone(p); 07937 } else { 07938 if ((res = attempt_transfer(p)) < 0) { 07939 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 07940 if (p->subs[SUB_THREEWAY].owner) 07941 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 07942 } else if (res) { 07943 /* Don't actually hang up at this point */ 07944 if (p->subs[SUB_THREEWAY].owner) 07945 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 07946 break; 07947 } 07948 } 07949 } else { 07950 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 07951 if (p->subs[SUB_THREEWAY].owner) 07952 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 07953 } 07954 } else { 07955 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 07956 /* Swap subs and dis-own channel */ 07957 swap_subs(p, SUB_THREEWAY, SUB_REAL); 07958 p->owner = NULL; 07959 /* Ring the phone */ 07960 dahdi_ring_phone(p); 07961 } 07962 } 07963 } else { 07964 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", idx); 07965 } 07966 /* Fall through */ 07967 default: 07968 dahdi_disable_ec(p); 07969 return NULL; 07970 } 07971 break; 07972 case DAHDI_EVENT_RINGOFFHOOK: 07973 if (p->inalarm) break; 07974 if (p->oprmode < 0) 07975 { 07976 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 07977 { 07978 /* Make sure it stops ringing */ 07979 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 07980 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, -1); 07981 restore_conference(p->oprpeer); 07982 } 07983 break; 07984 } 07985 if (p->radio) 07986 { 07987 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 07988 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_KEY; 07989 break; 07990 } 07991 /* for E911, its supposed to wait for offhook then dial 07992 the second half of the dial string */ 07993 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 07994 c = strchr(p->dialdest, '/'); 07995 if (c) 07996 c++; 07997 else 07998 c = p->dialdest; 07999 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 08000 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 08001 if (strlen(p->dop.dialstr) > 4) { 08002 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 08003 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 08004 p->echorest[sizeof(p->echorest) - 1] = '\0'; 08005 p->echobreak = 1; 08006 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 08007 } else 08008 p->echobreak = 0; 08009 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) { 08010 int saveerr = errno; 08011 08012 x = DAHDI_ONHOOK; 08013 ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 08014 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr)); 08015 return NULL; 08016 } 08017 p->dialing = 1; 08018 return &p->subs[idx].f; 08019 } 08020 switch (p->sig) { 08021 case SIG_FXOLS: 08022 case SIG_FXOGS: 08023 case SIG_FXOKS: 08024 switch (ast->_state) { 08025 case AST_STATE_RINGING: 08026 dahdi_enable_ec(p); 08027 dahdi_train_ec(p); 08028 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08029 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08030 /* Make sure it stops ringing */ 08031 p->subs[SUB_REAL].needringing = 0; 08032 dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 08033 ast_debug(1, "channel %d answered\n", p->channel); 08034 08035 /* Cancel any running CallerID spill */ 08036 ast_free(p->cidspill); 08037 p->cidspill = NULL; 08038 restore_conference(p); 08039 08040 p->dialing = 0; 08041 p->callwaitcas = 0; 08042 if (p->confirmanswer) { 08043 /* Ignore answer if "confirm answer" is enabled */ 08044 p->subs[idx].f.frametype = AST_FRAME_NULL; 08045 p->subs[idx].f.subclass.integer = 0; 08046 } else if (!ast_strlen_zero(p->dop.dialstr)) { 08047 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 08048 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08049 if (res < 0) { 08050 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08051 p->dop.dialstr[0] = '\0'; 08052 return NULL; 08053 } else { 08054 ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 08055 p->subs[idx].f.frametype = AST_FRAME_NULL; 08056 p->subs[idx].f.subclass.integer = 0; 08057 p->dialing = 1; 08058 } 08059 p->dop.dialstr[0] = '\0'; 08060 ast_setstate(ast, AST_STATE_DIALING); 08061 } else 08062 ast_setstate(ast, AST_STATE_UP); 08063 return &p->subs[idx].f; 08064 case AST_STATE_DOWN: 08065 ast_setstate(ast, AST_STATE_RING); 08066 ast->rings = 1; 08067 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08068 p->subs[idx].f.subclass.integer = AST_CONTROL_OFFHOOK; 08069 ast_debug(1, "channel %d picked up\n", p->channel); 08070 return &p->subs[idx].f; 08071 case AST_STATE_UP: 08072 /* Make sure it stops ringing */ 08073 dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 08074 /* Okay -- probably call waiting*/ 08075 if (ast_bridged_channel(p->owner)) 08076 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08077 p->subs[idx].needunhold = 1; 08078 break; 08079 case AST_STATE_RESERVED: 08080 /* Start up dialtone */ 08081 if (has_voicemail(p)) 08082 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER); 08083 else 08084 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE); 08085 break; 08086 default: 08087 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 08088 } 08089 break; 08090 case SIG_FXSLS: 08091 case SIG_FXSGS: 08092 case SIG_FXSKS: 08093 if (ast->_state == AST_STATE_RING) { 08094 p->ringt = p->ringt_base; 08095 } 08096 08097 /* If we get a ring then we cannot be in 08098 * reversed polarity. So we reset to idle */ 08099 ast_debug(1, "Setting IDLE polarity due " 08100 "to ring. Old polarity was %d\n", 08101 p->polarity); 08102 p->polarity = POLARITY_IDLE; 08103 08104 /* Fall through */ 08105 case SIG_EM: 08106 case SIG_EM_E1: 08107 case SIG_EMWINK: 08108 case SIG_FEATD: 08109 case SIG_FEATDMF: 08110 case SIG_FEATDMF_TA: 08111 case SIG_E911: 08112 case SIG_FGC_CAMA: 08113 case SIG_FGC_CAMAMF: 08114 case SIG_FEATB: 08115 case SIG_SF: 08116 case SIG_SFWINK: 08117 case SIG_SF_FEATD: 08118 case SIG_SF_FEATDMF: 08119 case SIG_SF_FEATB: 08120 if (ast->_state == AST_STATE_PRERING) 08121 ast_setstate(ast, AST_STATE_RING); 08122 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 08123 ast_debug(1, "Ring detected\n"); 08124 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08125 p->subs[idx].f.subclass.integer = AST_CONTROL_RING; 08126 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 08127 ast_debug(1, "Line answered\n"); 08128 if (p->confirmanswer) { 08129 p->subs[idx].f.frametype = AST_FRAME_NULL; 08130 p->subs[idx].f.subclass.integer = 0; 08131 } else { 08132 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08133 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08134 ast_setstate(ast, AST_STATE_UP); 08135 } 08136 } else if (ast->_state != AST_STATE_RING) 08137 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 08138 break; 08139 default: 08140 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 08141 } 08142 break; 08143 case DAHDI_EVENT_RINGBEGIN: 08144 switch (p->sig) { 08145 case SIG_FXSLS: 08146 case SIG_FXSGS: 08147 case SIG_FXSKS: 08148 if (ast->_state == AST_STATE_RING) { 08149 p->ringt = p->ringt_base; 08150 } 08151 break; 08152 } 08153 break; 08154 case DAHDI_EVENT_RINGERON: 08155 break; 08156 case DAHDI_EVENT_NOALARM: 08157 switch (p->sig) { 08158 #if defined(HAVE_PRI) 08159 case SIG_PRI_LIB_HANDLE_CASES: 08160 sig_pri_chan_alarm_notify(p->sig_pvt, 1); 08161 break; 08162 #endif /* defined(HAVE_PRI) */ 08163 #if defined(HAVE_SS7) 08164 case SIG_SS7: 08165 sig_ss7_set_alarm(p->sig_pvt, 0); 08166 break; 08167 #endif /* defined(HAVE_SS7) */ 08168 default: 08169 p->inalarm = 0; 08170 break; 08171 } 08172 handle_clear_alarms(p); 08173 break; 08174 case DAHDI_EVENT_WINKFLASH: 08175 if (p->inalarm) break; 08176 if (p->radio) break; 08177 if (p->oprmode < 0) break; 08178 if (p->oprmode > 1) 08179 { 08180 struct dahdi_params par; 08181 08182 memset(&par, 0, sizeof(par)); 08183 if (ioctl(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par) != -1) 08184 { 08185 if (!par.rxisoffhook) 08186 { 08187 /* Make sure it stops ringing */ 08188 dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 08189 dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RING); 08190 save_conference(p); 08191 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 08192 } 08193 } 08194 break; 08195 } 08196 /* Remember last time we got a flash-hook */ 08197 p->flashtime = ast_tvnow(); 08198 switch (mysig) { 08199 case SIG_FXOLS: 08200 case SIG_FXOGS: 08201 case SIG_FXOKS: 08202 ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 08203 idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd); 08204 08205 /* Cancel any running CallerID spill */ 08206 ast_free(p->cidspill); 08207 p->cidspill = NULL; 08208 restore_conference(p); 08209 p->callwaitcas = 0; 08210 08211 if (idx != SUB_REAL) { 08212 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", idx, p->channel); 08213 goto winkflashdone; 08214 } 08215 08216 if (p->subs[SUB_CALLWAIT].owner) { 08217 /* Swap to call-wait */ 08218 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 08219 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 08220 p->owner = p->subs[SUB_REAL].owner; 08221 ast_debug(1, "Making %s the new owner\n", p->owner->name); 08222 if (p->owner->_state == AST_STATE_RINGING) { 08223 ast_setstate(p->owner, AST_STATE_UP); 08224 p->subs[SUB_REAL].needanswer = 1; 08225 } 08226 p->callwaitingrepeat = 0; 08227 p->cidcwexpire = 0; 08228 p->cid_suppress_expire = 0; 08229 /* Start music on hold if appropriate */ 08230 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 08231 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 08232 S_OR(p->mohsuggest, NULL), 08233 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08234 } 08235 p->subs[SUB_CALLWAIT].needhold = 1; 08236 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 08237 ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD, 08238 S_OR(p->mohsuggest, NULL), 08239 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08240 } 08241 p->subs[SUB_REAL].needunhold = 1; 08242 } else if (!p->subs[SUB_THREEWAY].owner) { 08243 if (!p->threewaycalling) { 08244 /* Just send a flash if no 3-way calling */ 08245 p->subs[SUB_REAL].needflash = 1; 08246 goto winkflashdone; 08247 } else if (!check_for_conference(p)) { 08248 char cid_num[256]; 08249 char cid_name[256]; 08250 08251 cid_num[0] = 0; 08252 cid_name[0] = 0; 08253 if (p->dahditrcallerid && p->owner) { 08254 if (p->owner->caller.id.number.valid 08255 && p->owner->caller.id.number.str) { 08256 ast_copy_string(cid_num, p->owner->caller.id.number.str, 08257 sizeof(cid_num)); 08258 } 08259 if (p->owner->caller.id.name.valid 08260 && p->owner->caller.id.name.str) { 08261 ast_copy_string(cid_name, p->owner->caller.id.name.str, 08262 sizeof(cid_name)); 08263 } 08264 } 08265 /* XXX This section needs much more error checking!!! XXX */ 08266 /* Start a 3-way call if feasible */ 08267 if (!((ast->pbx) || 08268 (ast->_state == AST_STATE_UP) || 08269 (ast->_state == AST_STATE_RING))) { 08270 ast_debug(1, "Flash when call not up or ringing\n"); 08271 goto winkflashdone; 08272 } 08273 if (alloc_sub(p, SUB_THREEWAY)) { 08274 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 08275 goto winkflashdone; 08276 } 08277 /* Make new channel */ 08278 chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, NULL); 08279 if (p->dahditrcallerid) { 08280 if (!p->origcid_num) 08281 p->origcid_num = ast_strdup(p->cid_num); 08282 if (!p->origcid_name) 08283 p->origcid_name = ast_strdup(p->cid_name); 08284 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 08285 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 08286 } 08287 /* Swap things around between the three-way and real call */ 08288 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08289 /* Disable echo canceller for better dialing */ 08290 dahdi_disable_ec(p); 08291 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALRECALL); 08292 if (res) 08293 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 08294 p->owner = chan; 08295 if (!chan) { 08296 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 08297 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 08298 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 08299 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 08300 dahdi_enable_ec(p); 08301 ast_hangup(chan); 08302 } else { 08303 ast_verb(3, "Started three way call on channel %d\n", p->channel); 08304 08305 /* Start music on hold if appropriate */ 08306 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 08307 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 08308 S_OR(p->mohsuggest, NULL), 08309 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08310 } 08311 p->subs[SUB_THREEWAY].needhold = 1; 08312 } 08313 } 08314 } else { 08315 /* Already have a 3 way call */ 08316 if (p->subs[SUB_THREEWAY].inthreeway) { 08317 /* Call is already up, drop the last person */ 08318 ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel); 08319 /* If the primary call isn't answered yet, use it */ 08320 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 08321 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 08322 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08323 p->owner = p->subs[SUB_REAL].owner; 08324 } 08325 /* Drop the last call and stop the conference */ 08326 ast_verb(3, "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name); 08327 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08328 p->subs[SUB_REAL].inthreeway = 0; 08329 p->subs[SUB_THREEWAY].inthreeway = 0; 08330 } else { 08331 /* Lets see what we're up to */ 08332 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 08333 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 08334 int otherindex = SUB_THREEWAY; 08335 08336 ast_verb(3, "Building conference call with %s and %s\n", 08337 p->subs[SUB_THREEWAY].owner->name, 08338 p->subs[SUB_REAL].owner->name); 08339 /* Put them in the threeway, and flip */ 08340 p->subs[SUB_THREEWAY].inthreeway = 1; 08341 p->subs[SUB_REAL].inthreeway = 1; 08342 if (ast->_state == AST_STATE_UP) { 08343 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08344 otherindex = SUB_REAL; 08345 } 08346 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 08347 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 08348 p->subs[otherindex].needunhold = 1; 08349 p->owner = p->subs[SUB_REAL].owner; 08350 } else { 08351 ast_verb(3, "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name); 08352 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08353 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08354 p->owner = p->subs[SUB_REAL].owner; 08355 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 08356 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 08357 p->subs[SUB_REAL].needunhold = 1; 08358 dahdi_enable_ec(p); 08359 } 08360 } 08361 } 08362 winkflashdone: 08363 update_conf(p); 08364 break; 08365 case SIG_EM: 08366 case SIG_EM_E1: 08367 case SIG_FEATD: 08368 case SIG_SF: 08369 case SIG_SFWINK: 08370 case SIG_SF_FEATD: 08371 case SIG_FXSLS: 08372 case SIG_FXSGS: 08373 if (p->dialing) 08374 ast_debug(1, "Ignoring wink on channel %d\n", p->channel); 08375 else 08376 ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 08377 break; 08378 case SIG_FEATDMF_TA: 08379 switch (p->whichwink) { 08380 case 0: 08381 ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->caller.ani2, 08382 S_COR(p->owner->caller.ani.number.valid, 08383 p->owner->caller.ani.number.str, "")); 08384 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", 08385 p->owner->caller.ani2, 08386 S_COR(p->owner->caller.ani.number.valid, 08387 p->owner->caller.ani.number.str, "")); 08388 break; 08389 case 1: 08390 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 08391 break; 08392 case 2: 08393 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 08394 return NULL; 08395 } 08396 p->whichwink++; 08397 /* Fall through */ 08398 case SIG_FEATDMF: 08399 case SIG_E911: 08400 case SIG_FGC_CAMAMF: 08401 case SIG_FGC_CAMA: 08402 case SIG_FEATB: 08403 case SIG_SF_FEATDMF: 08404 case SIG_SF_FEATB: 08405 case SIG_EMWINK: 08406 /* FGD MF and EMWINK *Must* wait for wink */ 08407 if (!ast_strlen_zero(p->dop.dialstr)) { 08408 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08409 if (res < 0) { 08410 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08411 p->dop.dialstr[0] = '\0'; 08412 return NULL; 08413 } else 08414 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr); 08415 } 08416 p->dop.dialstr[0] = '\0'; 08417 break; 08418 default: 08419 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 08420 } 08421 break; 08422 case DAHDI_EVENT_HOOKCOMPLETE: 08423 if (p->inalarm) break; 08424 if ((p->radio || (p->oprmode < 0))) break; 08425 if (p->waitingfordt.tv_sec) break; 08426 switch (mysig) { 08427 case SIG_FXSLS: /* only interesting for FXS */ 08428 case SIG_FXSGS: 08429 case SIG_FXSKS: 08430 case SIG_EM: 08431 case SIG_EM_E1: 08432 case SIG_EMWINK: 08433 case SIG_FEATD: 08434 case SIG_SF: 08435 case SIG_SFWINK: 08436 case SIG_SF_FEATD: 08437 if (!ast_strlen_zero(p->dop.dialstr)) { 08438 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08439 if (res < 0) { 08440 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08441 p->dop.dialstr[0] = '\0'; 08442 return NULL; 08443 } else 08444 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr); 08445 } 08446 p->dop.dialstr[0] = '\0'; 08447 p->dop.op = DAHDI_DIAL_OP_REPLACE; 08448 break; 08449 case SIG_FEATDMF: 08450 case SIG_FEATDMF_TA: 08451 case SIG_E911: 08452 case SIG_FGC_CAMA: 08453 case SIG_FGC_CAMAMF: 08454 case SIG_FEATB: 08455 case SIG_SF_FEATDMF: 08456 case SIG_SF_FEATB: 08457 ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 08458 break; 08459 default: 08460 break; 08461 } 08462 break; 08463 case DAHDI_EVENT_POLARITY: 08464 /* 08465 * If we get a Polarity Switch event, check to see 08466 * if we should change the polarity state and 08467 * mark the channel as UP or if this is an indication 08468 * of remote end disconnect. 08469 */ 08470 if (p->polarity == POLARITY_IDLE) { 08471 p->polarity = POLARITY_REV; 08472 if (p->answeronpolarityswitch && 08473 ((ast->_state == AST_STATE_DIALING) || 08474 (ast->_state == AST_STATE_RINGING))) { 08475 ast_debug(1, "Answering on polarity switch!\n"); 08476 ast_setstate(p->owner, AST_STATE_UP); 08477 if (p->hanguponpolarityswitch) { 08478 p->polaritydelaytv = ast_tvnow(); 08479 } 08480 } else 08481 ast_debug(1, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 08482 } 08483 /* Removed else statement from here as it was preventing hangups from ever happening*/ 08484 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 08485 if (p->hanguponpolarityswitch && 08486 (p->polarityonanswerdelay > 0) && 08487 (p->polarity == POLARITY_REV) && 08488 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 08489 /* Added log_debug information below to provide a better indication of what is going on */ 08490 ast_debug(1, "Polarity Reversal event occured - DEBUG 1: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %" PRIi64 "\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) ); 08491 08492 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 08493 ast_debug(1, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 08494 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 08495 p->polarity = POLARITY_IDLE; 08496 } else 08497 ast_debug(1, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state); 08498 08499 } else { 08500 p->polarity = POLARITY_IDLE; 08501 ast_debug(1, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 08502 } 08503 /* Added more log_debug information below to provide a better indication of what is going on */ 08504 ast_debug(1, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %" PRIi64 "\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) ); 08505 break; 08506 default: 08507 ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel); 08508 } 08509 return &p->subs[idx].f; 08510 }
static int dahdi_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 6003 of file chan_dahdi.c.
References ast_channel::_state, analog_hangup(), analog_lib_handles(), ast_bridged_channel(), ast_channel_setoption(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, ast_dsp_free(), ast_dsp_set_digitmode(), ast_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_verb, dahdi_pvt::callwaitcas, dahdi_pvt::callwaiting, dahdi_pvt::callwaitingrepeat, dahdi_pvt::channel, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_subaddr, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cid_tag, dahdi_pvt::cidcwexpire, dahdi_pvt::cidspill, dahdi_pvt::confirmanswer, dahdi_ast_cause_to_r2_cause(), dahdi_confmute(), dahdi_disable_ec(), dahdi_get_index, dahdi_r2_disconnect_call(), dahdi_set_hook(), dahdi_setlinear(), dahdi_sig_pri_lib_handles(), dahdi_pvt::destroy, destroy_channel(), dahdi_subchannel::dfd, dahdi_pvt::dialing, dahdi_pvt::didtdd, dahdi_pvt::digital, dahdi_pvt::distinctivering, dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, dahdi_pvt::dtmfrelax, errno, dahdi_pvt::exten, dahdi_pvt::faxhandled, analog_pvt::fxsoffhookstate, dahdi_pvt::guardtime, ast_channel::hangupcause, dahdi_pvt::hidecallerid, iflock, dahdi_pvt::ignoredtmf, dahdi_subchannel::inthreeway, dahdi_pvt::law, dahdi_pvt::law_default, dahdi_subchannel::linear, dahdi_pvt::lock, LOG_DEBUG, LOG_WARNING, dahdi_pvt::mfcr2, dahdi_pvt::mfcr2_forced_release, dahdi_pvt::mfcr2call, dahdi_pvt::mohsuggest, dahdi_pvt::muting, ast_channel::name, dahdi_subchannel::needanswer, dahdi_subchannel::needbusy, dahdi_subchannel::needcongestion, dahdi_subchannel::needflash, dahdi_subchannel::needringing, num_restart_pending, dahdi_pvt::oprmode, dahdi_pvt::origcid_name, dahdi_pvt::origcid_num, dahdi_pvt::outgoing, dahdi_pvt::owner, dahdi_subchannel::owner, pbx_builtin_getvar_helper(), dahdi_pvt::permcallwaiting, dahdi_pvt::permhidecallerid, dahdi_pvt::polarity, POLARITY_IDLE, dahdi_pvt::pulsedial, dahdi_pvt::r2chan, dahdi_pvt::radio, dahdi_pvt::rdnis, reset_conf(), restart_monitor(), dahdi_pvt::restartpending, restore_gains(), revert_fax_buffers(), dahdi_pvt::ringt, S_OR, dahdi_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_MFCR2, sig_pri_hangup(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, sig_ss7_hangup(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, dahdi_pvt::subs, swap_subs(), ast_channel::tech_pvt, unalloc_sub(), update_conf(), and dahdi_pvt::waitingfordt.
06004 { 06005 int res = 0; 06006 int idx,x; 06007 int law; 06008 /*static int restore_gains(struct dahdi_pvt *p);*/ 06009 struct dahdi_pvt *p = ast->tech_pvt; 06010 struct dahdi_params par; 06011 06012 ast_debug(1, "dahdi_hangup(%s)\n", ast->name); 06013 if (!ast->tech_pvt) { 06014 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 06015 return 0; 06016 } 06017 06018 ast_mutex_lock(&p->lock); 06019 p->exten[0] = '\0'; 06020 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 06021 dahdi_confmute(p, 0); 06022 restore_gains(p); 06023 p->ignoredtmf = 0; 06024 p->waitingfordt.tv_sec = 0; 06025 06026 res = analog_hangup(p->sig_pvt, ast); 06027 revert_fax_buffers(p, ast); 06028 06029 goto hangup_out; 06030 } else { 06031 p->cid_num[0] = '\0'; 06032 p->cid_name[0] = '\0'; 06033 p->cid_subaddr[0] = '\0'; 06034 } 06035 06036 #ifdef HAVE_PRI 06037 if (dahdi_sig_pri_lib_handles(p->sig)) { 06038 x = 1; 06039 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 06040 dahdi_confmute(p, 0); 06041 p->muting = 0; 06042 restore_gains(p); 06043 if (p->dsp) { 06044 ast_dsp_free(p->dsp); 06045 p->dsp = NULL; 06046 } 06047 p->ignoredtmf = 0; 06048 revert_fax_buffers(p, ast); 06049 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 06050 p->law = p->law_default; 06051 law = p->law_default; 06052 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06053 dahdi_disable_ec(p); 06054 update_conf(p); 06055 reset_conf(p); 06056 sig_pri_hangup(p->sig_pvt, ast); 06057 p->subs[SUB_REAL].owner = NULL; 06058 p->subs[SUB_REAL].needbusy = 0; 06059 p->owner = NULL; 06060 p->cid_tag[0] = '\0'; 06061 p->ringt = 0;/* Probably not used in this mode. Reset anyway. */ 06062 p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */ 06063 p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */ 06064 p->outgoing = 0; 06065 p->digital = 0; 06066 p->faxhandled = 0; 06067 p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */ 06068 goto hangup_out; 06069 } 06070 #endif 06071 06072 #if defined(HAVE_SS7) 06073 if (p->sig == SIG_SS7) { 06074 x = 1; 06075 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 06076 06077 dahdi_confmute(p, 0); 06078 p->muting = 0; 06079 restore_gains(p); 06080 if (p->dsp) { 06081 ast_dsp_free(p->dsp); 06082 p->dsp = NULL; 06083 } 06084 p->ignoredtmf = 0; 06085 06086 /* Real channel, do some fixup */ 06087 p->subs[SUB_REAL].owner = NULL; 06088 p->subs[SUB_REAL].needbusy = 0; 06089 p->polarity = POLARITY_IDLE; 06090 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 06091 06092 p->owner = NULL; 06093 p->ringt = 0;/* Probably not used in this mode. Reset anyway. */ 06094 p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */ 06095 p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */ 06096 p->outgoing = 0; 06097 p->digital = 0; 06098 p->faxhandled = 0; 06099 p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */ 06100 06101 revert_fax_buffers(p, ast); 06102 06103 p->law = p->law_default; 06104 law = p->law_default; 06105 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06106 if (res < 0) 06107 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno)); 06108 06109 sig_ss7_hangup(p->sig_pvt, ast); 06110 06111 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06112 dahdi_disable_ec(p); 06113 x = 0; 06114 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 06115 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 06116 p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */ 06117 update_conf(p); 06118 reset_conf(p); 06119 06120 /* Restore data mode */ 06121 x = 0; 06122 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 06123 06124 if (num_restart_pending == 0) 06125 restart_monitor(); 06126 06127 ast->tech_pvt = NULL; 06128 goto hangup_out; 06129 } 06130 #endif /* defined(HAVE_SS7) */ 06131 06132 idx = dahdi_get_index(ast, p, 1); 06133 06134 dahdi_confmute(p, 0); 06135 p->muting = 0; 06136 restore_gains(p); 06137 if (p->origcid_num) { 06138 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 06139 ast_free(p->origcid_num); 06140 p->origcid_num = NULL; 06141 } 06142 if (p->origcid_name) { 06143 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 06144 ast_free(p->origcid_name); 06145 p->origcid_name = NULL; 06146 } 06147 if (p->dsp) 06148 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 06149 06150 ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 06151 p->channel, idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd); 06152 p->ignoredtmf = 0; 06153 06154 if (idx > -1) { 06155 /* Real channel, do some fixup */ 06156 p->subs[idx].owner = NULL; 06157 p->subs[idx].needanswer = 0; 06158 p->subs[idx].needflash = 0; 06159 p->subs[idx].needringing = 0; 06160 p->subs[idx].needbusy = 0; 06161 p->subs[idx].needcongestion = 0; 06162 p->subs[idx].linear = 0; 06163 p->polarity = POLARITY_IDLE; 06164 dahdi_setlinear(p->subs[idx].dfd, 0); 06165 if (idx == SUB_REAL) { 06166 if ((p->subs[SUB_CALLWAIT].dfd > -1) && (p->subs[SUB_THREEWAY].dfd > -1)) { 06167 ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n"); 06168 if (p->subs[SUB_CALLWAIT].inthreeway) { 06169 /* We had flipped over to answer a callwait and now it's gone */ 06170 ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n"); 06171 /* Move to the call-wait, but un-own us until they flip back. */ 06172 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 06173 unalloc_sub(p, SUB_CALLWAIT); 06174 p->owner = NULL; 06175 } else { 06176 /* The three way hung up, but we still have a call wait */ 06177 ast_debug(1, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 06178 swap_subs(p, SUB_THREEWAY, SUB_REAL); 06179 unalloc_sub(p, SUB_THREEWAY); 06180 if (p->subs[SUB_REAL].inthreeway) { 06181 /* This was part of a three way call. Immediately make way for 06182 another call */ 06183 ast_debug(1, "Call was complete, setting owner to former third call\n"); 06184 p->owner = p->subs[SUB_REAL].owner; 06185 } else { 06186 /* This call hasn't been completed yet... Set owner to NULL */ 06187 ast_debug(1, "Call was incomplete, setting owner to NULL\n"); 06188 p->owner = NULL; 06189 } 06190 p->subs[SUB_REAL].inthreeway = 0; 06191 } 06192 } else if (p->subs[SUB_CALLWAIT].dfd > -1) { 06193 /* Move to the call-wait and switch back to them. */ 06194 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 06195 unalloc_sub(p, SUB_CALLWAIT); 06196 p->owner = p->subs[SUB_REAL].owner; 06197 if (p->owner->_state != AST_STATE_UP) 06198 p->subs[SUB_REAL].needanswer = 1; 06199 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 06200 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 06201 } else if (p->subs[SUB_THREEWAY].dfd > -1) { 06202 swap_subs(p, SUB_THREEWAY, SUB_REAL); 06203 unalloc_sub(p, SUB_THREEWAY); 06204 if (p->subs[SUB_REAL].inthreeway) { 06205 /* This was part of a three way call. Immediately make way for 06206 another call */ 06207 ast_debug(1, "Call was complete, setting owner to former third call\n"); 06208 p->owner = p->subs[SUB_REAL].owner; 06209 } else { 06210 /* This call hasn't been completed yet... Set owner to NULL */ 06211 ast_debug(1, "Call was incomplete, setting owner to NULL\n"); 06212 p->owner = NULL; 06213 } 06214 p->subs[SUB_REAL].inthreeway = 0; 06215 } 06216 } else if (idx == SUB_CALLWAIT) { 06217 /* Ditch the holding callwait call, and immediately make it availabe */ 06218 if (p->subs[SUB_CALLWAIT].inthreeway) { 06219 /* This is actually part of a three way, placed on hold. Place the third part 06220 on music on hold now */ 06221 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 06222 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 06223 S_OR(p->mohsuggest, NULL), 06224 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 06225 } 06226 p->subs[SUB_THREEWAY].inthreeway = 0; 06227 /* Make it the call wait now */ 06228 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 06229 unalloc_sub(p, SUB_THREEWAY); 06230 } else 06231 unalloc_sub(p, SUB_CALLWAIT); 06232 } else if (idx == SUB_THREEWAY) { 06233 if (p->subs[SUB_CALLWAIT].inthreeway) { 06234 /* The other party of the three way call is currently in a call-wait state. 06235 Start music on hold for them, and take the main guy out of the third call */ 06236 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 06237 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 06238 S_OR(p->mohsuggest, NULL), 06239 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 06240 } 06241 p->subs[SUB_CALLWAIT].inthreeway = 0; 06242 } 06243 p->subs[SUB_REAL].inthreeway = 0; 06244 /* If this was part of a three way call index, let us make 06245 another three way call */ 06246 unalloc_sub(p, SUB_THREEWAY); 06247 } else { 06248 /* This wasn't any sort of call, but how are we an index? */ 06249 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 06250 } 06251 } 06252 06253 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 06254 p->owner = NULL; 06255 p->ringt = 0; 06256 p->distinctivering = 0; 06257 p->confirmanswer = 0; 06258 p->outgoing = 0; 06259 p->digital = 0; 06260 p->faxhandled = 0; 06261 p->pulsedial = 0; 06262 if (p->dsp) { 06263 ast_dsp_free(p->dsp); 06264 p->dsp = NULL; 06265 } 06266 06267 revert_fax_buffers(p, ast); 06268 06269 p->law = p->law_default; 06270 law = p->law_default; 06271 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06272 if (res < 0) 06273 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno)); 06274 /* Perform low level hangup if no owner left */ 06275 #ifdef HAVE_OPENR2 06276 if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) { 06277 ast_log(LOG_DEBUG, "disconnecting MFC/R2 call on chan %d\n", p->channel); 06278 /* If it's an incoming call, check the mfcr2_forced_release setting */ 06279 if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) { 06280 dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE); 06281 } else { 06282 const char *r2causestr = pbx_builtin_getvar_helper(ast, "MFCR2_CAUSE"); 06283 int r2cause_user = r2causestr ? atoi(r2causestr) : 0; 06284 openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user) 06285 : dahdi_ast_cause_to_r2_cause(ast->hangupcause); 06286 dahdi_r2_disconnect_call(p, r2cause); 06287 } 06288 } else if (p->mfcr2call) { 06289 ast_log(LOG_DEBUG, "Clearing call request on channel %d\n", p->channel); 06290 /* since ast_request() was called but not ast_call() we have not yet dialed 06291 and the openr2 stack will not call on_call_end callback, we need to unset 06292 the mfcr2call flag and bump the monitor count so the monitor thread can take 06293 care of this channel events from now on */ 06294 p->mfcr2call = 0; 06295 } 06296 #endif 06297 switch (p->sig) { 06298 case SIG_SS7: 06299 case SIG_MFCR2: 06300 case SIG_PRI_LIB_HANDLE_CASES: 06301 case 0: 06302 break; 06303 default: 06304 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 06305 break; 06306 } 06307 if (res < 0) { 06308 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 06309 } 06310 switch (p->sig) { 06311 case SIG_FXOGS: 06312 case SIG_FXOLS: 06313 case SIG_FXOKS: 06314 memset(&par, 0, sizeof(par)); 06315 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par); 06316 if (!res) { 06317 struct analog_pvt *analog_p = p->sig_pvt; 06318 #if 0 06319 ast_debug(1, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 06320 #endif 06321 /* If they're off hook, try playing congestion */ 06322 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0)))) 06323 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 06324 else 06325 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06326 analog_p->fxsoffhookstate = par.rxisoffhook; 06327 } 06328 break; 06329 case SIG_FXSGS: 06330 case SIG_FXSLS: 06331 case SIG_FXSKS: 06332 /* Make sure we're not made available for at least two seconds assuming 06333 we were actually used for an inbound or outbound call. */ 06334 if (ast->_state != AST_STATE_RESERVED) { 06335 time(&p->guardtime); 06336 p->guardtime += 2; 06337 } 06338 break; 06339 default: 06340 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06341 } 06342 if (p->sig) 06343 dahdi_disable_ec(p); 06344 x = 0; 06345 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 06346 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 06347 p->didtdd = 0; 06348 p->callwaitcas = 0; 06349 p->callwaiting = p->permcallwaiting; 06350 p->hidecallerid = p->permhidecallerid; 06351 p->waitingfordt.tv_sec = 0; 06352 p->dialing = 0; 06353 p->rdnis[0] = '\0'; 06354 update_conf(p); 06355 reset_conf(p); 06356 /* Restore data mode */ 06357 switch (p->sig) { 06358 case SIG_PRI_LIB_HANDLE_CASES: 06359 case SIG_SS7: 06360 x = 0; 06361 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 06362 break; 06363 default: 06364 break; 06365 } 06366 if (num_restart_pending == 0) 06367 restart_monitor(); 06368 } 06369 06370 p->callwaitingrepeat = 0; 06371 p->cidcwexpire = 0; 06372 p->cid_suppress_expire = 0; 06373 p->oprmode = 0; 06374 ast->tech_pvt = NULL; 06375 hangup_out: 06376 ast_free(p->cidspill); 06377 p->cidspill = NULL; 06378 06379 ast_mutex_unlock(&p->lock); 06380 ast_module_unref(ast_module_info->self); 06381 ast_verb(3, "Hungup '%s'\n", ast->name); 06382 06383 ast_mutex_lock(&iflock); 06384 06385 if (p->restartpending) { 06386 num_restart_pending--; 06387 } 06388 06389 if (p->destroy) { 06390 destroy_channel(p, 0); 06391 } 06392 ast_mutex_unlock(&iflock); 06393 return 0; 06394 }
static void dahdi_iflist_extract | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5404 of file chan_dahdi.c.
References DAHDI_IFLIST_NONE, ifend, iflist, dahdi_pvt::next, dahdi_pvt::prev, and dahdi_pvt::which_iflist.
Referenced by destroy_dahdi_pvt().
05405 { 05406 /* Extract from the forward chain. */ 05407 if (pvt->prev) { 05408 pvt->prev->next = pvt->next; 05409 } else if (iflist == pvt) { 05410 /* Node is at the head of the list. */ 05411 iflist = pvt->next; 05412 } 05413 05414 /* Extract from the reverse chain. */ 05415 if (pvt->next) { 05416 pvt->next->prev = pvt->prev; 05417 } else if (ifend == pvt) { 05418 /* Node is at the end of the list. */ 05419 ifend = pvt->prev; 05420 } 05421 05422 /* Node is no longer in the list. */ 05423 pvt->which_iflist = DAHDI_IFLIST_NONE; 05424 pvt->prev = NULL; 05425 pvt->next = NULL; 05426 }
static void dahdi_iflist_insert | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5354 of file chan_dahdi.c.
References dahdi_pvt::channel, DAHDI_IFLIST_MAIN, iflist, dahdi_pvt::next, dahdi_pvt::prev, and dahdi_pvt::which_iflist.
Referenced by duplicate_pseudo().
05355 { 05356 struct dahdi_pvt *cur; 05357 05358 pvt->which_iflist = DAHDI_IFLIST_MAIN; 05359 05360 /* Find place in middle of list for the new interface. */ 05361 for (cur = iflist; cur; cur = cur->next) { 05362 if (pvt->channel < cur->channel) { 05363 /* New interface goes before the current interface. */ 05364 pvt->prev = cur->prev; 05365 pvt->next = cur; 05366 if (cur->prev) { 05367 /* Insert into the middle of the list. */ 05368 cur->prev->next = pvt; 05369 } else { 05370 /* Insert at head of list. */ 05371 iflist = pvt; 05372 } 05373 cur->prev = pvt; 05374 return; 05375 } 05376 } 05377 05378 /* New interface goes onto the end of the list */ 05379 pvt->prev = ifend; 05380 pvt->next = NULL; 05381 if (ifend) { 05382 ifend->next = pvt; 05383 } 05384 ifend = pvt; 05385 if (!iflist) { 05386 /* List was empty */ 05387 iflist = pvt; 05388 } 05389 }
static int dahdi_indicate | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 9126 of file chan_dahdi.c.
References ast_channel::_state, AST_CAUSE_CONGESTION, 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_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, dahdi_get_index, dahdi_set_hook(), dahdi_subchannel::dfd, dahdi_pvt::dop, errno, ast_channel::hangupcause, ISTRUNK, dahdi_pvt::lock, dahdi_pvt::mfcr2, dahdi_pvt::mfcr2_call_accepted, dahdi_pvt::mohinterpret, ast_channel::name, dahdi_pvt::radio, dahdi_pvt::sig, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, sig_pri_indicate(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, sig_ss7_indicate(), SUB_REAL, dahdi_pvt::subs, and ast_channel::tech_pvt.
09127 { 09128 struct dahdi_pvt *p = chan->tech_pvt; 09129 int res=-1; 09130 int idx; 09131 int func = DAHDI_FLASH; 09132 09133 ast_mutex_lock(&p->lock); 09134 ast_debug(1, "Requested indication %d on channel %s\n", condition, chan->name); 09135 switch (p->sig) { 09136 #if defined(HAVE_PRI) 09137 case SIG_PRI_LIB_HANDLE_CASES: 09138 res = sig_pri_indicate(p->sig_pvt, chan, condition, data, datalen); 09139 ast_mutex_unlock(&p->lock); 09140 return res; 09141 #endif /* defined(HAVE_PRI) */ 09142 #if defined(HAVE_SS7) 09143 case SIG_SS7: 09144 res = sig_ss7_indicate(p->sig_pvt, chan, condition, data, datalen); 09145 ast_mutex_unlock(&p->lock); 09146 return res; 09147 #endif /* defined(HAVE_SS7) */ 09148 default: 09149 break; 09150 } 09151 #ifdef HAVE_OPENR2 09152 if (p->mfcr2 && !p->mfcr2_call_accepted) { 09153 ast_mutex_unlock(&p->lock); 09154 /* if this is an R2 call and the call is not yet accepted, we don't want the 09155 tone indications to mess up with the MF tones */ 09156 return 0; 09157 } 09158 #endif 09159 idx = dahdi_get_index(chan, p, 0); 09160 if (idx == SUB_REAL) { 09161 switch (condition) { 09162 case AST_CONTROL_BUSY: 09163 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_BUSY); 09164 break; 09165 case AST_CONTROL_RINGING: 09166 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_RINGTONE); 09167 09168 if (chan->_state != AST_STATE_UP) { 09169 if ((chan->_state != AST_STATE_RING) || 09170 ((p->sig != SIG_FXSKS) && 09171 (p->sig != SIG_FXSLS) && 09172 (p->sig != SIG_FXSGS))) 09173 ast_setstate(chan, AST_STATE_RINGING); 09174 } 09175 break; 09176 case AST_CONTROL_PROCEEDING: 09177 ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 09178 /* don't continue in ast_indicate */ 09179 res = 0; 09180 break; 09181 case AST_CONTROL_PROGRESS: 09182 ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 09183 /* don't continue in ast_indicate */ 09184 res = 0; 09185 break; 09186 case AST_CONTROL_CONGESTION: 09187 chan->hangupcause = AST_CAUSE_CONGESTION; 09188 break; 09189 case AST_CONTROL_HOLD: 09190 ast_moh_start(chan, data, p->mohinterpret); 09191 break; 09192 case AST_CONTROL_UNHOLD: 09193 ast_moh_stop(chan); 09194 break; 09195 case AST_CONTROL_RADIO_KEY: 09196 if (p->radio) 09197 res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 09198 res = 0; 09199 break; 09200 case AST_CONTROL_RADIO_UNKEY: 09201 if (p->radio) 09202 res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_RINGOFF); 09203 res = 0; 09204 break; 09205 case AST_CONTROL_FLASH: 09206 /* flash hookswitch */ 09207 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 09208 /* Clear out the dial buffer */ 09209 p->dop.dialstr[0] = '\0'; 09210 if ((ioctl(p->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 09211 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 09212 chan->name, strerror(errno)); 09213 } else 09214 res = 0; 09215 } else 09216 res = 0; 09217 break; 09218 case AST_CONTROL_SRCUPDATE: 09219 res = 0; 09220 break; 09221 case -1: 09222 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 09223 break; 09224 } 09225 } else { 09226 res = 0; 09227 } 09228 ast_mutex_unlock(&p->lock); 09229 return res; 09230 }
Definition at line 6974 of file chan_dahdi.c.
References ast_log(), LOG_WARNING, and dahdi_pvt::slaves.
Referenced by dahdi_bridge().
06974 { 06975 int x; 06976 if (!slave || !master) { 06977 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 06978 return; 06979 } 06980 for (x = 0; x < MAX_SLAVES; x++) { 06981 if (!master->slaves[x]) { 06982 master->slaves[x] = slave; 06983 break; 06984 } 06985 } 06986 if (x >= MAX_SLAVES) { 06987 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 06988 master->slaves[MAX_SLAVES - 1] = slave; 06989 } 06990 if (slave->master) 06991 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 06992 slave->master = master; 06993 06994 ast_debug(1, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 06995 }
static void dahdi_lock_sub_owner | ( | struct dahdi_pvt * | pvt, | |
int | sub_idx | |||
) | [static] |
Definition at line 3634 of file chan_dahdi.c.
References ast_channel_trylock, dahdi_subchannel::owner, and dahdi_pvt::subs.
Referenced by wakeup_sub().
03635 { 03636 for (;;) { 03637 if (!pvt->subs[sub_idx].owner) { 03638 /* No subchannel owner pointer */ 03639 break; 03640 } 03641 if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) { 03642 /* Got subchannel owner lock */ 03643 break; 03644 } 03645 /* We must unlock the private to avoid the possibility of a deadlock */ 03646 DEADLOCK_AVOIDANCE(&pvt->lock); 03647 } 03648 }
static struct ast_channel * dahdi_new | ( | struct dahdi_pvt * | i, | |
int | state, | |||
int | startpbx, | |||
int | idx, | |||
int | law, | |||
const char * | linkedid | |||
) | [static] |
Definition at line 9280 of file chan_dahdi.c.
References accountcode, dahdi_pvt::accountcode, dahdi_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, dahdi_pvt::amaflags, analog_lib_handles(), ast_party_caller::ani, ast_party_caller::ani2, AST_ADSI_UNAVAILABLE, ast_cc_copy_config_params(), ast_channel_alloc, ast_channel_cc_params_init(), ast_channel_set_fd(), ast_copy_string(), ast_debug, ast_devstate_changed_literal(), ast_dsp_new(), ast_dsp_set_busy_compare(), ast_dsp_set_busy_count(), ast_dsp_set_busy_pattern(), ast_dsp_set_call_progress_zone(), ast_dsp_set_digitmode(), ast_dsp_set_features(), ast_dsp_set_threshold(), AST_FORMAT_ALAW, AST_FORMAT_ULAW, ast_free, ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), ast_state_chan2dev(), AST_STATE_RING, ast_str_buffer(), ast_strdup, ast_string_field_set, ast_strlen_zero(), dahdi_pvt::busycompare, dahdi_pvt::busycount, dahdi_pvt::busydetect, dahdi_pvt::busyfuzziness, dahdi_pvt::busyquietlength, dahdi_pvt::busytonelength, dahdi_pvt::call_forward, ast_channel::caller, dahdi_pvt::callgroup, ast_channel::callgroup, dahdi_pvt::callingpres, dahdi_pvt::callprogress, CALLPROGRESS_FAX_INCOMING, CALLPROGRESS_FAX_OUTGOING, CALLPROGRESS_PROGRESS, CANBUSYDETECT, CANPROGRESSDETECT, sig_pri_span::cc_params, dahdi_pvt::cc_params, CHAN_PSEUDO, dahdi_pvt::channel, dahdi_pvt::cid_ani, dahdi_pvt::cid_ani2, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_tag, dahdi_pvt::cid_ton, ast_channel::context, dahdi_pvt::context, create_channel_name(), dahdi_confmute(), dahdi_setlinear(), dahdi_sig_pri_lib_handles(), dahdi_tech, dahdi_subchannel::dfd, ast_channel::dialed, dahdi_pvt::dnid, dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, DSP_FEATURE_WAITDIALTONE, dahdi_pvt::dsp_features, DSP_PROGRESS_TALK, dahdi_pvt::dtmfrelax, ast_channel::exten, dahdi_pvt::exten, dahdi_pvt::fake_event, ast_party_redirecting::from, global_jbconf, dahdi_pvt::hardwaredtmf, ast_party_caller::id, language, dahdi_pvt::language, dahdi_pvt::law, dahdi_pvt::law_default, dahdi_subchannel::linear, dahdi_pvt::mfcr2_recvd_category, dahdi_pvt::mfcr2call, dahdi_pvt::muting, ast_variable::name, ast_party_id::name, ast_channel::name, ast_channel::nativeformats, NEED_MFDETECT, ast_variable::next, ast_party_dialed::number, ast_party_id::number, dahdi_pvt::oprmode, dahdi_pvt::outgoing, dahdi_pvt::owner, dahdi_subchannel::owner, parkinglot, dahdi_pvt::parkinglot, pbx_builtin_setvar_helper(), dahdi_pvt::pickupgroup, ast_channel::pickupgroup, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, dahdi_pvt::pri, progzone, dahdi_pvt::radio, ast_channel::rawreadformat, ast_channel::rawwriteformat, dahdi_pvt::rdnis, ast_channel::readformat, ast_channel::redirecting, ast_channel::rings, dahdi_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_PRI_LIB_HANDLE_CASES, SIG_SS7, dahdi_pvt::silencethreshold, ast_party_dialed::str, ast_party_number::str, SUB_REAL, subnames, dahdi_pvt::subs, ast_party_id::tag, ast_channel::tech, ast_channel::tech_pvt, ast_party_number::valid, ast_variable::value, dahdi_pvt::vars, dahdi_pvt::waitfordialtone, and ast_channel::writeformat.
Referenced by dahdi_handle_event(), dahdi_r2_on_call_accepted(), dahdi_r2_on_call_offered(), dahdi_request(), handle_init_event(), mwi_thread(), my_new_analog_ast_channel(), my_new_pri_ast_channel(), my_new_ss7_ast_channel(), and register_translator().
09281 { 09282 struct ast_channel *tmp; 09283 format_t deflaw; 09284 int x; 09285 int features; 09286 struct ast_str *chan_name; 09287 struct ast_variable *v; 09288 09289 if (i->subs[idx].owner) { 09290 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[idx]); 09291 return NULL; 09292 } 09293 09294 #if defined(HAVE_PRI) 09295 /* 09296 * The dnid has been stuffed with the called-number[:subaddress] 09297 * by dahdi_request() for outgoing calls. 09298 */ 09299 chan_name = create_channel_name(i, i->outgoing, i->dnid); 09300 #else 09301 chan_name = create_channel_name(i); 09302 #endif /* defined(HAVE_PRI) */ 09303 if (!chan_name) { 09304 return NULL; 09305 } 09306 09307 tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name)); 09308 ast_free(chan_name); 09309 if (!tmp) 09310 return NULL; 09311 tmp->tech = &dahdi_tech; 09312 #if defined(HAVE_PRI) 09313 if (i->pri) { 09314 ast_cc_copy_config_params(i->cc_params, i->pri->cc_params); 09315 } 09316 #endif /* defined(HAVE_PRI) */ 09317 ast_channel_cc_params_init(tmp, i->cc_params); 09318 if (law) { 09319 i->law = law; 09320 if (law == DAHDI_LAW_ALAW) { 09321 deflaw = AST_FORMAT_ALAW; 09322 } else { 09323 deflaw = AST_FORMAT_ULAW; 09324 } 09325 } else { 09326 switch (i->sig) { 09327 case SIG_PRI_LIB_HANDLE_CASES: 09328 /* Make sure companding law is known. */ 09329 i->law = (i->law_default == DAHDI_LAW_ALAW) 09330 ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW; 09331 break; 09332 default: 09333 i->law = i->law_default; 09334 break; 09335 } 09336 if (i->law_default == DAHDI_LAW_ALAW) { 09337 deflaw = AST_FORMAT_ALAW; 09338 } else { 09339 deflaw = AST_FORMAT_ULAW; 09340 } 09341 } 09342 ast_channel_set_fd(tmp, 0, i->subs[idx].dfd); 09343 tmp->nativeformats = deflaw; 09344 /* Start out assuming ulaw since it's smaller :) */ 09345 tmp->rawreadformat = deflaw; 09346 tmp->readformat = deflaw; 09347 tmp->rawwriteformat = deflaw; 09348 tmp->writeformat = deflaw; 09349 i->subs[idx].linear = 0; 09350 dahdi_setlinear(i->subs[idx].dfd, i->subs[idx].linear); 09351 features = 0; 09352 if (idx == SUB_REAL) { 09353 if (i->busydetect && CANBUSYDETECT(i)) 09354 features |= DSP_FEATURE_BUSY_DETECT; 09355 if ((i->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(i)) 09356 features |= DSP_FEATURE_CALL_PROGRESS; 09357 if ((i->waitfordialtone) && CANPROGRESSDETECT(i)) 09358 features |= DSP_FEATURE_WAITDIALTONE; 09359 if ((!i->outgoing && (i->callprogress & CALLPROGRESS_FAX_INCOMING)) || 09360 (i->outgoing && (i->callprogress & CALLPROGRESS_FAX_OUTGOING))) { 09361 features |= DSP_FEATURE_FAX_DETECT; 09362 } 09363 x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE; 09364 if (ioctl(i->subs[idx].dfd, DAHDI_TONEDETECT, &x)) { 09365 i->hardwaredtmf = 0; 09366 features |= DSP_FEATURE_DIGIT_DETECT; 09367 } else if (NEED_MFDETECT(i)) { 09368 i->hardwaredtmf = 1; 09369 features |= DSP_FEATURE_DIGIT_DETECT; 09370 } 09371 } 09372 if (features) { 09373 if (i->dsp) { 09374 ast_debug(1, "Already have a dsp on %s?\n", tmp->name); 09375 } else { 09376 if (i->channel != CHAN_PSEUDO) 09377 i->dsp = ast_dsp_new(); 09378 else 09379 i->dsp = NULL; 09380 if (i->dsp) { 09381 i->dsp_features = features; 09382 #if defined(HAVE_PRI) || defined(HAVE_SS7) 09383 /* We cannot do progress detection until receive PROGRESS message */ 09384 if (i->outgoing && (dahdi_sig_pri_lib_handles(i->sig) || (i->sig == SIG_SS7))) { 09385 /* Remember requested DSP features, don't treat 09386 talking as ANSWER */ 09387 i->dsp_features = features & ~DSP_PROGRESS_TALK; 09388 features = 0; 09389 } 09390 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 09391 ast_dsp_set_features(i->dsp, features); 09392 ast_dsp_set_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 09393 if (!ast_strlen_zero(progzone)) 09394 ast_dsp_set_call_progress_zone(i->dsp, progzone); 09395 if (i->busydetect && CANBUSYDETECT(i)) { 09396 if(i->silencethreshold > 0) 09397 ast_dsp_set_threshold(i->dsp, i->silencethreshold); 09398 ast_dsp_set_busy_count(i->dsp, i->busycount); 09399 if(i->busytonelength > 0) 09400 ast_dsp_set_busy_pattern(i->dsp, i->busytonelength, i->busyquietlength, i->busyfuzziness); 09401 if((i->busytonelength == i->busyquietlength) && i->busycompare) 09402 ast_dsp_set_busy_compare(i->dsp, i->busycompare); 09403 } 09404 } 09405 } 09406 } 09407 09408 if (state == AST_STATE_RING) 09409 tmp->rings = 1; 09410 tmp->tech_pvt = i; 09411 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 09412 /* Only FXO signalled stuff can be picked up */ 09413 tmp->callgroup = i->callgroup; 09414 tmp->pickupgroup = i->pickupgroup; 09415 } 09416 if (!ast_strlen_zero(i->parkinglot)) 09417 ast_string_field_set(tmp, parkinglot, i->parkinglot); 09418 if (!ast_strlen_zero(i->language)) 09419 ast_string_field_set(tmp, language, i->language); 09420 if (!i->owner) 09421 i->owner = tmp; 09422 if (!ast_strlen_zero(i->accountcode)) 09423 ast_string_field_set(tmp, accountcode, i->accountcode); 09424 if (i->amaflags) 09425 tmp->amaflags = i->amaflags; 09426 i->subs[idx].owner = tmp; 09427 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 09428 if (!analog_lib_handles(i->sig, i->radio, i->oprmode)) { 09429 ast_string_field_set(tmp, call_forward, i->call_forward); 09430 } 09431 /* If we've been told "no ADSI" then enforce it */ 09432 if (!i->adsi) 09433 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 09434 if (!ast_strlen_zero(i->exten)) 09435 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 09436 if (!ast_strlen_zero(i->rdnis)) { 09437 tmp->redirecting.from.number.valid = 1; 09438 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 09439 } 09440 if (!ast_strlen_zero(i->dnid)) { 09441 tmp->dialed.number.str = ast_strdup(i->dnid); 09442 } 09443 09444 /* Don't use ast_set_callerid() here because it will 09445 * generate a needless NewCallerID event */ 09446 #if defined(HAVE_PRI) || defined(HAVE_SS7) 09447 if (!ast_strlen_zero(i->cid_ani)) { 09448 tmp->caller.ani.number.valid = 1; 09449 tmp->caller.ani.number.str = ast_strdup(i->cid_ani); 09450 } else if (!ast_strlen_zero(i->cid_num)) { 09451 tmp->caller.ani.number.valid = 1; 09452 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 09453 } 09454 #else 09455 if (!ast_strlen_zero(i->cid_num)) { 09456 tmp->caller.ani.number.valid = 1; 09457 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 09458 } 09459 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 09460 tmp->caller.id.name.presentation = i->callingpres; 09461 tmp->caller.id.number.presentation = i->callingpres; 09462 tmp->caller.id.number.plan = i->cid_ton; 09463 tmp->caller.ani2 = i->cid_ani2; 09464 tmp->caller.id.tag = ast_strdup(i->cid_tag); 09465 /* clear the fake event in case we posted one before we had ast_channel */ 09466 i->fake_event = 0; 09467 /* Assure there is no confmute on this channel */ 09468 dahdi_confmute(i, 0); 09469 i->muting = 0; 09470 /* Configure the new channel jb */ 09471 ast_jb_configure(tmp, &global_jbconf); 09472 09473 ast_devstate_changed_literal(ast_state_chan2dev(state), tmp->name); 09474 09475 for (v = i->vars ; v ; v = v->next) 09476 pbx_builtin_setvar_helper(tmp, v->name, v->value); 09477 09478 ast_module_ref(ast_module_info->self); 09479 09480 if (startpbx) { 09481 #ifdef HAVE_OPENR2 09482 if (i->mfcr2call) { 09483 pbx_builtin_setvar_helper(tmp, "MFCR2_CATEGORY", openr2_proto_get_category_string(i->mfcr2_recvd_category)); 09484 } 09485 #endif 09486 if (ast_pbx_start(tmp)) { 09487 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 09488 ast_hangup(tmp); 09489 return NULL; 09490 } 09491 } 09492 return tmp; 09493 }
static int dahdi_new_pri_nobch_channel | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 12927 of file chan_dahdi.c.
References CHAN_PSEUDO, sig_pri_span::numchans, and sig_pri_span::pvts.
12928 { 12929 int pvt_idx; 12930 int res; 12931 unsigned idx; 12932 struct dahdi_pvt *pvt; 12933 struct sig_pri_chan *chan; 12934 struct dahdi_bufferinfo bi; 12935 12936 static int nobch_channel = CHAN_PSEUDO; 12937 12938 /* Find spot in the private pointer array for new interface. */ 12939 for (pvt_idx = 0; pvt_idx < pri->numchans; ++pvt_idx) { 12940 if (!pri->pvts[pvt_idx]) { 12941 break; 12942 } 12943 } 12944 if (pri->numchans == pvt_idx) { 12945 if (ARRAY_LEN(pri->pvts) <= pvt_idx) { 12946 ast_log(LOG_ERROR, "Unable to add a no-B-channel interface!\n"); 12947 return -1; 12948 } 12949 12950 /* Add new spot to the private pointer array. */ 12951 pri->pvts[pvt_idx] = NULL; 12952 ++pri->numchans; 12953 } 12954 12955 pvt = ast_calloc(1, sizeof(*pvt)); 12956 if (!pvt) { 12957 return -1; 12958 } 12959 pvt->cc_params = ast_cc_config_params_init(); 12960 if (!pvt->cc_params) { 12961 ast_free(pvt); 12962 return -1; 12963 } 12964 ast_mutex_init(&pvt->lock); 12965 for (idx = 0; idx < ARRAY_LEN(pvt->subs); ++idx) { 12966 pvt->subs[idx].dfd = -1; 12967 } 12968 pvt->buf_no = dahdi_pseudo_parms.buf_no; 12969 pvt->buf_policy = dahdi_pseudo_parms.buf_policy; 12970 pvt->faxbuf_no = dahdi_pseudo_parms.faxbuf_no; 12971 pvt->faxbuf_policy = dahdi_pseudo_parms.faxbuf_policy; 12972 12973 chan = sig_pri_chan_new(pvt, &dahdi_pri_callbacks, pri, 0, 0, 0); 12974 if (!chan) { 12975 destroy_dahdi_pvt(pvt); 12976 return -1; 12977 } 12978 chan->no_b_channel = 1; 12979 12980 /* 12981 * Pseudo channel companding law. 12982 * Needed for outgoing call waiting calls. 12983 * XXX May need to make this determined by switchtype or user option. 12984 */ 12985 pvt->law_default = DAHDI_LAW_ALAW; 12986 12987 pvt->sig = pri->sig; 12988 pvt->outsigmod = -1; 12989 pvt->pri = pri; 12990 pvt->sig_pvt = chan; 12991 pri->pvts[pvt_idx] = chan; 12992 12993 pvt->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo"); 12994 if (pvt->subs[SUB_REAL].dfd < 0) { 12995 ast_log(LOG_ERROR, "Unable to open no B channel interface pseudo channel: %s\n", 12996 strerror(errno)); 12997 destroy_dahdi_pvt(pvt); 12998 return -1; 12999 } 13000 memset(&bi, 0, sizeof(bi)); 13001 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi); 13002 if (!res) { 13003 pvt->bufsize = bi.bufsize; 13004 bi.txbufpolicy = pvt->buf_policy; 13005 bi.rxbufpolicy = pvt->buf_policy; 13006 bi.numbufs = pvt->buf_no; 13007 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi); 13008 if (res < 0) { 13009 ast_log(LOG_WARNING, 13010 "Unable to set buffer policy on no B channel interface: %s\n", 13011 strerror(errno)); 13012 } 13013 } else 13014 ast_log(LOG_WARNING, 13015 "Unable to check buffer policy on no B channel interface: %s\n", 13016 strerror(errno)); 13017 13018 --nobch_channel; 13019 if (CHAN_PSEUDO < nobch_channel) { 13020 nobch_channel = CHAN_PSEUDO - 1; 13021 } 13022 pvt->channel = nobch_channel; 13023 chan->channel = pvt->channel; 13024 13025 dahdi_nobch_insert(pri, pvt); 13026 13027 return pvt_idx; 13028 }
static void dahdi_nobch_extract | ( | struct sig_pri_span * | pri, | |
struct dahdi_pvt * | pvt | |||
) | [static] |
Definition at line 5498 of file chan_dahdi.c.
References DAHDI_IFLIST_NONE, dahdi_pvt::next, sig_pri_span::no_b_chan_end, sig_pri_span::no_b_chan_iflist, dahdi_pvt::prev, dahdi_pvt::pri, and dahdi_pvt::which_iflist.
Referenced by destroy_dahdi_pvt().
05499 { 05500 /* Extract from the forward chain. */ 05501 if (pvt->prev) { 05502 pvt->prev->next = pvt->next; 05503 } else if (pri->no_b_chan_iflist == pvt) { 05504 /* Node is at the head of the list. */ 05505 pri->no_b_chan_iflist = pvt->next; 05506 } 05507 05508 /* Extract from the reverse chain. */ 05509 if (pvt->next) { 05510 pvt->next->prev = pvt->prev; 05511 } else if (pri->no_b_chan_end == pvt) { 05512 /* Node is at the end of the list. */ 05513 pri->no_b_chan_end = pvt->prev; 05514 } 05515 05516 /* Node is no longer in the list. */ 05517 pvt->which_iflist = DAHDI_IFLIST_NONE; 05518 pvt->prev = NULL; 05519 pvt->next = NULL; 05520 }
static void dahdi_nobch_insert | ( | struct sig_pri_span * | pri, | |
struct dahdi_pvt * | pvt | |||
) | [static] |
Definition at line 5445 of file chan_dahdi.c.
References dahdi_pvt::channel, DAHDI_IFLIST_NO_B_CHAN, dahdi_pvt::next, sig_pri_span::no_b_chan_end, sig_pri_span::no_b_chan_iflist, dahdi_pvt::prev, dahdi_pvt::pri, and dahdi_pvt::which_iflist.
05446 { 05447 struct dahdi_pvt *cur; 05448 05449 pvt->which_iflist = DAHDI_IFLIST_NO_B_CHAN; 05450 05451 /* Find place in middle of list for the new interface. */ 05452 for (cur = pri->no_b_chan_iflist; cur; cur = cur->next) { 05453 if (pvt->channel < cur->channel) { 05454 /* New interface goes before the current interface. */ 05455 pvt->prev = cur->prev; 05456 pvt->next = cur; 05457 if (cur->prev) { 05458 /* Insert into the middle of the list. */ 05459 cur->prev->next = pvt; 05460 } else { 05461 /* Insert at head of list. */ 05462 pri->no_b_chan_iflist = pvt; 05463 } 05464 cur->prev = pvt; 05465 return; 05466 } 05467 } 05468 05469 /* New interface goes onto the end of the list */ 05470 pvt->prev = pri->no_b_chan_end; 05471 pvt->next = NULL; 05472 if (pri->no_b_chan_end) { 05473 ((struct dahdi_pvt *) pri->no_b_chan_end)->next = pvt; 05474 } 05475 pri->no_b_chan_end = pvt; 05476 if (!pri->no_b_chan_iflist) { 05477 /* List was empty */ 05478 pri->no_b_chan_iflist = pvt; 05479 } 05480 }
static int dahdi_open | ( | char * | fn | ) | [static] |
Definition at line 4165 of file chan_dahdi.c.
References ast_log(), errno, LOG_WARNING, and READ_SIZE.
Referenced by alloc_sub(), and duplicate_pseudo().
04166 { 04167 int fd; 04168 int isnum; 04169 int chan = 0; 04170 int bs; 04171 int x; 04172 isnum = 1; 04173 for (x = 0; x < strlen(fn); x++) { 04174 if (!isdigit(fn[x])) { 04175 isnum = 0; 04176 break; 04177 } 04178 } 04179 if (isnum) { 04180 chan = atoi(fn); 04181 if (chan < 1) { 04182 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn); 04183 return -1; 04184 } 04185 fn = "/dev/dahdi/channel"; 04186 } 04187 fd = open(fn, O_RDWR | O_NONBLOCK); 04188 if (fd < 0) { 04189 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno)); 04190 return -1; 04191 } 04192 if (chan) { 04193 if (ioctl(fd, DAHDI_SPECIFY, &chan)) { 04194 x = errno; 04195 close(fd); 04196 errno = x; 04197 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno)); 04198 return -1; 04199 } 04200 } 04201 bs = READ_SIZE; 04202 if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) { 04203 ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno)); 04204 x = errno; 04205 close(fd); 04206 errno = x; 04207 return -1; 04208 } 04209 return fd; 04210 }
static void dahdi_pri_error | ( | struct pri * | pri, | |
char * | s | |||
) | [static] |
Definition at line 13723 of file chan_dahdi.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, errno, pridebugfd, pridebugfdlock, and pris.
Referenced by load_module().
13724 { 13725 int x, y; 13726 int dchan = -1, span = -1; 13727 int dchancount = 0; 13728 13729 if (pri) { 13730 for (x = 0; x < NUM_SPANS; x++) { 13731 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 13732 if (pris[x].pri.dchans[y]) 13733 dchancount++; 13734 13735 if (pris[x].pri.dchans[y] == pri) 13736 dchan = y; 13737 } 13738 if (dchan >= 0) { 13739 span = x; 13740 break; 13741 } 13742 dchancount = 0; 13743 } 13744 if ((dchancount > 1) && (span > -1)) 13745 ast_log(LOG_ERROR, "[Span %d D-Channel %d] PRI: %s", span, dchan, s); 13746 else if (span > -1) 13747 ast_log(LOG_ERROR, "%d %s", span+1, s); 13748 else 13749 ast_log(LOG_ERROR, "%s", s); 13750 } else 13751 ast_log(LOG_ERROR, "%s", s); 13752 13753 ast_mutex_lock(&pridebugfdlock); 13754 13755 if (pridebugfd >= 0) { 13756 if (write(pridebugfd, s, strlen(s)) < 0) { 13757 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 13758 } 13759 } 13760 13761 ast_mutex_unlock(&pridebugfdlock); 13762 }
static void dahdi_pri_message | ( | struct pri * | pri, | |
char * | s | |||
) | [static] |
Definition at line 13681 of file chan_dahdi.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose, errno, pridebugfd, pridebugfdlock, and pris.
Referenced by load_module().
13682 { 13683 int x, y; 13684 int dchan = -1, span = -1, dchancount = 0; 13685 13686 if (pri) { 13687 for (x = 0; x < NUM_SPANS; x++) { 13688 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 13689 if (pris[x].pri.dchans[y]) 13690 dchancount++; 13691 13692 if (pris[x].pri.dchans[y] == pri) 13693 dchan = y; 13694 } 13695 if (dchan >= 0) { 13696 span = x; 13697 break; 13698 } 13699 dchancount = 0; 13700 } 13701 if (dchancount > 1 && (span > -1)) 13702 ast_verbose("[Span %d D-Channel %d]%s", span, dchan, s); 13703 else if (span > -1) 13704 ast_verbose("%d %s", span+1, s); 13705 else 13706 ast_verbose("%s", s); 13707 } else 13708 ast_verbose("%s", s); 13709 13710 ast_mutex_lock(&pridebugfdlock); 13711 13712 if (pridebugfd >= 0) { 13713 if (write(pridebugfd, s, strlen(s)) < 0) { 13714 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 13715 } 13716 } 13717 13718 ast_mutex_unlock(&pridebugfdlock); 13719 }
static void dahdi_pri_update_span_devstate | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 3173 of file chan_dahdi.c.
References AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_changed(), sig_pri_span::congestion_devstate, HAVE_PRI_SERVICE_MESSAGES, sig_pri_chan::inalarm, sig_pri_chan::no_b_channel, sig_pri_span::numchans, sig_pri_chan::owner, dahdi_pvt::pri, sig_pri_span::pvts, sig_pri_chan::service_status, and sig_pri_span::span.
03174 { 03175 unsigned idx; 03176 unsigned num_b_chans; /* Number of B channels provisioned on the span. */ 03177 unsigned in_use; /* Number of B channels in use on the span. */ 03178 unsigned in_alarm; /* TRUE if the span is in alarm condition. */ 03179 enum ast_device_state new_state; 03180 03181 /* Count the number of B channels and the number of B channels in use. */ 03182 num_b_chans = 0; 03183 in_use = 0; 03184 in_alarm = 1; 03185 for (idx = pri->numchans; idx--;) { 03186 if (pri->pvts[idx] && !pri->pvts[idx]->no_b_channel) { 03187 /* This is a B channel interface. */ 03188 ++num_b_chans; 03189 if (pri->pvts[idx]->owner 03190 #if defined(HAVE_PRI_SERVICE_MESSAGES) 03191 /* Out-of-service B channels are "in-use". */ 03192 || pri->pvts[idx]->service_status 03193 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 03194 ) { 03195 ++in_use; 03196 } 03197 if (!pri->pvts[idx]->inalarm) { 03198 /* There is a channel that is not in alarm. */ 03199 in_alarm = 0; 03200 } 03201 } 03202 } 03203 03204 /* Update the span congestion device state and report any change. */ 03205 if (in_alarm) { 03206 new_state = AST_DEVICE_UNAVAILABLE; 03207 } else { 03208 new_state = num_b_chans == in_use ? AST_DEVICE_BUSY : AST_DEVICE_NOT_INUSE; 03209 } 03210 if (pri->congestion_devstate != new_state) { 03211 pri->congestion_devstate = new_state; 03212 ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/congestion", pri->span); 03213 } 03214 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER) 03215 /* Update the span threshold device state and report any change. */ 03216 if (in_alarm) { 03217 new_state = AST_DEVICE_UNAVAILABLE; 03218 } else if (!in_use) { 03219 new_state = AST_DEVICE_NOT_INUSE; 03220 } else if (!pri->user_busy_threshold) { 03221 new_state = in_use < num_b_chans ? AST_DEVICE_INUSE : AST_DEVICE_BUSY; 03222 } else { 03223 new_state = in_use < pri->user_busy_threshold ? AST_DEVICE_INUSE 03224 : AST_DEVICE_BUSY; 03225 } 03226 if (pri->threshold_devstate != new_state) { 03227 pri->threshold_devstate = new_state; 03228 ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/threshold", pri->span); 03229 } 03230 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */ 03231 }
static int dahdi_queryoption | ( | struct ast_channel * | chan, | |
int | option, | |||
void * | data, | |||
int * | datalen | |||
) | [static] |
Definition at line 6491 of file chan_dahdi.c.
References ast_copy_string(), ast_debug, AST_OPTION_CC_AGENT_TYPE, AST_OPTION_DIGIT_DETECT, AST_OPTION_FAX_DETECT, dahdi_sig_pri_lib_handles(), DSP_FEATURE_FAX_DETECT, dahdi_pvt::dsp_features, errno, dahdi_pvt::ignoredtmf, ast_channel::name, dahdi_pvt::sig, and ast_channel::tech_pvt.
06492 { 06493 char *cp; 06494 struct dahdi_pvt *p = chan->tech_pvt; 06495 06496 /* all supported options require data */ 06497 if (!data || (*datalen < 1)) { 06498 errno = EINVAL; 06499 return -1; 06500 } 06501 06502 switch (option) { 06503 case AST_OPTION_DIGIT_DETECT: 06504 cp = (char *) data; 06505 *cp = p->ignoredtmf ? 0 : 1; 06506 ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name); 06507 break; 06508 case AST_OPTION_FAX_DETECT: 06509 cp = (char *) data; 06510 *cp = (p->dsp_features & DSP_FEATURE_FAX_DETECT) ? 0 : 1; 06511 ast_debug(1, "Reporting fax tone detection %sabled on %s\n", *cp ? "en" : "dis", chan->name); 06512 break; 06513 case AST_OPTION_CC_AGENT_TYPE: 06514 #if defined(HAVE_PRI) 06515 #if defined(HAVE_PRI_CCSS) 06516 if (dahdi_sig_pri_lib_handles(p->sig)) { 06517 ast_copy_string((char *) data, dahdi_pri_cc_type, *datalen); 06518 break; 06519 } 06520 #endif /* defined(HAVE_PRI_CCSS) */ 06521 #endif /* defined(HAVE_PRI) */ 06522 return -1; 06523 default: 06524 return -1; 06525 } 06526 06527 errno = 0; 06528 06529 return 0; 06530 }
Definition at line 3659 of file chan_dahdi.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_frame(), DEADLOCK_AVOIDANCE, f, dahdi_pvt::lock, and dahdi_pvt::owner.
Referenced by action_dahdidialoffhook().
03660 { 03661 for (;;) { 03662 if (p->owner) { 03663 if (ast_channel_trylock(p->owner)) { 03664 DEADLOCK_AVOIDANCE(&p->lock); 03665 } else { 03666 ast_queue_frame(p->owner, f); 03667 ast_channel_unlock(p->owner); 03668 break; 03669 } 03670 } else 03671 break; 03672 } 03673 }
static int16_t dahdi_r2_alaw_to_linear | ( | uint8_t | sample | ) | [inline, static] |
Definition at line 4120 of file chan_dahdi.c.
References AST_ALAW.
04121 { 04122 return AST_ALAW(sample); 04123 }
static int dahdi_r2_answer | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 3689 of file chan_dahdi.c.
References ast_true(), dahdi_pvt::owner, pbx_builtin_getvar_helper(), and dahdi_pvt::r2chan.
Referenced by dahdi_answer(), and dahdi_r2_on_call_accepted().
03690 { 03691 int res = 0; 03692 /* openr2 1.1.0 and older does not even define OR2_LIB_INTERFACE 03693 * and does not has support for openr2_chan_answer_call_with_mode 03694 * */ 03695 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 03696 const char *double_answer = pbx_builtin_getvar_helper(p->owner, "MFCR2_DOUBLE_ANSWER"); 03697 int wants_double_answer = ast_true(double_answer) ? 1 : 0; 03698 if (!double_answer) { 03699 /* this still can result in double answer if the channel context 03700 * was configured that way */ 03701 res = openr2_chan_answer_call(p->r2chan); 03702 } else if (wants_double_answer) { 03703 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE); 03704 } else { 03705 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE); 03706 } 03707 #else 03708 res = openr2_chan_answer_call(p->r2chan); 03709 #endif 03710 return res; 03711 }
static int dahdi_r2_cause_to_ast_cause | ( | openr2_call_disconnect_cause_t | cause | ) | [static] |
Definition at line 3930 of file chan_dahdi.c.
References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_NO_ANSWER, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_NOTDEFINED, and AST_CAUSE_UNREGISTERED.
Referenced by dahdi_r2_on_call_disconnect().
03931 { 03932 switch (cause) { 03933 case OR2_CAUSE_BUSY_NUMBER: 03934 return AST_CAUSE_BUSY; 03935 case OR2_CAUSE_NETWORK_CONGESTION: 03936 return AST_CAUSE_CONGESTION; 03937 case OR2_CAUSE_OUT_OF_ORDER: 03938 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03939 case OR2_CAUSE_UNALLOCATED_NUMBER: 03940 return AST_CAUSE_UNREGISTERED; 03941 case OR2_CAUSE_NO_ANSWER: 03942 return AST_CAUSE_NO_ANSWER; 03943 case OR2_CAUSE_NORMAL_CLEARING: 03944 return AST_CAUSE_NORMAL_CLEARING; 03945 case OR2_CAUSE_UNSPECIFIED: 03946 default: 03947 return AST_CAUSE_NOTDEFINED; 03948 } 03949 }
static void dahdi_r2_destroy_links | ( | void | ) | [static] |
Definition at line 11765 of file chan_dahdi.c.
References ast_free, AST_PTHREADT_NULL, r2links, and r2links_count.
Referenced by __unload_module(), and dahdi_restart().
11766 { 11767 int i = 0; 11768 if (!r2links) { 11769 return; 11770 } 11771 for (; i < r2links_count; i++) { 11772 if (r2links[i]->r2master != AST_PTHREADT_NULL) { 11773 pthread_cancel(r2links[i]->r2master); 11774 pthread_join(r2links[i]->r2master, NULL); 11775 openr2_context_delete(r2links[i]->protocol_context); 11776 } 11777 ast_free(r2links[i]); 11778 } 11779 ast_free(r2links); 11780 r2links = NULL; 11781 r2links_count = 0; 11782 }
static void dahdi_r2_disconnect_call | ( | struct dahdi_pvt * | p, | |
openr2_call_disconnect_cause_t | cause | |||
) | [static] |
Definition at line 3798 of file chan_dahdi.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, dahdi_pvt::lock, LOG_NOTICE, dahdi_pvt::mfcr2call, and dahdi_pvt::r2chan.
Referenced by dahdi_hangup(), dahdi_r2_on_call_accepted(), dahdi_r2_on_call_disconnect(), and dahdi_r2_on_call_offered().
03799 { 03800 if (openr2_chan_disconnect_call(p->r2chan, cause)) { 03801 ast_log(LOG_NOTICE, "Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n", 03802 p->channel, openr2_proto_get_disconnect_string(cause)); 03803 /* force the chan to idle and release the call flag now since we will not see a clean on_call_end */ 03804 openr2_chan_set_idle(p->r2chan); 03805 ast_mutex_lock(&p->lock); 03806 p->mfcr2call = 0; 03807 ast_mutex_unlock(&p->lock); 03808 } 03809 }
static openr2_calling_party_category_t dahdi_r2_get_channel_category | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3716 of file chan_dahdi.c.
References ast_debug, ast_log(), ast_strlen_zero(), LOG_WARNING, dahdi_pvt::mfcr2_category, ast_channel::name, pbx_builtin_getvar_helper(), and ast_channel::tech_pvt.
Referenced by dahdi_call().
03717 { 03718 openr2_calling_party_category_t cat; 03719 const char *catstr = pbx_builtin_getvar_helper(c, "MFCR2_CATEGORY"); 03720 struct dahdi_pvt *p = c->tech_pvt; 03721 if (ast_strlen_zero(catstr)) { 03722 ast_debug(1, "No MFC/R2 category specified for chan %s, using default %s\n", 03723 c->name, openr2_proto_get_category_string(p->mfcr2_category)); 03724 return p->mfcr2_category; 03725 } 03726 if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) { 03727 ast_log(LOG_WARNING, "Invalid category specified '%s' for chan %s, using default %s\n", 03728 catstr, c->name, openr2_proto_get_category_string(p->mfcr2_category)); 03729 return p->mfcr2_category; 03730 } 03731 ast_debug(1, "Using category %s\n", catstr); 03732 return cat; 03733 }
static struct dahdi_mfcr2* dahdi_r2_get_link | ( | void | ) | [static] |
Definition at line 11785 of file chan_dahdi.c.
References ast_calloc, ast_free, ast_log(), AST_PTHREADT_NULL, ast_realloc, LOG_DEBUG, LOG_ERROR, dahdi_mfcr2::monitored_count, R2_LINK_CAPACITY, r2links, r2links_count, and dahdi_mfcr2::r2master.
11786 { 11787 struct dahdi_mfcr2 *new_r2link = NULL; 11788 struct dahdi_mfcr2 **new_r2links = NULL; 11789 /* this function is called just when starting up and no monitor threads have been launched, 11790 no need to lock monitored_count member */ 11791 if (!r2links_count || (r2links[r2links_count - 1]->monitored_count == R2_LINK_CAPACITY)) { 11792 new_r2link = ast_calloc(1, sizeof(**r2links)); 11793 if (!new_r2link) { 11794 ast_log(LOG_ERROR, "Cannot allocate R2 link!\n"); 11795 return NULL; 11796 } 11797 new_r2links = ast_realloc(r2links, ((r2links_count + 1) * sizeof(*r2links))); 11798 if (!new_r2links) { 11799 ast_log(LOG_ERROR, "Cannot allocate R2 link!\n"); 11800 ast_free(new_r2link); 11801 return NULL; 11802 } 11803 r2links = new_r2links; 11804 new_r2link->r2master = AST_PTHREADT_NULL; 11805 r2links[r2links_count] = new_r2link; 11806 r2links_count++; 11807 ast_log(LOG_DEBUG, "Created new R2 link!\n"); 11808 } 11809 return r2links[r2links_count - 1]; 11810 }
static uint8_t dahdi_r2_linear_to_alaw | ( | int | sample | ) | [inline, static] |
Definition at line 4125 of file chan_dahdi.c.
References AST_LIN2A.
04126 { 04127 return AST_LIN2A(sample); 04128 }
static void dahdi_r2_on_ani_digit_received | ( | openr2_chan_t * | r2chan, | |
char | digit | |||
) | [static] |
Definition at line 4084 of file chan_dahdi.c.
References dahdi_pvt::cid_name, dahdi_pvt::cid_num, and dahdi_pvt::mfcr2_ani_index.
04085 { 04086 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 04087 p->cid_num[p->mfcr2_ani_index] = digit; 04088 p->cid_name[p->mfcr2_ani_index] = digit; 04089 p->mfcr2_ani_index++; 04090 p->cid_num[p->mfcr2_ani_index] = 0; 04091 p->cid_name[p->mfcr2_ani_index] = 0; 04092 }
static void dahdi_r2_on_billing_pulse_received | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 4094 of file chan_dahdi.c.
References ast_verbose.
04095 { 04096 ast_verbose("MFC/R2 billing pulse received on channel %d\n", openr2_chan_get_number(r2chan)); 04097 }
static void dahdi_r2_on_call_accepted | ( | openr2_chan_t * | r2chan, | |
openr2_call_mode_t | mode | |||
) | [static] |
Definition at line 3876 of file chan_dahdi.c.
References ast_log(), AST_STATE_RING, ast_verbose, dahdi_pvt::channel, dahdi_enable_ec(), dahdi_new(), dahdi_r2_answer(), dahdi_r2_disconnect_call(), dahdi_pvt::dialing, LOG_DEBUG, LOG_WARNING, dahdi_pvt::mfcr2_accept_on_offer, dahdi_pvt::mfcr2_answer_pending, dahdi_pvt::mfcr2_call_accepted, dahdi_subchannel::needringing, SUB_REAL, and dahdi_pvt::subs.
03877 { 03878 struct dahdi_pvt *p = NULL; 03879 struct ast_channel *c = NULL; 03880 p = openr2_chan_get_client_data(r2chan); 03881 dahdi_enable_ec(p); 03882 p->mfcr2_call_accepted = 1; 03883 /* if it's an incoming call ... */ 03884 if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) { 03885 ast_verbose("MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan)); 03886 /* If accept on offer is not set, it means at this point the PBX thread is already 03887 launched (was launched in the 'on call offered' handler) and therefore this callback 03888 is being executed already in the PBX thread rather than the monitor thread, don't launch 03889 any other thread, just disable the openr2 reading and answer the call if needed */ 03890 if (!p->mfcr2_accept_on_offer) { 03891 openr2_chan_disable_read(r2chan); 03892 if (p->mfcr2_answer_pending) { 03893 ast_log(LOG_DEBUG, "Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan)); 03894 dahdi_r2_answer(p); 03895 } 03896 return; 03897 } 03898 c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL); 03899 if (c) { 03900 /* chan_dahdi will take care of reading from now on in the PBX thread, tell the 03901 library to forget about it */ 03902 openr2_chan_disable_read(r2chan); 03903 return; 03904 } 03905 ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel); 03906 /* failed to create the channel, bail out and report it as an out of order line */ 03907 dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER); 03908 return; 03909 } 03910 /* this is an outgoing call, no need to launch the PBX thread, most likely we're in one already */ 03911 ast_verbose("MFC/R2 call has been accepted on forward channel %d\n", p->channel); 03912 p->subs[SUB_REAL].needringing = 1; 03913 p->dialing = 0; 03914 /* chan_dahdi will take care of reading from now on in the PBX thread, tell the library to forget about it */ 03915 openr2_chan_disable_read(r2chan); 03916 }
static void dahdi_r2_on_call_answered | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 3918 of file chan_dahdi.c.
References ast_verbose, dahdi_subchannel::needanswer, SUB_REAL, and dahdi_pvt::subs.
03919 { 03920 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 03921 ast_verbose("MFC/R2 call has been answered on channel %d\n", openr2_chan_get_number(r2chan)); 03922 p->subs[SUB_REAL].needanswer = 1; 03923 }
static void dahdi_r2_on_call_disconnect | ( | openr2_chan_t * | r2chan, | |
openr2_call_disconnect_cause_t | cause | |||
) | [static] |
Definition at line 3951 of file chan_dahdi.c.
References ast_channel::_softhangup, ast_channel::_state, ast_mutex_lock, ast_mutex_unlock, ast_queue_hangup_with_cause(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_verbose, dahdi_r2_cause_to_ast_cause(), dahdi_r2_disconnect_call(), dahdi_pvt::lock, dahdi_subchannel::needbusy, dahdi_subchannel::needcongestion, dahdi_pvt::owner, SUB_REAL, and dahdi_pvt::subs.
03952 { 03953 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 03954 ast_verbose("MFC/R2 call disconnected on channel %d\n", openr2_chan_get_number(r2chan)); 03955 ast_mutex_lock(&p->lock); 03956 if (!p->owner) { 03957 ast_mutex_unlock(&p->lock); 03958 /* no owner, therefore we can't use dahdi_hangup to disconnect, do it right now */ 03959 dahdi_r2_disconnect_call(p, OR2_CAUSE_NORMAL_CLEARING); 03960 return; 03961 } 03962 /* when we have an owner we don't call dahdi_r2_disconnect_call here, that will 03963 be done in dahdi_hangup */ 03964 if (p->owner->_state == AST_STATE_UP) { 03965 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03966 ast_mutex_unlock(&p->lock); 03967 } else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) { 03968 /* being the forward side we must report what happened to the call to whoever requested it */ 03969 switch (cause) { 03970 case OR2_CAUSE_BUSY_NUMBER: 03971 p->subs[SUB_REAL].needbusy = 1; 03972 break; 03973 case OR2_CAUSE_NETWORK_CONGESTION: 03974 case OR2_CAUSE_OUT_OF_ORDER: 03975 case OR2_CAUSE_UNALLOCATED_NUMBER: 03976 case OR2_CAUSE_NO_ANSWER: 03977 case OR2_CAUSE_UNSPECIFIED: 03978 case OR2_CAUSE_NORMAL_CLEARING: 03979 p->subs[SUB_REAL].needcongestion = 1; 03980 break; 03981 default: 03982 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03983 } 03984 ast_mutex_unlock(&p->lock); 03985 } else { 03986 ast_mutex_unlock(&p->lock); 03987 /* being the backward side and not UP yet, we only need to request hangup */ 03988 /* TODO: what about doing this same thing when were AST_STATE_UP? */ 03989 ast_queue_hangup_with_cause(p->owner, dahdi_r2_cause_to_ast_cause(cause)); 03990 } 03991 }
static void dahdi_r2_on_call_end | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 3866 of file chan_dahdi.c.
References ast_mutex_lock, ast_mutex_unlock, ast_verbose, dahdi_pvt::channel, dahdi_pvt::lock, and dahdi_pvt::mfcr2call.
03867 { 03868 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 03869 ast_verbose("MFC/R2 call end on channel %d\n", p->channel); 03870 ast_mutex_lock(&p->lock); 03871 p->mfcr2call = 0; 03872 ast_mutex_unlock(&p->lock); 03873 }
static void dahdi_r2_on_call_init | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 3735 of file chan_dahdi.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_subaddr, dahdi_pvt::exten, dahdi_pvt::lock, LOG_ERROR, dahdi_pvt::mfcr2_ani_index, dahdi_pvt::mfcr2_answer_pending, dahdi_pvt::mfcr2_call_accepted, dahdi_pvt::mfcr2_dnis_index, dahdi_pvt::mfcr2_dnis_matched, dahdi_pvt::mfcr2call, and dahdi_pvt::rdnis.
03736 { 03737 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 03738 ast_mutex_lock(&p->lock); 03739 if (p->mfcr2call) { 03740 ast_mutex_unlock(&p->lock); 03741 /* TODO: This can happen when some other thread just finished dahdi_request requesting this very same 03742 interface but has not yet seized the line (dahdi_call), and the far end wins and seize the line, 03743 can we avoid this somehow?, at this point when dahdi_call send the seize, it is likely that since 03744 the other end will see our seize as a forced release and drop the call, we will see an invalid 03745 pattern that will be seen and treated as protocol error. */ 03746 ast_log(LOG_ERROR, "Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan)); 03747 return; 03748 } 03749 p->mfcr2call = 1; 03750 /* better safe than sorry ... */ 03751 p->cid_name[0] = '\0'; 03752 p->cid_num[0] = '\0'; 03753 p->cid_subaddr[0] = '\0'; 03754 p->rdnis[0] = '\0'; 03755 p->exten[0] = '\0'; 03756 p->mfcr2_ani_index = '\0'; 03757 p->mfcr2_dnis_index = '\0'; 03758 p->mfcr2_dnis_matched = 0; 03759 p->mfcr2_answer_pending = 0; 03760 p->mfcr2_call_accepted = 0; 03761 ast_mutex_unlock(&p->lock); 03762 ast_verbose("New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan)); 03763 }
static void dahdi_r2_on_call_offered | ( | openr2_chan_t * | r2chan, | |
const char * | ani, | |||
const char * | dnis, | |||
openr2_calling_party_category_t | category | |||
) | [static] |
Definition at line 3811 of file chan_dahdi.c.
References ast_exists_extension(), ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_STATE_RING, ast_verbose, dahdi_pvt::channel, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::context, dahdi_new(), dahdi_r2_disconnect_call(), dahdi_pvt::exten, dahdi_pvt::immediate, dahdi_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, dahdi_pvt::mfcr2_accept_on_offer, dahdi_pvt::mfcr2_allow_collect_calls, dahdi_pvt::mfcr2_charge_calls, dahdi_pvt::mfcr2_recvd_category, SUB_REAL, and dahdi_pvt::use_callerid.
03812 { 03813 struct dahdi_pvt *p; 03814 struct ast_channel *c; 03815 ast_verbose("MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n", 03816 openr2_chan_get_number(r2chan), ani ? ani : "(restricted)", dnis, 03817 openr2_proto_get_category_string(category)); 03818 p = openr2_chan_get_client_data(r2chan); 03819 /* if collect calls are not allowed and this is a collect call, reject it! */ 03820 if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) { 03821 ast_log(LOG_NOTICE, "Rejecting MFC/R2 collect call\n"); 03822 dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED); 03823 return; 03824 } 03825 ast_mutex_lock(&p->lock); 03826 p->mfcr2_recvd_category = category; 03827 /* if we're not supposed to use CID, clear whatever we have */ 03828 if (!p->use_callerid) { 03829 ast_log(LOG_DEBUG, "No CID allowed in configuration, CID is being cleared!\n"); 03830 p->cid_num[0] = 0; 03831 p->cid_name[0] = 0; 03832 } 03833 /* if we're supposed to answer immediately, clear DNIS and set 's' exten */ 03834 if (p->immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) { 03835 ast_log(LOG_DEBUG, "Setting exten => s because of immediate or 0 DNIS configured\n"); 03836 p->exten[0] = 's'; 03837 p->exten[1] = 0; 03838 } 03839 ast_mutex_unlock(&p->lock); 03840 if (!ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) { 03841 ast_log(LOG_NOTICE, "MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n", 03842 p->channel, p->exten, p->context); 03843 dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER); 03844 return; 03845 } 03846 if (!p->mfcr2_accept_on_offer) { 03847 /* The user wants us to start the PBX thread right away without accepting the call first */ 03848 c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL); 03849 if (c) { 03850 /* Done here, don't disable reading now since we still need to generate MF tones to accept 03851 the call or reject it and detect the tone off condition of the other end, all of this 03852 will be done in the PBX thread now */ 03853 return; 03854 } 03855 ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel); 03856 dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER); 03857 } else if (p->mfcr2_charge_calls) { 03858 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with charge on chan %d\n", p->channel); 03859 openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE); 03860 } else { 03861 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with no charge on chan %d\n", p->channel); 03862 openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE); 03863 } 03864 }
static void dahdi_r2_on_call_read | ( | openr2_chan_t * | r2chan, | |
const unsigned char * | buf, | |||
int | buflen | |||
) | [static] |
Definition at line 3925 of file chan_dahdi.c.
03926 { 03927 /*ast_log(LOG_DEBUG, "Read data from dahdi channel %d\n", openr2_chan_get_number(r2chan));*/ 03928 }
static void dahdi_r2_on_chan_log | ( | openr2_chan_t * | r2chan, | |
openr2_log_level_t | level, | |||
const char * | fmt, | |||
va_list | ap | |||
) | [static] |
Definition at line 4052 of file chan_dahdi.c.
References CHAN_TAG, and dahdi_r2_write_log().
04053 { 04054 #define CHAN_TAG "Chan " 04055 char logmsg[256]; 04056 char completemsg[sizeof(logmsg) + sizeof(CHAN_TAG) - 1]; 04057 vsnprintf(logmsg, sizeof(logmsg), fmt, ap); 04058 snprintf(completemsg, sizeof(completemsg), CHAN_TAG "%d - %s", openr2_chan_get_number(r2chan), logmsg); 04059 dahdi_r2_write_log(level, completemsg); 04060 }
static void dahdi_r2_on_context_log | ( | openr2_context_t * | r2context, | |
openr2_log_level_t | level, | |||
const char * | fmt, | |||
va_list | ap | |||
) | [static] |
Definition at line 4039 of file chan_dahdi.c.
References CONTEXT_TAG, and dahdi_r2_write_log().
04040 { 04041 #define CONTEXT_TAG "Context - " 04042 char logmsg[256]; 04043 char completemsg[sizeof(logmsg) + sizeof(CONTEXT_TAG) - 1]; 04044 vsnprintf(logmsg, sizeof(logmsg), fmt, ap); 04045 snprintf(completemsg, sizeof(completemsg), CONTEXT_TAG "%s", logmsg); 04046 dahdi_r2_write_log(level, completemsg); 04047 #undef CONTEXT_TAG 04048 }
static int dahdi_r2_on_dnis_digit_received | ( | openr2_chan_t * | r2chan, | |
char | digit | |||
) | [static] |
Definition at line 4062 of file chan_dahdi.c.
References ast_exists_extension(), ast_matchmore_extension(), dahdi_pvt::cid_num, dahdi_pvt::context, dahdi_pvt::exten, dahdi_pvt::immediate, dahdi_pvt::mfcr2_dnis_index, dahdi_pvt::mfcr2_dnis_matched, and dahdi_pvt::rdnis.
04063 { 04064 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 04065 /* if 'immediate' is set, let's stop requesting DNIS */ 04066 if (p->immediate) { 04067 return 0; 04068 } 04069 p->exten[p->mfcr2_dnis_index] = digit; 04070 p->rdnis[p->mfcr2_dnis_index] = digit; 04071 p->mfcr2_dnis_index++; 04072 p->exten[p->mfcr2_dnis_index] = 0; 04073 p->rdnis[p->mfcr2_dnis_index] = 0; 04074 /* if the DNIS is a match and cannot match more, stop requesting DNIS */ 04075 if ((p->mfcr2_dnis_matched || 04076 (ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num) && (p->mfcr2_dnis_matched = 1))) && 04077 !ast_matchmore_extension(NULL, p->context, p->exten, 1, p->cid_num)) { 04078 return 0; 04079 } 04080 /* otherwise keep going */ 04081 return 1; 04082 }
static void dahdi_r2_on_hardware_alarm | ( | openr2_chan_t * | r2chan, | |
int | alarm | |||
) | [static] |
Definition at line 3765 of file chan_dahdi.c.
References ast_mutex_lock, ast_mutex_unlock, get_alarms(), handle_alarms(), handle_clear_alarms(), dahdi_pvt::inalarm, and dahdi_pvt::lock.
03766 { 03767 int res; 03768 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 03769 ast_mutex_lock(&p->lock); 03770 p->inalarm = alarm ? 1 : 0; 03771 if (p->inalarm) { 03772 res = get_alarms(p); 03773 handle_alarms(p, res); 03774 } else { 03775 handle_clear_alarms(p); 03776 } 03777 ast_mutex_unlock(&p->lock); 03778 }
static void dahdi_r2_on_line_blocked | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 4019 of file chan_dahdi.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::lock, LOG_NOTICE, and dahdi_pvt::remotelyblocked.
04020 { 04021 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 04022 ast_mutex_lock(&p->lock); 04023 p->remotelyblocked = 1; 04024 ast_mutex_unlock(&p->lock); 04025 ast_log(LOG_NOTICE, "Far end blocked on chan %d\n", openr2_chan_get_number(r2chan)); 04026 }
static void dahdi_r2_on_line_idle | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 4028 of file chan_dahdi.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::lock, LOG_NOTICE, and dahdi_pvt::remotelyblocked.
04029 { 04030 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 04031 ast_mutex_lock(&p->lock); 04032 p->remotelyblocked = 0; 04033 ast_mutex_unlock(&p->lock); 04034 ast_log(LOG_NOTICE, "Far end unblocked on chan %d\n", openr2_chan_get_number(r2chan)); 04035 }
static void dahdi_r2_on_os_error | ( | openr2_chan_t * | r2chan, | |
int | errorcode | |||
) | [static] |
static void dahdi_r2_on_protocol_error | ( | openr2_chan_t * | r2chan, | |
openr2_protocol_error_t | reason | |||
) | [static] |
Definition at line 3785 of file chan_dahdi.c.
References ast_channel::_softhangup, AST_CAUSE_PROTOCOL_ERROR, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_SOFTHANGUP_DEV, ast_channel::hangupcause, dahdi_pvt::lock, LOG_ERROR, dahdi_pvt::mfcr2call, and dahdi_pvt::owner.
03786 { 03787 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 03788 ast_log(LOG_ERROR, "MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason)); 03789 if (p->owner) { 03790 p->owner->hangupcause = AST_CAUSE_PROTOCOL_ERROR; 03791 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03792 } 03793 ast_mutex_lock(&p->lock); 03794 p->mfcr2call = 0; 03795 ast_mutex_unlock(&p->lock); 03796 }
static int dahdi_r2_set_context | ( | struct dahdi_mfcr2 * | r2_link, | |
const struct dahdi_chan_conf * | conf | |||
) | [static] |
Definition at line 11812 of file chan_dahdi.c.
References ast_config_AST_LOG_DIR, ast_log(), ast_strlen_zero(), dahdi_mfcr2_conf::double_answer, dahdi_mfcr2_conf::get_ani_first, dahdi_mfcr2_conf::immediate_accept, LOG_ERROR, dahdi_mfcr2_conf::logdir, dahdi_mfcr2_conf::loglevel, dahdi_mfcr2_conf::max_ani, dahdi_mfcr2_conf::max_dnis, dahdi_mfcr2_conf::metering_pulse_timeout, dahdi_mfcr2_conf::mfback_timeout, dahdi_chan_conf::mfcr2, dahdi_mfcr2::monitored_count, dahdi_mfcr2::protocol_context, dahdi_mfcr2_conf::r2proto_file, and dahdi_mfcr2_conf::variant.
11813 { 11814 char tmplogdir[] = "/tmp"; 11815 char logdir[OR2_MAX_PATH]; 11816 int threshold = 0; 11817 int snres = 0; 11818 r2_link->protocol_context = openr2_context_new(NULL, &dahdi_r2_event_iface, 11819 &dahdi_r2_transcode_iface, conf->mfcr2.variant, conf->mfcr2.max_ani, 11820 conf->mfcr2.max_dnis); 11821 if (!r2_link->protocol_context) { 11822 return -1; 11823 } 11824 openr2_context_set_log_level(r2_link->protocol_context, conf->mfcr2.loglevel); 11825 openr2_context_set_ani_first(r2_link->protocol_context, conf->mfcr2.get_ani_first); 11826 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 11827 openr2_context_set_skip_category_request(r2_link->protocol_context, conf->mfcr2.skip_category_request); 11828 #endif 11829 openr2_context_set_mf_threshold(r2_link->protocol_context, threshold); 11830 openr2_context_set_mf_back_timeout(r2_link->protocol_context, conf->mfcr2.mfback_timeout); 11831 openr2_context_set_metering_pulse_timeout(r2_link->protocol_context, conf->mfcr2.metering_pulse_timeout); 11832 openr2_context_set_double_answer(r2_link->protocol_context, conf->mfcr2.double_answer); 11833 openr2_context_set_immediate_accept(r2_link->protocol_context, conf->mfcr2.immediate_accept); 11834 if (ast_strlen_zero(conf->mfcr2.logdir)) { 11835 if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) { 11836 ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir); 11837 } 11838 } else { 11839 snres = snprintf(logdir, sizeof(logdir), "%s/%s/%s", ast_config_AST_LOG_DIR, "mfcr2", conf->mfcr2.logdir); 11840 if (snres >= sizeof(logdir)) { 11841 ast_log(LOG_ERROR, "MFC/R2 logging directory truncated, using %s\n", tmplogdir); 11842 if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) { 11843 ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir); 11844 } 11845 } else { 11846 if (openr2_context_set_log_directory(r2_link->protocol_context, logdir)) { 11847 ast_log(LOG_ERROR, "Failed setting MFC/R2 log directory %s\n", logdir); 11848 } 11849 } 11850 } 11851 if (!ast_strlen_zero(conf->mfcr2.r2proto_file)) { 11852 if (openr2_context_configure_from_advanced_file(r2_link->protocol_context, conf->mfcr2.r2proto_file)) { 11853 ast_log(LOG_ERROR, "Failed to configure r2context from advanced configuration file %s\n", conf->mfcr2.r2proto_file); 11854 } 11855 } 11856 r2_link->monitored_count = 0; 11857 return 0; 11858 }
static void dahdi_r2_write_log | ( | openr2_log_level_t | level, | |
char * | logmessage | |||
) | [static] |
Definition at line 3993 of file chan_dahdi.c.
References ast_log(), ast_verbose, LOG_DEBUG, LOG_ERROR, and LOG_WARNING.
Referenced by dahdi_r2_on_chan_log(), and dahdi_r2_on_context_log().
03994 { 03995 switch (level) { 03996 case OR2_LOG_NOTICE: 03997 ast_verbose("%s", logmessage); 03998 break; 03999 case OR2_LOG_WARNING: 04000 ast_log(LOG_WARNING, "%s", logmessage); 04001 break; 04002 case OR2_LOG_ERROR: 04003 ast_log(LOG_ERROR, "%s", logmessage); 04004 break; 04005 case OR2_LOG_STACK_TRACE: 04006 case OR2_LOG_MF_TRACE: 04007 case OR2_LOG_CAS_TRACE: 04008 case OR2_LOG_DEBUG: 04009 case OR2_LOG_EX_DEBUG: 04010 ast_log(LOG_DEBUG, "%s", logmessage); 04011 break; 04012 default: 04013 ast_log(LOG_WARNING, "We should handle logging level %d here.\n", level); 04014 ast_log(LOG_DEBUG, "%s", logmessage); 04015 break; 04016 } 04017 }
static struct ast_frame * dahdi_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 8640 of file chan_dahdi.c.
References __dahdi_exception(), ast_channel::_state, analog_exception(), analog_handle_dtmf(), analog_lib_handles(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_debug, ast_dsp_get_tcount(), ast_dsp_get_tstate(), ast_dsp_process(), ast_dsp_set_features(), ast_dsp_was_muted(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_getformatname(), ast_log(), ast_mutex_trylock, ast_mutex_unlock, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_setstate(), AST_STATE_DIALING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_tv(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, dahdi_subchannel::buffer, dahdi_pvt::busydetect, dahdi_pvt::callprogress, dahdi_pvt::callwaitcas, dahdi_pvt::callwaitingrepeat, dahdi_pvt::callwaitrings, dahdi_pvt::channel, CHANNEL_DEADLOCK_AVOIDANCE, CHECK_BLOCKING, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cidcwexpire, dahdi_pvt::cidspill, ast_frame_subclass::codec, dahdi_callwait(), dahdi_confmute(), dahdi_get_index, dahdi_handle_dtmf(), DAHDI_OVERLAPDIAL_INCOMING, DAHDI_OVERLAPDIAL_OUTGOING, dahdi_setlinear(), dahdi_sig_pri_lib_handles(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, dahdi_subchannel::dfd, dahdi_pvt::dialing, dahdi_pvt::dop, dahdi_pvt::dsp, DSP_FEATURE_WAITDIALTONE, dahdi_pvt::dsp_features, DSP_TONE_STATE_DIALTONE, DSP_TONE_STATE_RINGING, errno, dahdi_subchannel::f, f, dahdi_pvt::fake_event, dahdi_pvt::firstradio, ast_frame::frametype, dahdi_pvt::ignoredtmf, dahdi_pvt::inalarm, ast_frame_subclass::integer, dahdi_subchannel::linear, dahdi_pvt::lock, LOG_DEBUG, ast_frame::mallocd, dahdi_pvt::mfcr2, dahdi_pvt::mfcr2_call_accepted, dahdi_pvt::mfcr2_progress, mute, dahdi_pvt::muting, ast_channel::name, dahdi_subchannel::needanswer, dahdi_subchannel::needbusy, dahdi_subchannel::needcongestion, dahdi_subchannel::needflash, dahdi_subchannel::needhold, dahdi_subchannel::needringing, dahdi_subchannel::needunhold, ast_frame::offset, dahdi_pvt::oprmode, dahdi_pvt::outgoing, sig_pri_span::overlapdial, dahdi_pvt::owner, dahdi_pvt::pri, ast_frame::ptr, dahdi_pvt::pulsedial, dahdi_pvt::r2chan, dahdi_pvt::radio, ast_channel::rawreadformat, READ_SIZE, restore_conference(), dahdi_pvt::ringt, ast_frame::samples, send_callerid(), dahdi_pvt::sig, dahdi_pvt::sig_pvt, ast_frame::src, SUB_CALLWAIT, SUB_REAL, ast_frame::subclass, dahdi_pvt::subs, dahdi_pvt::tdd, tdd_feed(), ast_channel::tech_pvt, dahdi_pvt::waitfordialtone, and dahdi_pvt::waitingfordt.
08641 { 08642 struct dahdi_pvt *p = ast->tech_pvt; 08643 int res; 08644 int idx; 08645 void *readbuf; 08646 struct ast_frame *f; 08647 08648 while (ast_mutex_trylock(&p->lock)) { 08649 CHANNEL_DEADLOCK_AVOIDANCE(ast); 08650 } 08651 08652 idx = dahdi_get_index(ast, p, 0); 08653 08654 /* Hang up if we don't really exist */ 08655 if (idx < 0) { 08656 ast_log(LOG_WARNING, "We don't exist?\n"); 08657 ast_mutex_unlock(&p->lock); 08658 return NULL; 08659 } 08660 08661 if ((p->radio || (p->oprmode < 0)) && p->inalarm) { 08662 ast_mutex_unlock(&p->lock); 08663 return NULL; 08664 } 08665 08666 p->subs[idx].f.frametype = AST_FRAME_NULL; 08667 p->subs[idx].f.datalen = 0; 08668 p->subs[idx].f.samples = 0; 08669 p->subs[idx].f.mallocd = 0; 08670 p->subs[idx].f.offset = 0; 08671 p->subs[idx].f.subclass.integer = 0; 08672 p->subs[idx].f.delivery = ast_tv(0,0); 08673 p->subs[idx].f.src = "dahdi_read"; 08674 p->subs[idx].f.data.ptr = NULL; 08675 08676 /* make sure it sends initial key state as first frame */ 08677 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio)) 08678 { 08679 struct dahdi_params ps; 08680 08681 memset(&ps, 0, sizeof(ps)); 08682 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) { 08683 ast_mutex_unlock(&p->lock); 08684 return NULL; 08685 } 08686 p->firstradio = 1; 08687 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08688 if (ps.rxisoffhook) 08689 { 08690 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_KEY; 08691 } 08692 else 08693 { 08694 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_UNKEY; 08695 } 08696 ast_mutex_unlock(&p->lock); 08697 return &p->subs[idx].f; 08698 } 08699 if (p->ringt > 0) { 08700 if (!(--p->ringt)) { 08701 ast_mutex_unlock(&p->lock); 08702 return NULL; 08703 } 08704 } 08705 08706 #ifdef HAVE_OPENR2 08707 if (p->mfcr2) { 08708 openr2_chan_process_event(p->r2chan); 08709 if (OR2_DIR_FORWARD == openr2_chan_get_direction(p->r2chan)) { 08710 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_PROGRESS }, }; 08711 /* if the call is already accepted and we already delivered AST_CONTROL_RINGING 08712 * now enqueue a progress frame to bridge the media up */ 08713 if (p->mfcr2_call_accepted && 08714 !p->mfcr2_progress && 08715 ast->_state == AST_STATE_RINGING) { 08716 ast_log(LOG_DEBUG, "Enqueuing progress frame after R2 accept in chan %d\n", p->channel); 08717 ast_queue_frame(p->owner, &f); 08718 p->mfcr2_progress = 1; 08719 } 08720 } 08721 } 08722 #endif 08723 08724 if (p->subs[idx].needringing) { 08725 /* Send ringing frame if requested */ 08726 p->subs[idx].needringing = 0; 08727 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08728 p->subs[idx].f.subclass.integer = AST_CONTROL_RINGING; 08729 ast_setstate(ast, AST_STATE_RINGING); 08730 ast_mutex_unlock(&p->lock); 08731 return &p->subs[idx].f; 08732 } 08733 08734 if (p->subs[idx].needbusy) { 08735 /* Send busy frame if requested */ 08736 p->subs[idx].needbusy = 0; 08737 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08738 p->subs[idx].f.subclass.integer = AST_CONTROL_BUSY; 08739 ast_mutex_unlock(&p->lock); 08740 return &p->subs[idx].f; 08741 } 08742 08743 if (p->subs[idx].needcongestion) { 08744 /* Send congestion frame if requested */ 08745 p->subs[idx].needcongestion = 0; 08746 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08747 p->subs[idx].f.subclass.integer = AST_CONTROL_CONGESTION; 08748 ast_mutex_unlock(&p->lock); 08749 return &p->subs[idx].f; 08750 } 08751 08752 if (p->subs[idx].needanswer) { 08753 /* Send answer frame if requested */ 08754 p->subs[idx].needanswer = 0; 08755 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08756 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08757 ast_mutex_unlock(&p->lock); 08758 return &p->subs[idx].f; 08759 } 08760 #ifdef HAVE_OPENR2 08761 if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) { 08762 /* openr2 took care of reading and handling any event 08763 (needanswer, needbusy etc), if we continue we will read() 08764 twice, lets just return a null frame. This should only 08765 happen when openr2 is dialing out */ 08766 ast_mutex_unlock(&p->lock); 08767 return &ast_null_frame; 08768 } 08769 #endif 08770 08771 if (p->subs[idx].needflash) { 08772 /* Send answer frame if requested */ 08773 p->subs[idx].needflash = 0; 08774 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08775 p->subs[idx].f.subclass.integer = AST_CONTROL_FLASH; 08776 ast_mutex_unlock(&p->lock); 08777 return &p->subs[idx].f; 08778 } 08779 08780 if (p->subs[idx].needhold) { 08781 /* Send answer frame if requested */ 08782 p->subs[idx].needhold = 0; 08783 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08784 p->subs[idx].f.subclass.integer = AST_CONTROL_HOLD; 08785 ast_mutex_unlock(&p->lock); 08786 ast_debug(1, "Sending hold on '%s'\n", ast->name); 08787 return &p->subs[idx].f; 08788 } 08789 08790 if (p->subs[idx].needunhold) { 08791 /* Send answer frame if requested */ 08792 p->subs[idx].needunhold = 0; 08793 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08794 p->subs[idx].f.subclass.integer = AST_CONTROL_UNHOLD; 08795 ast_mutex_unlock(&p->lock); 08796 ast_debug(1, "Sending unhold on '%s'\n", ast->name); 08797 return &p->subs[idx].f; 08798 } 08799 08800 if (ast->rawreadformat == AST_FORMAT_SLINEAR) { 08801 if (!p->subs[idx].linear) { 08802 p->subs[idx].linear = 1; 08803 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 08804 if (res) 08805 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, idx); 08806 } 08807 } else if ((ast->rawreadformat == AST_FORMAT_ULAW) || 08808 (ast->rawreadformat == AST_FORMAT_ALAW)) { 08809 if (p->subs[idx].linear) { 08810 p->subs[idx].linear = 0; 08811 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 08812 if (res) 08813 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, idx); 08814 } 08815 } else { 08816 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat)); 08817 ast_mutex_unlock(&p->lock); 08818 return NULL; 08819 } 08820 readbuf = ((unsigned char *)p->subs[idx].buffer) + AST_FRIENDLY_OFFSET; 08821 CHECK_BLOCKING(ast); 08822 res = read(p->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE); 08823 ast_clear_flag(ast, AST_FLAG_BLOCKING); 08824 /* Check for hangup */ 08825 if (res < 0) { 08826 f = NULL; 08827 if (res == -1) { 08828 if (errno == EAGAIN) { 08829 /* Return "NULL" frame if there is nobody there */ 08830 ast_mutex_unlock(&p->lock); 08831 return &p->subs[idx].f; 08832 } else if (errno == ELAST) { 08833 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 08834 struct analog_pvt *analog_p = p->sig_pvt; 08835 f = analog_exception(analog_p, ast); 08836 } else { 08837 f = __dahdi_exception(ast); 08838 } 08839 } else 08840 ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno)); 08841 } 08842 ast_mutex_unlock(&p->lock); 08843 return f; 08844 } 08845 if (res != (p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE)) { 08846 ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE); 08847 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 08848 struct analog_pvt *analog_p = p->sig_pvt; 08849 f = analog_exception(analog_p, ast); 08850 } else { 08851 f = __dahdi_exception(ast); 08852 } 08853 ast_mutex_unlock(&p->lock); 08854 return f; 08855 } 08856 if (p->tdd) { /* if in TDD mode, see if we receive that */ 08857 int c; 08858 08859 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 08860 if (c < 0) { 08861 ast_debug(1,"tdd_feed failed\n"); 08862 ast_mutex_unlock(&p->lock); 08863 return NULL; 08864 } 08865 if (c) { /* if a char to return */ 08866 p->subs[idx].f.subclass.integer = 0; 08867 p->subs[idx].f.frametype = AST_FRAME_TEXT; 08868 p->subs[idx].f.mallocd = 0; 08869 p->subs[idx].f.offset = AST_FRIENDLY_OFFSET; 08870 p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET; 08871 p->subs[idx].f.datalen = 1; 08872 *((char *) p->subs[idx].f.data.ptr) = c; 08873 ast_mutex_unlock(&p->lock); 08874 return &p->subs[idx].f; 08875 } 08876 } 08877 if (idx == SUB_REAL) { 08878 /* Ensure the CW timers decrement only on a single subchannel */ 08879 if (p->cidcwexpire) { 08880 if (!--p->cidcwexpire) { 08881 /* Expired CID/CW */ 08882 ast_verb(3, "CPE does not support Call Waiting Caller*ID.\n"); 08883 restore_conference(p); 08884 } 08885 } 08886 if (p->cid_suppress_expire) { 08887 --p->cid_suppress_expire; 08888 } 08889 if (p->callwaitingrepeat) { 08890 if (!--p->callwaitingrepeat) { 08891 /* Expired, Repeat callwaiting tone */ 08892 ++p->callwaitrings; 08893 dahdi_callwait(ast); 08894 } 08895 } 08896 } 08897 if (p->subs[idx].linear) { 08898 p->subs[idx].f.datalen = READ_SIZE * 2; 08899 } else 08900 p->subs[idx].f.datalen = READ_SIZE; 08901 08902 /* Handle CallerID Transmission */ 08903 if ((p->owner == ast) && p->cidspill) { 08904 send_callerid(p); 08905 } 08906 08907 p->subs[idx].f.frametype = AST_FRAME_VOICE; 08908 p->subs[idx].f.subclass.codec = ast->rawreadformat; 08909 p->subs[idx].f.samples = READ_SIZE; 08910 p->subs[idx].f.mallocd = 0; 08911 p->subs[idx].f.offset = AST_FRIENDLY_OFFSET; 08912 p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[idx].buffer[0]); 08913 #if 0 08914 ast_debug(1, "Read %d of voice on %s\n", p->subs[idx].f.datalen, ast->name); 08915 #endif 08916 if (p->dialing || p->radio || /* Transmitting something */ 08917 (idx && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 08918 ((idx == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 08919 ) { 08920 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 08921 don't send anything */ 08922 p->subs[idx].f.frametype = AST_FRAME_NULL; 08923 p->subs[idx].f.subclass.integer = 0; 08924 p->subs[idx].f.samples = 0; 08925 p->subs[idx].f.mallocd = 0; 08926 p->subs[idx].f.offset = 0; 08927 p->subs[idx].f.data.ptr = NULL; 08928 p->subs[idx].f.datalen= 0; 08929 } 08930 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress || p->waitingfordt.tv_sec) && !idx) { 08931 /* Perform busy detection etc on the dahdi line */ 08932 int mute; 08933 08934 f = ast_dsp_process(ast, p->dsp, &p->subs[idx].f); 08935 08936 /* Check if DSP code thinks we should be muting this frame and mute the conference if so */ 08937 mute = ast_dsp_was_muted(p->dsp); 08938 if (p->muting != mute) { 08939 p->muting = mute; 08940 dahdi_confmute(p, mute); 08941 } 08942 08943 if (f) { 08944 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_BUSY)) { 08945 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 08946 /* Treat this as a "hangup" instead of a "busy" on the assumption that 08947 a busy */ 08948 f = NULL; 08949 } 08950 } else if (f->frametype == AST_FRAME_DTMF_BEGIN 08951 || f->frametype == AST_FRAME_DTMF_END) { 08952 #ifdef HAVE_PRI 08953 if (dahdi_sig_pri_lib_handles(p->sig) 08954 && !((struct sig_pri_chan *) p->sig_pvt)->proceeding 08955 && p->pri 08956 && ((!p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) 08957 || (p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)))) { 08958 /* Don't accept in-band DTMF when in overlap dial mode */ 08959 ast_debug(1, "Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n", 08960 f->frametype == AST_FRAME_DTMF_BEGIN ? "begin" : "end", 08961 f->subclass.integer, f->subclass.integer, ast->name); 08962 08963 f->frametype = AST_FRAME_NULL; 08964 f->subclass.integer = 0; 08965 } 08966 #endif 08967 /* DSP clears us of being pulse */ 08968 p->pulsedial = 0; 08969 } else if (p->waitingfordt.tv_sec) { 08970 if (ast_tvdiff_ms(ast_tvnow(), p->waitingfordt) >= p->waitfordialtone ) { 08971 p->waitingfordt.tv_sec = 0; 08972 ast_log(LOG_WARNING, "Never saw dialtone on channel %d\n", p->channel); 08973 f=NULL; 08974 } else if (f->frametype == AST_FRAME_VOICE) { 08975 f->frametype = AST_FRAME_NULL; 08976 f->subclass.integer = 0; 08977 if ((ast_dsp_get_tstate(p->dsp) == DSP_TONE_STATE_DIALTONE || ast_dsp_get_tstate(p->dsp) == DSP_TONE_STATE_RINGING) && ast_dsp_get_tcount(p->dsp) > 9) { 08978 p->waitingfordt.tv_sec = 0; 08979 p->dsp_features &= ~DSP_FEATURE_WAITDIALTONE; 08980 ast_dsp_set_features(p->dsp, p->dsp_features); 08981 ast_log(LOG_DEBUG, "Got 10 samples of dialtone!\n"); 08982 if (!ast_strlen_zero(p->dop.dialstr)) { /* Dial deferred digits */ 08983 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08984 if (res < 0) { 08985 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 08986 p->dop.dialstr[0] = '\0'; 08987 ast_mutex_unlock(&p->lock); 08988 return NULL; 08989 } else { 08990 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 08991 p->dialing = 1; 08992 p->dop.dialstr[0] = '\0'; 08993 p->dop.op = DAHDI_DIAL_OP_REPLACE; 08994 ast_setstate(ast, AST_STATE_DIALING); 08995 } 08996 } 08997 } 08998 } 08999 } 09000 } 09001 } else 09002 f = &p->subs[idx].f; 09003 09004 if (f) { 09005 switch (f->frametype) { 09006 case AST_FRAME_DTMF_BEGIN: 09007 case AST_FRAME_DTMF_END: 09008 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09009 analog_handle_dtmf(p->sig_pvt, ast, idx, &f); 09010 } else { 09011 dahdi_handle_dtmf(ast, idx, &f); 09012 } 09013 break; 09014 case AST_FRAME_VOICE: 09015 if (p->cidspill || p->cid_suppress_expire) { 09016 /* We are/were sending a caller id spill. Suppress any echo. */ 09017 p->subs[idx].f.frametype = AST_FRAME_NULL; 09018 p->subs[idx].f.subclass.integer = 0; 09019 p->subs[idx].f.samples = 0; 09020 p->subs[idx].f.mallocd = 0; 09021 p->subs[idx].f.offset = 0; 09022 p->subs[idx].f.data.ptr = NULL; 09023 p->subs[idx].f.datalen= 0; 09024 } 09025 break; 09026 default: 09027 break; 09028 } 09029 } 09030 09031 /* If we have a fake_event, trigger exception to handle it */ 09032 if (p->fake_event) 09033 ast_set_flag(ast, AST_FLAG_EXCEPTION); 09034 09035 ast_mutex_unlock(&p->lock); 09036 return f; 09037 }
static struct ast_channel * dahdi_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 13261 of file chan_dahdi.c.
References analog_lib_handles(), analog_request(), ast_atomic_fetchadd_int(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_STATE_RESERVED, AST_TRANS_CAP_DIGITAL, available(), dahdi_starting_point::backwards, dahdi_starting_point::cadance, CHAN_PSEUDO, dahdi_pvt::channel, dahdi_starting_point::channelmatch, dahdi_pvt::confirmanswer, dahdi_new(), dahdi_sig_pri_lib_handles(), determine_starting_point(), dahdi_pvt::dialstring, dahdi_pvt::distinctivering, dahdi_pvt::dnid, duplicate_pseudo(), dahdi_starting_point::groupmatch, ifend, iflist, iflock, is_group_or_channel_match(), ast_channel::linkedid, dahdi_pvt::lock, LOG_DEBUG, dahdi_pvt::mfcr2, dahdi_pvt::mfcr2call, dahdi_pvt::next, dahdi_pvt::oprmode, dahdi_starting_point::opt, dahdi_pvt::outgoing, dahdi_pvt::owner, dahdi_pvt::prev, dahdi_pvt::pri, dahdi_pvt::radio, restart_monitor(), round_robin, dahdi_starting_point::roundrobin, dahdi_starting_point::rr_starting_point, dahdi_pvt::sig, SIG_PRI_DEFLAW, sig_pri_extract_called_num_subaddr(), SIG_PRI_LIB_HANDLE_CASES, sig_pri_request(), dahdi_pvt::sig_pvt, SIG_SS7, SIG_SS7_DEFLAW, sig_ss7_request(), dahdi_starting_point::span, SUB_CALLWAIT, and SUB_REAL.
13262 { 13263 int callwait = 0; 13264 struct dahdi_pvt *p; 13265 struct ast_channel *tmp = NULL; 13266 struct dahdi_pvt *exitpvt; 13267 int channelmatched = 0; 13268 int groupmatched = 0; 13269 int transcapdigital = 0; 13270 struct dahdi_starting_point start; 13271 13272 ast_mutex_lock(&iflock); 13273 p = determine_starting_point(data, &start); 13274 if (!p) { 13275 /* We couldn't determine a starting point, which likely means badly-formatted channel name. Abort! */ 13276 ast_mutex_unlock(&iflock); 13277 return NULL; 13278 } 13279 13280 /* Search for an unowned channel */ 13281 exitpvt = p; 13282 while (p && !tmp) { 13283 if (start.roundrobin) 13284 round_robin[start.rr_starting_point] = p; 13285 13286 if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched) 13287 && available(&p, channelmatched)) { 13288 ast_debug(1, "Using channel %d\n", p->channel); 13289 13290 callwait = (p->owner != NULL); 13291 #ifdef HAVE_OPENR2 13292 if (p->mfcr2) { 13293 ast_mutex_lock(&p->lock); 13294 if (p->mfcr2call) { 13295 ast_mutex_unlock(&p->lock); 13296 ast_log(LOG_DEBUG, "Yay!, someone just beat us in the race for channel %d.\n", p->channel); 13297 goto next; 13298 } 13299 p->mfcr2call = 1; 13300 ast_mutex_unlock(&p->lock); 13301 } 13302 #endif 13303 if (p->channel == CHAN_PSEUDO) { 13304 p = duplicate_pseudo(p); 13305 if (!p) { 13306 break; 13307 } 13308 } 13309 13310 /* Make special notes */ 13311 switch (start.opt) { 13312 case '\0': 13313 /* No option present. */ 13314 break; 13315 case 'c': 13316 /* Confirm answer */ 13317 p->confirmanswer = 1; 13318 break; 13319 case 'r': 13320 /* Distinctive ring */ 13321 p->distinctivering = start.cadance; 13322 break; 13323 case 'd': 13324 /* If this is an ISDN call, make it digital */ 13325 transcapdigital = AST_TRANS_CAP_DIGITAL; 13326 break; 13327 default: 13328 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", start.opt, (char *)data); 13329 break; 13330 } 13331 13332 p->outgoing = 1; 13333 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 13334 tmp = analog_request(p->sig_pvt, &callwait, requestor); 13335 #ifdef HAVE_PRI 13336 } else if (dahdi_sig_pri_lib_handles(p->sig)) { 13337 sig_pri_extract_called_num_subaddr(p->sig_pvt, data, p->dnid, 13338 sizeof(p->dnid)); 13339 tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW, requestor, transcapdigital); 13340 #endif 13341 #if defined(HAVE_SS7) 13342 } else if (p->sig == SIG_SS7) { 13343 tmp = sig_ss7_request(p->sig_pvt, SIG_SS7_DEFLAW, requestor, transcapdigital); 13344 #endif /* defined(HAVE_SS7) */ 13345 } else { 13346 tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, requestor ? requestor->linkedid : ""); 13347 } 13348 if (!tmp) { 13349 p->outgoing = 0; 13350 #if defined(HAVE_PRI) 13351 #if defined(HAVE_PRI_CALL_WAITING) 13352 switch (p->sig) { 13353 case SIG_PRI_LIB_HANDLE_CASES: 13354 if (((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting) { 13355 ((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting = 0; 13356 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1); 13357 } 13358 break; 13359 default: 13360 break; 13361 } 13362 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 13363 #endif /* defined(HAVE_PRI) */ 13364 } else { 13365 snprintf(p->dialstring, sizeof(p->dialstring), "DAHDI/%s", (char *) data); 13366 } 13367 break; 13368 } 13369 #ifdef HAVE_OPENR2 13370 next: 13371 #endif 13372 if (start.backwards) { 13373 p = p->prev; 13374 if (!p) 13375 p = ifend; 13376 } else { 13377 p = p->next; 13378 if (!p) 13379 p = iflist; 13380 } 13381 /* stop when you roll to the one that we started from */ 13382 if (p == exitpvt) 13383 break; 13384 } 13385 ast_mutex_unlock(&iflock); 13386 restart_monitor(); 13387 if (cause && !tmp) { 13388 if (callwait || channelmatched) { 13389 *cause = AST_CAUSE_BUSY; 13390 } else if (groupmatched) { 13391 *cause = AST_CAUSE_CONGESTION; 13392 } else { 13393 /* 13394 * We did not match any channel requested. 13395 * Dialplan error requesting non-existant channel? 13396 */ 13397 } 13398 } 13399 13400 return tmp; 13401 }
static int dahdi_restart | ( | void | ) | [static] |
Definition at line 14626 of file chan_dahdi.c.
References ast_debug, ast_mutex_lock, AST_PTHREADT_NULL, ast_verb, dahdi_r2_destroy_links(), dahdi_softhangup_all(), sig_pri_span::master, dahdi_pri::pri, dahdi_pvt::pri, pris, and restart_lock.
Referenced by action_dahdirestart(), and dahdi_restart_cmd().
14627 { 14628 #if defined(HAVE_PRI) || defined(HAVE_SS7) 14629 int i, j; 14630 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 14631 int cancel_code; 14632 struct dahdi_pvt *p; 14633 14634 ast_mutex_lock(&restart_lock); 14635 ast_verb(1, "Destroying channels and reloading DAHDI configuration.\n"); 14636 dahdi_softhangup_all(); 14637 ast_verb(4, "Initial softhangup of all DAHDI channels complete.\n"); 14638 #ifdef HAVE_OPENR2 14639 dahdi_r2_destroy_links(); 14640 #endif 14641 14642 #if defined(HAVE_PRI) 14643 for (i = 0; i < NUM_SPANS; i++) { 14644 if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) { 14645 cancel_code = pthread_cancel(pris[i].pri.master); 14646 pthread_kill(pris[i].pri.master, SIGURG); 14647 ast_debug(4, "Waiting to join thread of span %d with pid=%p, cancel_code=%d\n", i, (void *) pris[i].pri.master, cancel_code); 14648 pthread_join(pris[i].pri.master, NULL); 14649 ast_debug(4, "Joined thread of span %d\n", i); 14650 } 14651 } 14652 #endif 14653 14654 #if defined(HAVE_SS7) 14655 for (i = 0; i < NUM_SPANS; i++) { 14656 if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) { 14657 cancel_code = pthread_cancel(linksets[i].ss7.master); 14658 pthread_kill(linksets[i].ss7.master, SIGURG); 14659 ast_debug(4, "Waiting to join thread of span %d with pid=%p, cancel_code=%d\n", i, (void *) linksets[i].ss7.master, cancel_code); 14660 pthread_join(linksets[i].ss7.master, NULL); 14661 ast_debug(4, "Joined thread of span %d\n", i); 14662 } 14663 } 14664 #endif /* defined(HAVE_SS7) */ 14665 14666 ast_mutex_lock(&monlock); 14667 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 14668 cancel_code = pthread_cancel(monitor_thread); 14669 pthread_kill(monitor_thread, SIGURG); 14670 ast_debug(4, "Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (void *) monitor_thread, cancel_code); 14671 pthread_join(monitor_thread, NULL); 14672 ast_debug(4, "Joined monitor thread\n"); 14673 } 14674 monitor_thread = AST_PTHREADT_NULL; /* prepare to restart thread in setup_dahdi once channels are reconfigured */ 14675 14676 ast_mutex_lock(&ss_thread_lock); 14677 while (ss_thread_count > 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */ 14678 int x = DAHDI_FLASH; 14679 ast_debug(3, "Waiting on %d analog_ss_thread(s) to finish\n", ss_thread_count); 14680 14681 ast_mutex_lock(&iflock); 14682 for (p = iflist; p; p = p->next) { 14683 if (p->owner) { 14684 /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */ 14685 ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 14686 } 14687 } 14688 ast_mutex_unlock(&iflock); 14689 ast_cond_wait(&ss_thread_complete, &ss_thread_lock); 14690 } 14691 14692 /* ensure any created channels before monitor threads were stopped are hungup */ 14693 dahdi_softhangup_all(); 14694 ast_verb(4, "Final softhangup of all DAHDI channels complete.\n"); 14695 destroy_all_channels(); 14696 ast_debug(1, "Channels destroyed. Now re-reading config. %d active channels remaining.\n", ast_active_channels()); 14697 14698 ast_mutex_unlock(&monlock); 14699 14700 #ifdef HAVE_PRI 14701 for (i = 0; i < NUM_SPANS; i++) { 14702 for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) 14703 dahdi_close_pri_fd(&(pris[i]), j); 14704 } 14705 14706 memset(pris, 0, sizeof(pris)); 14707 for (i = 0; i < NUM_SPANS; i++) { 14708 sig_pri_init_pri(&pris[i].pri); 14709 } 14710 pri_set_error(dahdi_pri_error); 14711 pri_set_message(dahdi_pri_message); 14712 #endif 14713 #if defined(HAVE_SS7) 14714 for (i = 0; i < NUM_SPANS; i++) { 14715 for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) 14716 dahdi_close_ss7_fd(&(linksets[i]), j); 14717 } 14718 14719 memset(linksets, 0, sizeof(linksets)); 14720 for (i = 0; i < NUM_SPANS; i++) { 14721 sig_ss7_init_linkset(&linksets[i].ss7); 14722 } 14723 ss7_set_error(dahdi_ss7_error); 14724 ss7_set_message(dahdi_ss7_message); 14725 #endif /* defined(HAVE_SS7) */ 14726 14727 if (setup_dahdi(2) != 0) { 14728 ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n"); 14729 ast_mutex_unlock(&ss_thread_lock); 14730 return 1; 14731 } 14732 ast_mutex_unlock(&ss_thread_lock); 14733 ast_mutex_unlock(&restart_lock); 14734 return 0; 14735 }
static char* dahdi_restart_cmd | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14737 of file chan_dahdi.c.
References ast_cli_args::argc, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_restart(), and ast_cli_entry::usage.
14738 { 14739 switch (cmd) { 14740 case CLI_INIT: 14741 e->command = "dahdi restart"; 14742 e->usage = 14743 "Usage: dahdi restart\n" 14744 " Restarts the DAHDI channels: destroys them all and then\n" 14745 " re-reads them from chan_dahdi.conf.\n" 14746 " Note that this will STOP any running CALL on DAHDI channels.\n" 14747 ""; 14748 return NULL; 14749 case CLI_GENERATE: 14750 return NULL; 14751 } 14752 if (a->argc != 2) 14753 return CLI_SHOWUSAGE; 14754 14755 if (dahdi_restart() != 0) 14756 return CLI_FAILURE; 14757 return CLI_SUCCESS; 14758 }
static int dahdi_ring_phone | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7388 of file chan_dahdi.c.
References ast_log(), errno, SUB_REAL, and dahdi_pvt::subs.
Referenced by __dahdi_exception(), dahdi_handle_event(), and my_ring().
07389 { 07390 int x; 07391 int res; 07392 /* Make sure our transmit state is on hook */ 07393 x = 0; 07394 x = DAHDI_ONHOOK; 07395 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 07396 do { 07397 x = DAHDI_RING; 07398 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 07399 if (res) { 07400 switch (errno) { 07401 case EBUSY: 07402 case EINTR: 07403 /* Wait just in case */ 07404 usleep(10000); 07405 continue; 07406 case EINPROGRESS: 07407 res = 0; 07408 break; 07409 default: 07410 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 07411 res = 0; 07412 } 07413 } 07414 } while (res); 07415 return res; 07416 }
static int dahdi_send_callrerouting_facility_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 5778 of file chan_dahdi.c.
References ast_channel::_state, args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), dahdi_tech, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::name, parse(), pri_send_callrerouting_facility_exec(), dahdi_pvt::sig, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, ast_channel::tech, and ast_channel::tech_pvt.
Referenced by load_module().
05779 { 05780 /* Data will be our digit string */ 05781 struct dahdi_pvt *pvt; 05782 char *parse; 05783 int res = -1; 05784 AST_DECLARE_APP_ARGS(args, 05785 AST_APP_ARG(destination); 05786 AST_APP_ARG(original); 05787 AST_APP_ARG(reason); 05788 ); 05789 05790 if (ast_strlen_zero(data)) { 05791 ast_log(LOG_DEBUG, "No data sent to application!\n"); 05792 return -1; 05793 } 05794 if (chan->tech != &dahdi_tech) { 05795 ast_log(LOG_DEBUG, "Only DAHDI technology accepted!\n"); 05796 return -1; 05797 } 05798 pvt = (struct dahdi_pvt *) chan->tech_pvt; 05799 if (!pvt) { 05800 ast_log(LOG_DEBUG, "Unable to find technology private\n"); 05801 return -1; 05802 } 05803 switch (pvt->sig) { 05804 case SIG_PRI_LIB_HANDLE_CASES: 05805 break; 05806 default: 05807 ast_log(LOG_DEBUG, "callrerouting attempted on non-ISDN channel %s\n", 05808 chan->name); 05809 return -1; 05810 } 05811 05812 parse = ast_strdupa(data); 05813 AST_STANDARD_APP_ARGS(args, parse); 05814 05815 if (ast_strlen_zero(args.destination)) { 05816 ast_log(LOG_WARNING, "callrerouting facility requires at least destination number argument\n"); 05817 return -1; 05818 } 05819 05820 if (ast_strlen_zero(args.original)) { 05821 ast_log(LOG_WARNING, "Callrerouting Facility without original called number argument\n"); 05822 args.original = NULL; 05823 } 05824 05825 if (ast_strlen_zero(args.reason)) { 05826 ast_log(LOG_NOTICE, "Callrerouting Facility without diversion reason argument, defaulting to unknown\n"); 05827 args.reason = NULL; 05828 } 05829 05830 pri_send_callrerouting_facility_exec(pvt->sig_pvt, chan->_state, args.destination, 05831 args.original, args.reason); 05832 05833 return res; 05834 }
static int dahdi_send_keypad_facility_exec | ( | struct ast_channel * | chan, | |
const char * | digits | |||
) | [static] |
Definition at line 5751 of file chan_dahdi.c.
References ast_debug, ast_strlen_zero(), pri_send_keypad_facility_exec(), dahdi_pvt::sig_pvt, and ast_channel::tech_pvt.
Referenced by load_module().
05752 { 05753 /* Data will be our digit string */ 05754 struct dahdi_pvt *p; 05755 05756 if (ast_strlen_zero(digits)) { 05757 ast_debug(1, "No digit string sent to application!\n"); 05758 return -1; 05759 } 05760 05761 p = (struct dahdi_pvt *)chan->tech_pvt; 05762 05763 if (!p) { 05764 ast_debug(1, "Unable to find technology private\n"); 05765 return -1; 05766 } 05767 05768 pri_send_keypad_facility_exec(p->sig_pvt, digits); 05769 05770 return 0; 05771 }
static int dahdi_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 18051 of file chan_dahdi.c.
References ASCII_BYTES_PER_CHAR, ast_check_hangup(), ast_debug, ast_free, AST_LAW, ast_log(), ast_malloc, dahdi_pvt::channel, dahdi_get_index, dahdi_subchannel::dfd, END_SILENCE_LEN, errno, HEADER_LEN, HEADER_MS, len(), dahdi_pvt::mate, PUT_CLID, PUT_CLID_MARKMS, READ_SIZE, dahdi_pvt::subs, dahdi_pvt::tdd, TDD_BYTES_PER_CHAR, tdd_generate(), ast_channel::tech_pvt, and TRAILER_MS.
18052 { 18053 #define END_SILENCE_LEN 400 18054 #define HEADER_MS 50 18055 #define TRAILER_MS 5 18056 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 18057 #define ASCII_BYTES_PER_CHAR 80 18058 18059 unsigned char *buf,*mybuf; 18060 struct dahdi_pvt *p = c->tech_pvt; 18061 struct pollfd fds[1]; 18062 int size,res,fd,len,x; 18063 int bytes=0; 18064 /* Initial carrier (imaginary) */ 18065 float cr = 1.0; 18066 float ci = 0.0; 18067 float scont = 0.0; 18068 int idx; 18069 18070 idx = dahdi_get_index(c, p, 0); 18071 if (idx < 0) { 18072 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 18073 return -1; 18074 } 18075 if (!text[0]) return(0); /* if nothing to send, don't */ 18076 if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ 18077 if (p->mate) 18078 buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 18079 else 18080 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 18081 if (!buf) 18082 return -1; 18083 mybuf = buf; 18084 if (p->mate) { 18085 int codec = AST_LAW(p); 18086 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */ 18087 PUT_CLID_MARKMS; 18088 } 18089 /* Put actual message */ 18090 for (x = 0; text[x]; x++) { 18091 PUT_CLID(text[x]); 18092 } 18093 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */ 18094 PUT_CLID_MARKMS; 18095 } 18096 len = bytes; 18097 buf = mybuf; 18098 } else { 18099 len = tdd_generate(p->tdd, buf, text); 18100 if (len < 1) { 18101 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text)); 18102 ast_free(mybuf); 18103 return -1; 18104 } 18105 } 18106 memset(buf + len, 0x7f, END_SILENCE_LEN); 18107 len += END_SILENCE_LEN; 18108 fd = p->subs[idx].dfd; 18109 while (len) { 18110 if (ast_check_hangup(c)) { 18111 ast_free(mybuf); 18112 return -1; 18113 } 18114 size = len; 18115 if (size > READ_SIZE) 18116 size = READ_SIZE; 18117 fds[0].fd = fd; 18118 fds[0].events = POLLOUT | POLLPRI; 18119 fds[0].revents = 0; 18120 res = poll(fds, 1, -1); 18121 if (!res) { 18122 ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel); 18123 continue; 18124 } 18125 /* if got exception */ 18126 if (fds[0].revents & POLLPRI) { 18127 ast_free(mybuf); 18128 return -1; 18129 } 18130 if (!(fds[0].revents & POLLOUT)) { 18131 ast_debug(1, "write fd not ready on channel %d\n", p->channel); 18132 continue; 18133 } 18134 res = write(fd, buf, size); 18135 if (res != size) { 18136 if (res == -1) { 18137 ast_free(mybuf); 18138 return -1; 18139 } 18140 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 18141 break; 18142 } 18143 len -= size; 18144 buf += size; 18145 } 18146 ast_free(mybuf); 18147 return(0); 18148 }
static char* dahdi_set_dnd | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15349 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_false(), ast_mutex_lock, ast_mutex_unlock, ast_true(), dahdi_pvt::channel, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_dnd(), ast_cli_args::fd, iflist, dahdi_pvt::next, and ast_cli_entry::usage.
15350 { 15351 int channel; 15352 int on; 15353 struct dahdi_pvt *dahdi_chan = NULL; 15354 15355 switch (cmd) { 15356 case CLI_INIT: 15357 e->command = "dahdi set dnd"; 15358 e->usage = 15359 "Usage: dahdi set dnd <chan#> <on|off>\n" 15360 " Sets/resets DND (Do Not Disturb) mode on a channel.\n" 15361 " Changes take effect immediately.\n" 15362 " <chan num> is the channel number\n" 15363 " <on|off> Enable or disable DND mode?\n" 15364 ; 15365 return NULL; 15366 case CLI_GENERATE: 15367 return NULL; 15368 } 15369 15370 if (a->argc != 5) 15371 return CLI_SHOWUSAGE; 15372 15373 if ((channel = atoi(a->argv[3])) <= 0) { 15374 ast_cli(a->fd, "Expected channel number, got '%s'\n", a->argv[3]); 15375 return CLI_SHOWUSAGE; 15376 } 15377 15378 if (ast_true(a->argv[4])) 15379 on = 1; 15380 else if (ast_false(a->argv[4])) 15381 on = 0; 15382 else { 15383 ast_cli(a->fd, "Expected 'on' or 'off', got '%s'\n", a->argv[4]); 15384 return CLI_SHOWUSAGE; 15385 } 15386 15387 ast_mutex_lock(&iflock); 15388 for (dahdi_chan = iflist; dahdi_chan; dahdi_chan = dahdi_chan->next) { 15389 if (dahdi_chan->channel != channel) 15390 continue; 15391 15392 /* Found the channel. Actually set it */ 15393 dahdi_dnd(dahdi_chan, on); 15394 break; 15395 } 15396 ast_mutex_unlock(&iflock); 15397 15398 if (!dahdi_chan) { 15399 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15400 return CLI_FAILURE; 15401 } 15402 15403 return CLI_SUCCESS; 15404 }
static int dahdi_set_hook | ( | int | fd, | |
int | hs | |||
) | [inline, static] |
Definition at line 5011 of file chan_dahdi.c.
References ast_log(), errno, and LOG_WARNING.
Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_handle_event(), dahdi_hangup(), dahdi_indicate(), dahdi_wink(), handle_init_event(), mwi_send_process_buffer(), mwi_send_process_event(), my_off_hook(), and my_on_hook().
05012 { 05013 int x, res; 05014 05015 x = hs; 05016 res = ioctl(fd, DAHDI_HOOK, &x); 05017 05018 if (res < 0) { 05019 if (errno == EINPROGRESS) 05020 return 0; 05021 ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno)); 05022 /* will expectedly fail if phone is off hook during operation, such as during a restart */ 05023 } 05024 05025 return res; 05026 }
static char* dahdi_set_hwgain | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15209 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, errno, ast_cli_args::fd, iflist, dahdi_pvt::next, SUB_REAL, dahdi_pvt::subs, and ast_cli_entry::usage.
15210 { 15211 int channel; 15212 int gain; 15213 int tx; 15214 struct dahdi_hwgain hwgain; 15215 struct dahdi_pvt *tmp = NULL; 15216 15217 switch (cmd) { 15218 case CLI_INIT: 15219 e->command = "dahdi set hwgain"; 15220 e->usage = 15221 "Usage: dahdi set hwgain <rx|tx> <chan#> <gain>\n" 15222 " Sets the hardware gain on a a given channel, overriding the\n" 15223 " value provided at module loadtime, whether the channel is in\n" 15224 " use or not. Changes take effect immediately.\n" 15225 " <rx|tx> which direction do you want to change (relative to our module)\n" 15226 " <chan num> is the channel number relative to the device\n" 15227 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"; 15228 return NULL; 15229 case CLI_GENERATE: 15230 return NULL; 15231 } 15232 15233 if (a->argc != 6) 15234 return CLI_SHOWUSAGE; 15235 15236 if (!strcasecmp("rx", a->argv[3])) 15237 tx = 0; /* rx */ 15238 else if (!strcasecmp("tx", a->argv[3])) 15239 tx = 1; /* tx */ 15240 else 15241 return CLI_SHOWUSAGE; 15242 15243 channel = atoi(a->argv[4]); 15244 gain = atof(a->argv[5])*10.0; 15245 15246 ast_mutex_lock(&iflock); 15247 15248 for (tmp = iflist; tmp; tmp = tmp->next) { 15249 15250 if (tmp->channel != channel) 15251 continue; 15252 15253 if (tmp->subs[SUB_REAL].dfd == -1) 15254 break; 15255 15256 hwgain.newgain = gain; 15257 hwgain.tx = tx; 15258 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_HWGAIN, &hwgain) < 0) { 15259 ast_cli(a->fd, "Unable to set the hardware gain for channel %d: %s\n", channel, strerror(errno)); 15260 ast_mutex_unlock(&iflock); 15261 return CLI_FAILURE; 15262 } 15263 ast_cli(a->fd, "hardware %s gain set to %d (%.1f dB) on channel %d\n", 15264 tx ? "tx" : "rx", gain, (float)gain/10.0, channel); 15265 break; 15266 } 15267 15268 ast_mutex_unlock(&iflock); 15269 15270 if (tmp) 15271 return CLI_SUCCESS; 15272 15273 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15274 return CLI_FAILURE; 15275 15276 }
static char* dahdi_set_swgain | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15278 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iflist, dahdi_pvt::law, dahdi_pvt::next, dahdi_pvt::rxdrc, set_actual_rxgain(), set_actual_txgain(), SUB_REAL, dahdi_pvt::subs, dahdi_pvt::txdrc, and ast_cli_entry::usage.
15279 { 15280 int channel; 15281 float gain; 15282 int tx; 15283 int res; 15284 struct dahdi_pvt *tmp = NULL; 15285 15286 switch (cmd) { 15287 case CLI_INIT: 15288 e->command = "dahdi set swgain"; 15289 e->usage = 15290 "Usage: dahdi set swgain <rx|tx> <chan#> <gain>\n" 15291 " Sets the software gain on a a given channel, overriding the\n" 15292 " value provided at module loadtime, whether the channel is in\n" 15293 " use or not. Changes take effect immediately.\n" 15294 " <rx|tx> which direction do you want to change (relative to our module)\n" 15295 " <chan num> is the channel number relative to the device\n" 15296 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"; 15297 return NULL; 15298 case CLI_GENERATE: 15299 return NULL; 15300 } 15301 15302 if (a->argc != 6) 15303 return CLI_SHOWUSAGE; 15304 15305 if (!strcasecmp("rx", a->argv[3])) 15306 tx = 0; /* rx */ 15307 else if (!strcasecmp("tx", a->argv[3])) 15308 tx = 1; /* tx */ 15309 else 15310 return CLI_SHOWUSAGE; 15311 15312 channel = atoi(a->argv[4]); 15313 gain = atof(a->argv[5]); 15314 15315 ast_mutex_lock(&iflock); 15316 for (tmp = iflist; tmp; tmp = tmp->next) { 15317 15318 if (tmp->channel != channel) 15319 continue; 15320 15321 if (tmp->subs[SUB_REAL].dfd == -1) 15322 break; 15323 15324 if (tx) 15325 res = set_actual_txgain(tmp->subs[SUB_REAL].dfd, gain, tmp->txdrc, tmp->law); 15326 else 15327 res = set_actual_rxgain(tmp->subs[SUB_REAL].dfd, gain, tmp->rxdrc, tmp->law); 15328 15329 if (res) { 15330 ast_cli(a->fd, "Unable to set the software gain for channel %d\n", channel); 15331 ast_mutex_unlock(&iflock); 15332 return CLI_FAILURE; 15333 } 15334 15335 ast_cli(a->fd, "software %s gain set to %.1f on channel %d\n", 15336 tx ? "tx" : "rx", gain, channel); 15337 break; 15338 } 15339 ast_mutex_unlock(&iflock); 15340 15341 if (tmp) 15342 return CLI_SUCCESS; 15343 15344 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15345 return CLI_FAILURE; 15346 15347 }
static int dahdi_setlaw | ( | int | dfd, | |
int | law | |||
) | [static] |
Definition at line 2485 of file chan_dahdi.c.
Referenced by my_new_pri_ast_channel(), my_new_ss7_ast_channel(), and my_pri_open_media().
02486 { 02487 int res; 02488 res = ioctl(dfd, DAHDI_SETLAW, &law); 02489 if (res) 02490 return res; 02491 return 0; 02492 }
static int dahdi_setlinear | ( | int | dfd, | |
int | linear | |||
) | [static] |
Definition at line 4240 of file chan_dahdi.c.
Referenced by analog_ss_thread(), dahdi_hangup(), dahdi_new(), dahdi_read(), dahdi_write(), my_all_subchannels_hungup(), my_set_linear_mode(), my_start_cid_detect(), my_stop_cid_detect(), and send_callerid().
static int dahdi_setoption | ( | struct ast_channel * | chan, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 6532 of file chan_dahdi.c.
References ast_check_hangup(), ast_debug, ast_dsp_set_digitmode(), ast_dsp_set_features(), ast_log(), AST_OPTION_AUDIO_MODE, AST_OPTION_DIGIT_DETECT, AST_OPTION_ECHOCAN, AST_OPTION_FAX_DETECT, AST_OPTION_OPRMODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_tdd_gen_ecdisa(), dahdi_pvt::channel, dahdi_disable_ec(), dahdi_enable_ec(), dahdi_get_index, dahdi_sig_pri_lib_handles(), dahdi_subchannel::dfd, dahdi_pvt::didtdd, disable_dtmf_detect(), dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_FAX_DETECT, dahdi_pvt::dsp_features, dahdi_pvt::dtmfrelax, enable_dtmf_detect(), errno, dahdi_pvt::law, len(), LOG_NOTICE, LOG_WARNING, dahdi_pvt::mate, oprmode::mode, ast_channel::name, dahdi_pvt::oprmode, dahdi_pvt::oprpeer, oprmode::peer, pp, READ_SIZE, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, set_actual_rxgain(), set_actual_txgain(), dahdi_pvt::sig, dahdi_pvt::sig_pvt, SUB_REAL, dahdi_pvt::subs, dahdi_pvt::tdd, tdd_free(), tdd_new(), ast_channel::tech, ast_channel::tech_pvt, dahdi_pvt::txdrc, dahdi_pvt::txgain, and ast_channel_tech::type.
06533 { 06534 char *cp; 06535 signed char *scp; 06536 int x; 06537 int idx; 06538 struct dahdi_pvt *p = chan->tech_pvt, *pp; 06539 struct oprmode *oprmode; 06540 06541 06542 /* all supported options require data */ 06543 if (!data || (datalen < 1)) { 06544 errno = EINVAL; 06545 return -1; 06546 } 06547 06548 switch (option) { 06549 case AST_OPTION_TXGAIN: 06550 scp = (signed char *) data; 06551 idx = dahdi_get_index(chan, p, 0); 06552 if (idx < 0) { 06553 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 06554 return -1; 06555 } 06556 ast_debug(1, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp); 06557 return set_actual_txgain(p->subs[idx].dfd, p->txgain + (float) *scp, p->txdrc, p->law); 06558 case AST_OPTION_RXGAIN: 06559 scp = (signed char *) data; 06560 idx = dahdi_get_index(chan, p, 0); 06561 if (idx < 0) { 06562 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 06563 return -1; 06564 } 06565 ast_debug(1, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp); 06566 return set_actual_rxgain(p->subs[idx].dfd, p->rxgain + (float) *scp, p->rxdrc, p->law); 06567 case AST_OPTION_TONE_VERIFY: 06568 if (!p->dsp) 06569 break; 06570 cp = (char *) data; 06571 switch (*cp) { 06572 case 1: 06573 ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name); 06574 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 06575 break; 06576 case 2: 06577 ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name); 06578 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 06579 break; 06580 default: 06581 ast_debug(1, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name); 06582 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 06583 break; 06584 } 06585 break; 06586 case AST_OPTION_TDD: 06587 /* turn on or off TDD */ 06588 cp = (char *) data; 06589 p->mate = 0; 06590 if (!*cp) { /* turn it off */ 06591 ast_debug(1, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name); 06592 if (p->tdd) 06593 tdd_free(p->tdd); 06594 p->tdd = 0; 06595 break; 06596 } 06597 ast_debug(1, "Set option TDD MODE, value: %s(%d) on %s\n", 06598 (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name); 06599 dahdi_disable_ec(p); 06600 /* otherwise, turn it on */ 06601 if (!p->didtdd) { /* if havent done it yet */ 06602 unsigned char mybuf[41000];/*! \todo XXX This is an abuse of the stack!! */ 06603 unsigned char *buf; 06604 int size, res, fd, len; 06605 struct pollfd fds[1]; 06606 06607 buf = mybuf; 06608 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 06609 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 06610 len = 40000; 06611 idx = dahdi_get_index(chan, p, 0); 06612 if (idx < 0) { 06613 ast_log(LOG_WARNING, "No index in TDD?\n"); 06614 return -1; 06615 } 06616 fd = p->subs[idx].dfd; 06617 while (len) { 06618 if (ast_check_hangup(chan)) 06619 return -1; 06620 size = len; 06621 if (size > READ_SIZE) 06622 size = READ_SIZE; 06623 fds[0].fd = fd; 06624 fds[0].events = POLLPRI | POLLOUT; 06625 fds[0].revents = 0; 06626 res = poll(fds, 1, -1); 06627 if (!res) { 06628 ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel); 06629 continue; 06630 } 06631 /* if got exception */ 06632 if (fds[0].revents & POLLPRI) 06633 return -1; 06634 if (!(fds[0].revents & POLLOUT)) { 06635 ast_debug(1, "write fd not ready on channel %d\n", p->channel); 06636 continue; 06637 } 06638 res = write(fd, buf, size); 06639 if (res != size) { 06640 if (res == -1) return -1; 06641 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 06642 break; 06643 } 06644 len -= size; 06645 buf += size; 06646 } 06647 p->didtdd = 1; /* set to have done it now */ 06648 } 06649 if (*cp == 2) { /* Mate mode */ 06650 if (p->tdd) 06651 tdd_free(p->tdd); 06652 p->tdd = 0; 06653 p->mate = 1; 06654 break; 06655 } 06656 if (!p->tdd) { /* if we don't have one yet */ 06657 p->tdd = tdd_new(); /* allocate one */ 06658 } 06659 break; 06660 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 06661 if (!p->dsp) 06662 break; 06663 cp = (char *) data; 06664 ast_debug(1, "Set option RELAX DTMF, value: %s(%d) on %s\n", 06665 *cp ? "ON" : "OFF", (int) *cp, chan->name); 06666 ast_dsp_set_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax); 06667 break; 06668 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 06669 #if defined(HAVE_PRI) 06670 if (dahdi_sig_pri_lib_handles(p->sig) 06671 && ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 06672 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */ 06673 break; 06674 } 06675 #endif /* defined(HAVE_PRI) */ 06676 06677 cp = (char *) data; 06678 if (!*cp) { 06679 ast_debug(1, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name); 06680 x = 0; 06681 dahdi_disable_ec(p); 06682 } else { 06683 ast_debug(1, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name); 06684 x = 1; 06685 } 06686 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x) == -1) 06687 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, x, strerror(errno)); 06688 break; 06689 case AST_OPTION_OPRMODE: /* Operator services mode */ 06690 oprmode = (struct oprmode *) data; 06691 /* We don't support operator mode across technologies */ 06692 if (strcasecmp(chan->tech->type, oprmode->peer->tech->type)) { 06693 ast_log(LOG_NOTICE, "Operator mode not supported on %s to %s calls.\n", 06694 chan->tech->type, oprmode->peer->tech->type); 06695 errno = EINVAL; 06696 return -1; 06697 } 06698 pp = oprmode->peer->tech_pvt; 06699 p->oprmode = pp->oprmode = 0; 06700 /* setup peers */ 06701 p->oprpeer = pp; 06702 pp->oprpeer = p; 06703 /* setup modes, if any */ 06704 if (oprmode->mode) 06705 { 06706 pp->oprmode = oprmode->mode; 06707 p->oprmode = -oprmode->mode; 06708 } 06709 ast_debug(1, "Set Operator Services mode, value: %d on %s/%s\n", 06710 oprmode->mode, chan->name,oprmode->peer->name); 06711 break; 06712 case AST_OPTION_ECHOCAN: 06713 cp = (char *) data; 06714 if (*cp) { 06715 ast_debug(1, "Enabling echo cancellation on %s\n", chan->name); 06716 dahdi_enable_ec(p); 06717 } else { 06718 ast_debug(1, "Disabling echo cancellation on %s\n", chan->name); 06719 dahdi_disable_ec(p); 06720 } 06721 break; 06722 case AST_OPTION_DIGIT_DETECT: 06723 cp = (char *) data; 06724 ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name); 06725 if (*cp) { 06726 enable_dtmf_detect(p); 06727 } else { 06728 disable_dtmf_detect(p); 06729 } 06730 break; 06731 case AST_OPTION_FAX_DETECT: 06732 cp = (char *) data; 06733 if (p->dsp) { 06734 ast_debug(1, "%sabling fax tone detection on %s\n", *cp ? "En" : "Dis", chan->name); 06735 if (*cp) { 06736 p->dsp_features |= DSP_FEATURE_FAX_DETECT; 06737 } else { 06738 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 06739 } 06740 ast_dsp_set_features(p->dsp, p->dsp_features); 06741 } 06742 break; 06743 default: 06744 return -1; 06745 } 06746 errno = 0; 06747 06748 return 0; 06749 }
static char* dahdi_show_channel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14856 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, dahdi_pvt::busycount, dahdi_pvt::busydetect, dahdi_pvt::busyquietlength, dahdi_pvt::busytonelength, dahdi_pvt::callwaitcas, dahdi_pvt::channel, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_subaddr, dahdi_pvt::cid_ton, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, dahdi_pvt::confno, dahdi_pvt::context, dahdi_dnd(), dahdi_pvt::destroy, dahdi_pvt::dialing, dahdi_pvt::dsp, dahdi_pvt::dtmfrelax, dahdi_pvt::echocanbridged, dahdi_pvt::echocancel, dahdi_pvt::echocanon, dahdi_pvt::exten, dahdi_pvt::faxhandled, ast_cli_args::fd, HAVE_PRI_SUBADDR, dahdi_pvt::head, iflist, dahdi_pvt::inalarm, dahdi_pvt::inconference, dahdi_subchannel::inthreeway, dahdi_pvt::law_default, dahdi_subchannel::linear, dahdi_pvt::mailbox, dahdi_pvt::master, dahdi_pvt::mfcr2, dahdi_pvt::mfcr2_accept_on_offer, dahdi_pvt::mfcr2_allow_collect_calls, dahdi_pvt::mfcr2_charge_calls, dahdi_pvt::mfcr2_forced_release, ast_channel::name, ast_variable::name, ast_variable::next, dahdi_pvt::next, dahdi_pvt::owner, dahdi_pvt::params, dahdi_pvt::propconfno, dahdi_pvt::pulsedial, dahdi_pvt::r2chan, dahdi_pvt::radio, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, S_OR, dahdi_pvt::sig, sig2str, dahdi_pvt::slaves, dahdi_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, dahdi_pvt::subs, dahdi_pvt::tdd, dahdi_pvt::txdrc, dahdi_pvt::txgain, ast_cli_entry::usage, ast_variable::value, dahdi_pvt::vars, and dahdi_pvt::waitfordialtone.
14857 { 14858 int channel; 14859 struct dahdi_pvt *tmp = NULL; 14860 struct dahdi_confinfo ci; 14861 struct dahdi_params ps; 14862 int x; 14863 14864 switch (cmd) { 14865 case CLI_INIT: 14866 e->command = "dahdi show channel"; 14867 e->usage = 14868 "Usage: dahdi show channel <chan num>\n" 14869 " Detailed information about a given channel\n"; 14870 return NULL; 14871 case CLI_GENERATE: 14872 return NULL; 14873 } 14874 14875 if (a->argc != 4) 14876 return CLI_SHOWUSAGE; 14877 14878 channel = atoi(a->argv[3]); 14879 14880 ast_mutex_lock(&iflock); 14881 for (tmp = iflist; tmp; tmp = tmp->next) { 14882 if (tmp->channel == channel) { 14883 ast_cli(a->fd, "Channel: %d\n", tmp->channel); 14884 ast_cli(a->fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].dfd); 14885 ast_cli(a->fd, "Span: %d\n", tmp->span); 14886 ast_cli(a->fd, "Extension: %s\n", tmp->exten); 14887 ast_cli(a->fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 14888 ast_cli(a->fd, "Context: %s\n", tmp->context); 14889 ast_cli(a->fd, "Caller ID: %s\n", tmp->cid_num); 14890 ast_cli(a->fd, "Calling TON: %d\n", tmp->cid_ton); 14891 #if defined(HAVE_PRI) 14892 #if defined(HAVE_PRI_SUBADDR) 14893 ast_cli(a->fd, "Caller ID subaddress: %s\n", tmp->cid_subaddr); 14894 #endif /* defined(HAVE_PRI_SUBADDR) */ 14895 #endif /* defined(HAVE_PRI) */ 14896 ast_cli(a->fd, "Caller ID name: %s\n", tmp->cid_name); 14897 ast_cli(a->fd, "Mailbox: %s\n", S_OR(tmp->mailbox, "none")); 14898 if (tmp->vars) { 14899 struct ast_variable *v; 14900 ast_cli(a->fd, "Variables:\n"); 14901 for (v = tmp->vars ; v ; v = v->next) 14902 ast_cli(a->fd, " %s = %s\n", v->name, v->value); 14903 } 14904 ast_cli(a->fd, "Destroy: %d\n", tmp->destroy); 14905 ast_cli(a->fd, "InAlarm: %d\n", tmp->inalarm); 14906 ast_cli(a->fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 14907 ast_cli(a->fd, "Radio: %d\n", tmp->radio); 14908 ast_cli(a->fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>"); 14909 ast_cli(a->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)" : ""); 14910 ast_cli(a->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)" : ""); 14911 ast_cli(a->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)" : ""); 14912 ast_cli(a->fd, "Confno: %d\n", tmp->confno); 14913 ast_cli(a->fd, "Propagated Conference: %d\n", tmp->propconfno); 14914 ast_cli(a->fd, "Real in conference: %d\n", tmp->inconference); 14915 ast_cli(a->fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 14916 ast_cli(a->fd, "Busy Detection: %s\n", tmp->busydetect ? "yes" : "no"); 14917 if (tmp->busydetect) { 14918 #if defined(BUSYDETECT_TONEONLY) 14919 ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_TONEONLY\n"); 14920 #elif defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE) 14921 ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_COMPARE_TONE_AND_SILENCE\n"); 14922 #endif 14923 #ifdef BUSYDETECT_DEBUG 14924 ast_cli(a->fd, " Busy Detector Debug: Enabled\n"); 14925 #endif 14926 ast_cli(a->fd, " Busy Count: %d\n", tmp->busycount); 14927 ast_cli(a->fd, " Busy Pattern: %d,%d\n", tmp->busytonelength, tmp->busyquietlength); 14928 } 14929 ast_cli(a->fd, "TDD: %s\n", tmp->tdd ? "yes" : "no"); 14930 ast_cli(a->fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 14931 ast_cli(a->fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 14932 ast_cli(a->fd, "Default law: %s\n", tmp->law_default == DAHDI_LAW_MULAW ? "ulaw" : tmp->law_default == DAHDI_LAW_ALAW ? "alaw" : "unknown"); 14933 ast_cli(a->fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 14934 ast_cli(a->fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 14935 ast_cli(a->fd, "Gains (RX/TX): %.2f/%.2f\n", tmp->rxgain, tmp->txgain); 14936 ast_cli(a->fd, "Dynamic Range Compression (RX/TX): %.2f/%.2f\n", tmp->rxdrc, tmp->txdrc); 14937 ast_cli(a->fd, "DND: %s\n", dahdi_dnd(tmp, -1) ? "yes" : "no"); 14938 ast_cli(a->fd, "Echo Cancellation:\n"); 14939 14940 if (tmp->echocancel.head.tap_length) { 14941 ast_cli(a->fd, "\t%d taps\n", tmp->echocancel.head.tap_length); 14942 for (x = 0; x < tmp->echocancel.head.param_count; x++) { 14943 ast_cli(a->fd, "\t\t%s: %ud\n", tmp->echocancel.params[x].name, tmp->echocancel.params[x].value); 14944 } 14945 ast_cli(a->fd, "\t%scurrently %s\n", tmp->echocanbridged ? "" : "(unless TDM bridged) ", tmp->echocanon ? "ON" : "OFF"); 14946 } else { 14947 ast_cli(a->fd, "\tnone\n"); 14948 } 14949 ast_cli(a->fd, "Wait for dialtone: %dms\n", tmp->waitfordialtone); 14950 if (tmp->master) 14951 ast_cli(a->fd, "Master Channel: %d\n", tmp->master->channel); 14952 for (x = 0; x < MAX_SLAVES; x++) { 14953 if (tmp->slaves[x]) 14954 ast_cli(a->fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 14955 } 14956 #ifdef HAVE_OPENR2 14957 if (tmp->mfcr2) { 14958 char calldir[OR2_MAX_PATH]; 14959 openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan); 14960 openr2_variant_t r2variant = openr2_context_get_variant(r2context); 14961 ast_cli(a->fd, "MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan)); 14962 ast_cli(a->fd, "MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan)); 14963 ast_cli(a->fd, "MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan)); 14964 ast_cli(a->fd, "MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan)); 14965 ast_cli(a->fd, "MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ? "Yes" : "No"); 14966 ast_cli(a->fd, "MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant)); 14967 ast_cli(a->fd, "MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context)); 14968 ast_cli(a->fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context)); 14969 ast_cli(a->fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No"); 14970 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 14971 ast_cli(a->fd, "MFC/R2 Skip Category Request: %s\n", openr2_context_get_skip_category_request(r2context) ? "Yes" : "No"); 14972 #endif 14973 ast_cli(a->fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No"); 14974 ast_cli(a->fd, "MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No"); 14975 ast_cli(a->fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No"); 14976 ast_cli(a->fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No"); 14977 ast_cli(a->fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No"); 14978 ast_cli(a->fd, "MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context)); 14979 ast_cli(a->fd, "MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context)); 14980 ast_cli(a->fd, "MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan)); 14981 ast_cli(a->fd, "MFC/R2 Tx CAS: %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan)); 14982 ast_cli(a->fd, "MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan)); 14983 ast_cli(a->fd, "MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan)); 14984 ast_cli(a->fd, "MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir, sizeof(calldir))); 14985 } 14986 #endif 14987 #if defined(HAVE_SS7) 14988 if (tmp->ss7) { 14989 struct sig_ss7_chan *chan = tmp->sig_pvt; 14990 14991 ast_cli(a->fd, "CIC: %d\n", chan->cic); 14992 } 14993 #endif /* defined(HAVE_SS7) */ 14994 #ifdef HAVE_PRI 14995 if (tmp->pri) { 14996 struct sig_pri_chan *chan = tmp->sig_pvt; 14997 14998 ast_cli(a->fd, "PRI Flags: "); 14999 if (chan->resetting) 15000 ast_cli(a->fd, "Resetting "); 15001 if (chan->call) 15002 ast_cli(a->fd, "Call "); 15003 ast_cli(a->fd, "\n"); 15004 if (tmp->logicalspan) 15005 ast_cli(a->fd, "PRI Logical Span: %d\n", tmp->logicalspan); 15006 else 15007 ast_cli(a->fd, "PRI Logical Span: Implicit\n"); 15008 } 15009 #endif 15010 memset(&ci, 0, sizeof(ci)); 15011 ps.channo = tmp->channel; 15012 if (tmp->subs[SUB_REAL].dfd > -1) { 15013 memset(&ci, 0, sizeof(ci)); 15014 if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) { 15015 ast_cli(a->fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 15016 } 15017 if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONFMUTE, &x)) { 15018 ast_cli(a->fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 15019 } 15020 memset(&ps, 0, sizeof(ps)); 15021 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) { 15022 ast_log(LOG_WARNING, "Failed to get parameters on channel %d: %s\n", tmp->channel, strerror(errno)); 15023 } else { 15024 ast_cli(a->fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 15025 } 15026 } 15027 if (ISTRUNK(tmp)) { 15028 ast_cli(a->fd, "Call Progress: %s\n", tmp->callprogress ? "yes" : "no"); 15029 if (!ast_strlen_zero(progzone)) 15030 ast_cli(a->fd, "Progress Zone: %s\n", progzone); 15031 ast_cli(a->fd, "Busy Detect: %s\n", tmp->busydetect ? "yes" : "no"); 15032 if(tmp->busydetect) { 15033 ast_cli(a->fd, "Busy Count: %d\n", tmp->busycount); 15034 if(tmp->busytonelength > 0) { 15035 ast_cli(a->fd, "Busy Pattern:\n"); 15036 ast_cli(a->fd, " -- Tone Length: %6d ms\n", tmp->busytonelength); 15037 if (tmp->busyquietlength > 0) 15038 ast_cli(a->fd, " -- Quiet Length: %6d ms\n", tmp->busyquietlength); 15039 else 15040 ast_cli(a->fd, " -- Detect Tone Only\n"); 15041 if(tmp->busyfuzziness > 0) 15042 ast_cli(a->fd, "Busy Pattern Fuziness: %d\n", tmp->busyfuzziness); 15043 } 15044 } 15045 } 15046 ast_mutex_unlock(&iflock); 15047 return CLI_SUCCESS; 15048 } 15049 } 15050 ast_mutex_unlock(&iflock); 15051 15052 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15053 return CLI_FAILURE; 15054 }
static char* dahdi_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14770 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, dahdi_pvt::context, ast_cli_args::fd, FORMAT2, dahdi_pvt::group, iflist, dahdi_pvt::next, and ast_cli_entry::usage.
14771 { 14772 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" 14773 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" 14774 unsigned int targetnum = 0; 14775 int filtertype = 0; 14776 struct dahdi_pvt *tmp = NULL; 14777 char tmps[20] = ""; 14778 char statestr[20] = ""; 14779 char blockstr[20] = ""; 14780 14781 switch (cmd) { 14782 case CLI_INIT: 14783 e->command = "dahdi show channels [group|context]"; 14784 e->usage = 14785 "Usage: dahdi show channels [ group <group> | context <context> ]\n" 14786 " Shows a list of available channels with optional filtering\n" 14787 " <group> must be a number between 0 and 63\n"; 14788 return NULL; 14789 case CLI_GENERATE: 14790 return NULL; 14791 } 14792 14793 /* syntax: dahdi show channels [ group <group> | context <context> ] */ 14794 14795 if (!((a->argc == 3) || (a->argc == 5))) 14796 return CLI_SHOWUSAGE; 14797 14798 if (a->argc == 5) { 14799 if (!strcasecmp(a->argv[3], "group")) { 14800 targetnum = atoi(a->argv[4]); 14801 if ((targetnum < 0) || (targetnum > 63)) 14802 return CLI_SHOWUSAGE; 14803 targetnum = 1 << targetnum; 14804 filtertype = 1; 14805 } else if (!strcasecmp(a->argv[3], "context")) { 14806 filtertype = 2; 14807 } 14808 } 14809 14810 ast_cli(a->fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret", "Blocked", "State"); 14811 ast_mutex_lock(&iflock); 14812 for (tmp = iflist; tmp; tmp = tmp->next) { 14813 if (filtertype) { 14814 switch(filtertype) { 14815 case 1: /* dahdi show channels group <group> */ 14816 if (!(tmp->group & targetnum)) { 14817 continue; 14818 } 14819 break; 14820 case 2: /* dahdi show channels context <context> */ 14821 if (strcasecmp(tmp->context, a->argv[4])) { 14822 continue; 14823 } 14824 break; 14825 default: 14826 ; 14827 } 14828 } 14829 if (tmp->channel > 0) { 14830 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 14831 } else 14832 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 14833 14834 if (tmp->locallyblocked) 14835 blockstr[0] = 'L'; 14836 else 14837 blockstr[0] = ' '; 14838 14839 if (tmp->remotelyblocked) 14840 blockstr[1] = 'R'; 14841 else 14842 blockstr[1] = ' '; 14843 14844 blockstr[2] = '\0'; 14845 14846 snprintf(statestr, sizeof(statestr), "%s", "In Service"); 14847 14848 ast_cli(a->fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret, blockstr, statestr); 14849 } 14850 ast_mutex_unlock(&iflock); 14851 return CLI_SUCCESS; 14852 #undef FORMAT 14853 #undef FORMAT2 14854 }
static char* dahdi_show_status | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15093 of file chan_dahdi.c.
References ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, errno, ast_cli_args::fd, FORMAT, FORMAT2, lbostr, and ast_cli_entry::usage.
15094 { 15095 #define FORMAT "%-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n" 15096 #define FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n" 15097 int span; 15098 int res; 15099 char alarmstr[50]; 15100 15101 int ctl; 15102 struct dahdi_spaninfo s; 15103 15104 switch (cmd) { 15105 case CLI_INIT: 15106 e->command = "dahdi show status"; 15107 e->usage = 15108 "Usage: dahdi show status\n" 15109 " Shows a list of DAHDI cards with status\n"; 15110 return NULL; 15111 case CLI_GENERATE: 15112 return NULL; 15113 } 15114 ctl = open("/dev/dahdi/ctl", O_RDWR); 15115 if (ctl < 0) { 15116 ast_cli(a->fd, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); 15117 return CLI_FAILURE; 15118 } 15119 ast_cli(a->fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4", "Framing", "Coding", "Options", "LBO"); 15120 15121 for (span = 1; span < DAHDI_MAX_SPANS; ++span) { 15122 s.spanno = span; 15123 res = ioctl(ctl, DAHDI_SPANSTAT, &s); 15124 if (res) { 15125 continue; 15126 } 15127 alarmstr[0] = '\0'; 15128 if (s.alarms > 0) { 15129 if (s.alarms & DAHDI_ALARM_BLUE) 15130 strcat(alarmstr, "BLU/"); 15131 if (s.alarms & DAHDI_ALARM_YELLOW) 15132 strcat(alarmstr, "YEL/"); 15133 if (s.alarms & DAHDI_ALARM_RED) 15134 strcat(alarmstr, "RED/"); 15135 if (s.alarms & DAHDI_ALARM_LOOPBACK) 15136 strcat(alarmstr, "LB/"); 15137 if (s.alarms & DAHDI_ALARM_RECOVER) 15138 strcat(alarmstr, "REC/"); 15139 if (s.alarms & DAHDI_ALARM_NOTOPEN) 15140 strcat(alarmstr, "NOP/"); 15141 if (!strlen(alarmstr)) 15142 strcat(alarmstr, "UUU/"); 15143 if (strlen(alarmstr)) { 15144 /* Strip trailing / */ 15145 alarmstr[strlen(alarmstr) - 1] = '\0'; 15146 } 15147 } else { 15148 if (s.numchans) 15149 strcpy(alarmstr, "OK"); 15150 else 15151 strcpy(alarmstr, "UNCONFIGURED"); 15152 } 15153 15154 ast_cli(a->fd, FORMAT, s.desc, alarmstr, s.irqmisses, s.bpvcount, s.crc4count, 15155 s.lineconfig & DAHDI_CONFIG_D4 ? "D4" : 15156 s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" : 15157 s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" : 15158 "CAS", 15159 s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" : 15160 s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" : 15161 s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" : 15162 "Unk", 15163 s.lineconfig & DAHDI_CONFIG_CRC4 ? 15164 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" : 15165 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : "", 15166 lbostr[s.lbo] 15167 ); 15168 } 15169 close(ctl); 15170 15171 return CLI_SUCCESS; 15172 #undef FORMAT 15173 #undef FORMAT2 15174 }
static char* dahdi_show_version | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15176 of file chan_dahdi.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, errno, ast_cli_args::fd, and ast_cli_entry::usage.
15177 { 15178 int pseudo_fd = -1; 15179 struct dahdi_versioninfo vi; 15180 15181 switch (cmd) { 15182 case CLI_INIT: 15183 e->command = "dahdi show version"; 15184 e->usage = 15185 "Usage: dahdi show version\n" 15186 " Shows the DAHDI version in use\n"; 15187 return NULL; 15188 case CLI_GENERATE: 15189 return NULL; 15190 } 15191 if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) { 15192 ast_cli(a->fd, "Failed to open control file to get version.\n"); 15193 return CLI_SUCCESS; 15194 } 15195 15196 strcpy(vi.version, "Unknown"); 15197 strcpy(vi.echo_canceller, "Unknown"); 15198 15199 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi)) 15200 ast_cli(a->fd, "Failed to get DAHDI version: %s\n", strerror(errno)); 15201 else 15202 ast_cli(a->fd, "DAHDI Version: %s Echo Canceller: %s\n", vi.version, vi.echo_canceller); 15203 15204 close(pseudo_fd); 15205 15206 return CLI_SUCCESS; 15207 }
static char* dahdi_sig2str | ( | int | sig | ) | [static] |
Definition at line 4461 of file chan_dahdi.c.
References SIG_BRI, SIG_BRI_PTMP, 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_MFCR2, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, and SIG_SS7.
04462 { 04463 static char buf[256]; 04464 switch (sig) { 04465 case SIG_EM: 04466 return "E & M Immediate"; 04467 case SIG_EMWINK: 04468 return "E & M Wink"; 04469 case SIG_EM_E1: 04470 return "E & M E1"; 04471 case SIG_FEATD: 04472 return "Feature Group D (DTMF)"; 04473 case SIG_FEATDMF: 04474 return "Feature Group D (MF)"; 04475 case SIG_FEATDMF_TA: 04476 return "Feature Groud D (MF) Tandem Access"; 04477 case SIG_FEATB: 04478 return "Feature Group B (MF)"; 04479 case SIG_E911: 04480 return "E911 (MF)"; 04481 case SIG_FGC_CAMA: 04482 return "FGC/CAMA (Dialpulse)"; 04483 case SIG_FGC_CAMAMF: 04484 return "FGC/CAMA (MF)"; 04485 case SIG_FXSLS: 04486 return "FXS Loopstart"; 04487 case SIG_FXSGS: 04488 return "FXS Groundstart"; 04489 case SIG_FXSKS: 04490 return "FXS Kewlstart"; 04491 case SIG_FXOLS: 04492 return "FXO Loopstart"; 04493 case SIG_FXOGS: 04494 return "FXO Groundstart"; 04495 case SIG_FXOKS: 04496 return "FXO Kewlstart"; 04497 case SIG_PRI: 04498 return "ISDN PRI"; 04499 case SIG_BRI: 04500 return "ISDN BRI Point to Point"; 04501 case SIG_BRI_PTMP: 04502 return "ISDN BRI Point to MultiPoint"; 04503 case SIG_SS7: 04504 return "SS7"; 04505 case SIG_MFCR2: 04506 return "MFC/R2"; 04507 case SIG_SF: 04508 return "SF (Tone) Immediate"; 04509 case SIG_SFWINK: 04510 return "SF (Tone) Wink"; 04511 case SIG_SF_FEATD: 04512 return "SF (Tone) with Feature Group D (DTMF)"; 04513 case SIG_SF_FEATDMF: 04514 return "SF (Tone) with Feature Group D (MF)"; 04515 case SIG_SF_FEATB: 04516 return "SF (Tone) with Feature Group B (MF)"; 04517 case 0: 04518 return "Pseudo"; 04519 default: 04520 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig); 04521 return buf; 04522 } 04523 }
static int dahdi_sig_pri_lib_handles | ( | int | signaling | ) | [inline, static] |
Definition at line 1533 of file chan_dahdi.c.
References SIG_PRI_LIB_HANDLE_CASES.
Referenced by dahdi_bridge(), dahdi_call(), dahdi_cc_callback(), dahdi_digit_end(), dahdi_handle_event(), dahdi_hangup(), dahdi_new(), dahdi_queryoption(), dahdi_read(), dahdi_request(), and dahdi_setoption().
01534 { 01535 int handles; 01536 01537 switch (signaling) { 01538 case SIG_PRI_LIB_HANDLE_CASES: 01539 handles = 1; 01540 break; 01541 default: 01542 handles = 0; 01543 break; 01544 } 01545 01546 return handles; 01547 }
static void dahdi_softhangup_all | ( | void | ) | [static] |
Definition at line 14597 of file chan_dahdi.c.
References ast_channel_trylock, ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, AST_SOFTHANGUP_EXPLICIT, ast_softhangup_nolock(), ast_verbose, iflist, dahdi_pvt::lock, ast_channel::name, dahdi_pvt::next, num_restart_pending, option_debug, dahdi_pvt::owner, and dahdi_pvt::restartpending.
Referenced by dahdi_restart().
14598 { 14599 struct dahdi_pvt *p; 14600 retry: 14601 ast_mutex_lock(&iflock); 14602 for (p = iflist; p; p = p->next) { 14603 ast_mutex_lock(&p->lock); 14604 if (p->owner && !p->restartpending) { 14605 if (ast_channel_trylock(p->owner)) { 14606 if (option_debug > 2) 14607 ast_verbose("Avoiding deadlock\n"); 14608 /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */ 14609 ast_mutex_unlock(&p->lock); 14610 ast_mutex_unlock(&iflock); 14611 goto retry; 14612 } 14613 if (option_debug > 2) 14614 ast_verbose("Softhanging up on %s\n", p->owner->name); 14615 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_EXPLICIT); 14616 p->restartpending = 1; 14617 num_restart_pending++; 14618 ast_channel_unlock(p->owner); 14619 } 14620 ast_mutex_unlock(&p->lock); 14621 } 14622 ast_mutex_unlock(&iflock); 14623 }
static void dahdi_ss7_error | ( | struct ss7 * | ss7, | |
char * | s | |||
) | [static] |
Definition at line 13583 of file chan_dahdi.c.
References ast_log(), linksets, and dahdi_ss7::ss7.
Referenced by load_module().
13584 { 13585 int i; 13586 13587 if (ss7) { 13588 for (i = 0; i < NUM_SPANS; i++) { 13589 if (linksets[i].ss7.ss7 == ss7) { 13590 ast_log(LOG_ERROR, "[%d] %s", i + 1, s); 13591 return; 13592 } 13593 } 13594 } 13595 ast_log(LOG_ERROR, "%s", s); 13596 }
static void dahdi_ss7_message | ( | struct ss7 * | ss7, | |
char * | s | |||
) | [static] |
Definition at line 13566 of file chan_dahdi.c.
References ast_verbose, linksets, and dahdi_ss7::ss7.
Referenced by load_module().
13567 { 13568 int i; 13569 13570 if (ss7) { 13571 for (i = 0; i < NUM_SPANS; i++) { 13572 if (linksets[i].ss7.ss7 == ss7) { 13573 ast_verbose("[%d] %s", i + 1, s); 13574 return; 13575 } 13576 } 13577 } 13578 ast_verbose("%s", s); 13579 }
static int dahdi_status_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 17820 of file chan_dahdi.c.
References ast_data_add_bool(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_remove_node(), ast_data_search_match(), ast_log(), errno, and lbostr.
17822 { 17823 int ctl, res, span; 17824 struct ast_data *data_span, *data_alarms; 17825 struct dahdi_spaninfo s; 17826 17827 ctl = open("/dev/dahdi/ctl", O_RDWR); 17828 if (ctl < 0) { 17829 ast_log(LOG_ERROR, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); 17830 return -1; 17831 } 17832 for (span = 1; span < DAHDI_MAX_SPANS; ++span) { 17833 s.spanno = span; 17834 res = ioctl(ctl, DAHDI_SPANSTAT, &s); 17835 if (res) { 17836 continue; 17837 } 17838 17839 data_span = ast_data_add_node(data_root, "span"); 17840 if (!data_span) { 17841 continue; 17842 } 17843 ast_data_add_str(data_span, "description", s.desc); 17844 17845 /* insert the alarms status */ 17846 data_alarms = ast_data_add_node(data_span, "alarms"); 17847 if (!data_alarms) { 17848 continue; 17849 } 17850 17851 ast_data_add_bool(data_alarms, "BLUE", s.alarms & DAHDI_ALARM_BLUE); 17852 ast_data_add_bool(data_alarms, "YELLOW", s.alarms & DAHDI_ALARM_YELLOW); 17853 ast_data_add_bool(data_alarms, "RED", s.alarms & DAHDI_ALARM_RED); 17854 ast_data_add_bool(data_alarms, "LOOPBACK", s.alarms & DAHDI_ALARM_LOOPBACK); 17855 ast_data_add_bool(data_alarms, "RECOVER", s.alarms & DAHDI_ALARM_RECOVER); 17856 ast_data_add_bool(data_alarms, "NOTOPEN", s.alarms & DAHDI_ALARM_NOTOPEN); 17857 17858 ast_data_add_int(data_span, "irqmisses", s.irqmisses); 17859 ast_data_add_int(data_span, "bpviol", s.bpvcount); 17860 ast_data_add_int(data_span, "crc4", s.crc4count); 17861 ast_data_add_str(data_span, "framing", s.lineconfig & DAHDI_CONFIG_D4 ? "D4" : 17862 s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" : 17863 s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" : 17864 "CAS"); 17865 ast_data_add_str(data_span, "coding", s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" : 17866 s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" : 17867 s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" : 17868 "Unknown"); 17869 ast_data_add_str(data_span, "options", s.lineconfig & DAHDI_CONFIG_CRC4 ? 17870 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" : 17871 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : ""); 17872 ast_data_add_str(data_span, "lbo", lbostr[s.lbo]); 17873 17874 /* if this span doesn't match remove it. */ 17875 if (!ast_data_search_match(search, data_span)) { 17876 ast_data_remove_node(data_root, data_span); 17877 } 17878 } 17879 close(ctl); 17880 17881 return 0; 17882 }
static void dahdi_train_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4803 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_pvt::channel, dahdi_pvt::echocanon, dahdi_pvt::echotraining, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_handle_event(), and my_train_echocanceller().
04804 { 04805 int x; 04806 int res; 04807 04808 if (p && p->echocanon && p->echotraining) { 04809 x = p->echotraining; 04810 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x); 04811 if (res) 04812 ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno)); 04813 else 04814 ast_debug(1, "Engaged echo training on channel %d\n", p->channel); 04815 } else { 04816 ast_debug(1, "No echo training requested\n"); 04817 } 04818 }
static void dahdi_unlink | ( | struct dahdi_pvt * | slave, | |
struct dahdi_pvt * | master, | |||
int | needlock | |||
) | [static] |
Definition at line 6918 of file chan_dahdi.c.
References ast_debug, ast_mutex_lock, ast_mutex_trylock, dahdi_pvt::channel, conf_del(), DEADLOCK_AVOIDANCE, dahdi_pvt::lock, dahdi_pvt::master, dahdi_pvt::slaves, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_bridge(), and dahdi_fixup().
06919 { 06920 /* Unlink a specific slave or all slaves/masters from a given master */ 06921 int x; 06922 int hasslaves; 06923 if (!master) 06924 return; 06925 if (needlock) { 06926 ast_mutex_lock(&master->lock); 06927 if (slave) { 06928 while (ast_mutex_trylock(&slave->lock)) { 06929 DEADLOCK_AVOIDANCE(&master->lock); 06930 } 06931 } 06932 } 06933 hasslaves = 0; 06934 for (x = 0; x < MAX_SLAVES; x++) { 06935 if (master->slaves[x]) { 06936 if (!slave || (master->slaves[x] == slave)) { 06937 /* Take slave out of the conference */ 06938 ast_debug(1, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 06939 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 06940 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 06941 master->slaves[x]->master = NULL; 06942 master->slaves[x] = NULL; 06943 } else 06944 hasslaves = 1; 06945 } 06946 if (!hasslaves) 06947 master->inconference = 0; 06948 } 06949 if (!slave) { 06950 if (master->master) { 06951 /* Take master out of the conference */ 06952 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 06953 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 06954 hasslaves = 0; 06955 for (x = 0; x < MAX_SLAVES; x++) { 06956 if (master->master->slaves[x] == master) 06957 master->master->slaves[x] = NULL; 06958 else if (master->master->slaves[x]) 06959 hasslaves = 1; 06960 } 06961 if (!hasslaves) 06962 master->master->inconference = 0; 06963 } 06964 master->master = NULL; 06965 } 06966 update_conf(master); 06967 if (needlock) { 06968 if (slave) 06969 ast_mutex_unlock(&slave->lock); 06970 ast_mutex_unlock(&master->lock); 06971 } 06972 }
static void dahdi_unlink_pri_pvt | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5533 of file chan_dahdi.c.
References ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::pri, sig_pri_span::pri, and dahdi_pvt::sig_pvt.
Referenced by destroy_dahdi_pvt().
05534 { 05535 unsigned idx; 05536 struct sig_pri_span *pri; 05537 05538 pri = pvt->pri; 05539 if (!pri) { 05540 /* Not PRI signaling so cannot be in a PRI private pointer array. */ 05541 return; 05542 } 05543 ast_mutex_lock(&pri->lock); 05544 for (idx = 0; idx < pri->numchans; ++idx) { 05545 if (pri->pvts[idx] == pvt->sig_pvt) { 05546 pri->pvts[idx] = NULL; 05547 ast_mutex_unlock(&pri->lock); 05548 return; 05549 } 05550 } 05551 ast_mutex_unlock(&pri->lock); 05552 }
static void dahdi_unlink_ss7_pvt | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5565 of file chan_dahdi.c.
References ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::sig_pvt, dahdi_pvt::ss7, and sig_ss7_linkset::ss7.
Referenced by destroy_dahdi_pvt().
05566 { 05567 unsigned idx; 05568 struct sig_ss7_linkset *ss7; 05569 05570 ss7 = pvt->ss7; 05571 if (!ss7) { 05572 /* Not SS7 signaling so cannot be in a SS7 private pointer array. */ 05573 return; 05574 } 05575 ast_mutex_lock(&ss7->lock); 05576 for (idx = 0; idx < ss7->numchans; ++idx) { 05577 if (ss7->pvts[idx] == pvt->sig_pvt) { 05578 ss7->pvts[idx] = NULL; 05579 ast_mutex_unlock(&ss7->lock); 05580 return; 05581 } 05582 } 05583 ast_mutex_unlock(&ss7->lock); 05584 }
static int dahdi_version_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 17923 of file chan_dahdi.c.
References ast_data_add_str(), ast_log(), and errno.
17925 { 17926 int pseudo_fd = -1; 17927 struct dahdi_versioninfo vi = { 17928 .version = "Unknown", 17929 .echo_canceller = "Unknown" 17930 }; 17931 17932 if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) { 17933 ast_log(LOG_ERROR, "Failed to open control file to get version.\n"); 17934 return -1; 17935 } 17936 17937 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi)) { 17938 ast_log(LOG_ERROR, "Failed to get DAHDI version: %s\n", strerror(errno)); 17939 } 17940 17941 close(pseudo_fd); 17942 17943 ast_data_add_str(data_root, "value", vi.version); 17944 ast_data_add_str(data_root, "echocanceller", vi.echo_canceller); 17945 17946 return 0; 17947 }
static int dahdi_wait_event | ( | int | fd | ) | [inline, static] |
Avoid the silly dahdi_waitevent which ignores a bunch of events.
Definition at line 478 of file chan_dahdi.c.
00479 { 00480 int i, j = 0; 00481 i = DAHDI_IOMUX_SIGEVENT; 00482 if (ioctl(fd, DAHDI_IOMUX, &i) == -1) 00483 return -1; 00484 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1) 00485 return -1; 00486 return j; 00487 }
static int dahdi_wink | ( | struct dahdi_pvt * | p, | |
int | index | |||
) | [static] |
Definition at line 9515 of file chan_dahdi.c.
References dahdi_set_hook(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
Referenced by analog_ss_thread(), and my_wink().
09516 { 09517 int j; 09518 dahdi_set_hook(p->subs[idx].dfd, DAHDI_WINK); 09519 for (;;) 09520 { 09521 /* set bits of interest */ 09522 j = DAHDI_IOMUX_SIGEVENT; 09523 /* wait for some happening */ 09524 if (ioctl(p->subs[idx].dfd,DAHDI_IOMUX,&j) == -1) return(-1); 09525 /* exit loop if we have it */ 09526 if (j & DAHDI_IOMUX_SIGEVENT) break; 09527 } 09528 /* get the event info */ 09529 if (ioctl(p->subs[idx].dfd,DAHDI_GETEVENT,&j) == -1) return(-1); 09530 return 0; 09531 }
static int dahdi_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 9061 of file chan_dahdi.c.
References ast_debug, AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_getformatname(), ast_log(), dahdi_pvt::channel, dahdi_pvt::cidspill, ast_frame_subclass::codec, dahdi_get_index, dahdi_setlinear(), ast_frame::data, ast_frame::datalen, dahdi_subchannel::dfd, dahdi_pvt::dialing, errno, ast_frame::frametype, dahdi_subchannel::linear, my_dahdi_write(), ast_channel::name, dahdi_pvt::owner, ast_frame::ptr, ast_frame::subclass, dahdi_pvt::subs, and ast_channel::tech_pvt.
09062 { 09063 struct dahdi_pvt *p = ast->tech_pvt; 09064 int res; 09065 int idx; 09066 idx = dahdi_get_index(ast, p, 0); 09067 if (idx < 0) { 09068 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name); 09069 return -1; 09070 } 09071 09072 /* Write a frame of (presumably voice) data */ 09073 if (frame->frametype != AST_FRAME_VOICE) { 09074 if (frame->frametype != AST_FRAME_IMAGE) 09075 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 09076 return 0; 09077 } 09078 if ((frame->subclass.codec != AST_FORMAT_SLINEAR) && 09079 (frame->subclass.codec != AST_FORMAT_ULAW) && 09080 (frame->subclass.codec != AST_FORMAT_ALAW)) { 09081 ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(frame->subclass.codec)); 09082 return -1; 09083 } 09084 if (p->dialing) { 09085 ast_debug(1, "Dropping frame since I'm still dialing on %s...\n",ast->name); 09086 return 0; 09087 } 09088 if (!p->owner) { 09089 ast_debug(1, "Dropping frame since there is no active owner on %s...\n",ast->name); 09090 return 0; 09091 } 09092 if (p->cidspill) { 09093 ast_debug(1, "Dropping frame since I've still got a callerid spill on %s...\n", 09094 ast->name); 09095 return 0; 09096 } 09097 /* Return if it's not valid data */ 09098 if (!frame->data.ptr || !frame->datalen) 09099 return 0; 09100 09101 if (frame->subclass.codec == AST_FORMAT_SLINEAR) { 09102 if (!p->subs[idx].linear) { 09103 p->subs[idx].linear = 1; 09104 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09105 if (res) 09106 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 09107 } 09108 res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 1); 09109 } else { 09110 /* x-law already */ 09111 if (p->subs[idx].linear) { 09112 p->subs[idx].linear = 0; 09113 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09114 if (res) 09115 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 09116 } 09117 res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 0); 09118 } 09119 if (res < 0) { 09120 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 09121 return -1; 09122 } 09123 return 0; 09124 }
static enum analog_event dahdievent_to_analogevent | ( | int | event | ) | [static] |
Definition at line 2630 of file chan_dahdi.c.
References ANALOG_EVENT_ALARM, ANALOG_EVENT_DIALCOMPLETE, ANALOG_EVENT_DTMFDOWN, ANALOG_EVENT_DTMFUP, ANALOG_EVENT_EC_DISABLED, ANALOG_EVENT_EC_NLP_DISABLED, ANALOG_EVENT_EC_NLP_ENABLED, ANALOG_EVENT_ERROR, ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_NEONMWI_ACTIVE, ANALOG_EVENT_NEONMWI_INACTIVE, ANALOG_EVENT_NOALARM, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_POLARITY, ANALOG_EVENT_PULSE_START, ANALOG_EVENT_PULSEDIGIT, ANALOG_EVENT_REMOVED, ANALOG_EVENT_RINGBEGIN, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_RX_CED_DETECTED, ANALOG_EVENT_TX_CED_DETECTED, and ANALOG_EVENT_WINKFLASH.
Referenced by my_get_callerid(), and my_get_event().
02631 { 02632 enum analog_event res; 02633 02634 switch (event) { 02635 case DAHDI_EVENT_ONHOOK: 02636 res = ANALOG_EVENT_ONHOOK; 02637 break; 02638 case DAHDI_EVENT_RINGOFFHOOK: 02639 res = ANALOG_EVENT_RINGOFFHOOK; 02640 break; 02641 case DAHDI_EVENT_WINKFLASH: 02642 res = ANALOG_EVENT_WINKFLASH; 02643 break; 02644 case DAHDI_EVENT_ALARM: 02645 res = ANALOG_EVENT_ALARM; 02646 break; 02647 case DAHDI_EVENT_NOALARM: 02648 res = ANALOG_EVENT_NOALARM; 02649 break; 02650 case DAHDI_EVENT_DIALCOMPLETE: 02651 res = ANALOG_EVENT_DIALCOMPLETE; 02652 break; 02653 case DAHDI_EVENT_RINGERON: 02654 res = ANALOG_EVENT_RINGERON; 02655 break; 02656 case DAHDI_EVENT_RINGEROFF: 02657 res = ANALOG_EVENT_RINGEROFF; 02658 break; 02659 case DAHDI_EVENT_HOOKCOMPLETE: 02660 res = ANALOG_EVENT_HOOKCOMPLETE; 02661 break; 02662 case DAHDI_EVENT_PULSE_START: 02663 res = ANALOG_EVENT_PULSE_START; 02664 break; 02665 case DAHDI_EVENT_POLARITY: 02666 res = ANALOG_EVENT_POLARITY; 02667 break; 02668 case DAHDI_EVENT_RINGBEGIN: 02669 res = ANALOG_EVENT_RINGBEGIN; 02670 break; 02671 case DAHDI_EVENT_EC_DISABLED: 02672 res = ANALOG_EVENT_EC_DISABLED; 02673 break; 02674 case DAHDI_EVENT_REMOVED: 02675 res = ANALOG_EVENT_REMOVED; 02676 break; 02677 case DAHDI_EVENT_NEONMWI_ACTIVE: 02678 res = ANALOG_EVENT_NEONMWI_ACTIVE; 02679 break; 02680 case DAHDI_EVENT_NEONMWI_INACTIVE: 02681 res = ANALOG_EVENT_NEONMWI_INACTIVE; 02682 break; 02683 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 02684 case DAHDI_EVENT_TX_CED_DETECTED: 02685 res = ANALOG_EVENT_TX_CED_DETECTED; 02686 break; 02687 case DAHDI_EVENT_RX_CED_DETECTED: 02688 res = ANALOG_EVENT_RX_CED_DETECTED; 02689 break; 02690 case DAHDI_EVENT_EC_NLP_DISABLED: 02691 res = ANALOG_EVENT_EC_NLP_DISABLED; 02692 break; 02693 case DAHDI_EVENT_EC_NLP_ENABLED: 02694 res = ANALOG_EVENT_EC_NLP_ENABLED; 02695 break; 02696 #endif 02697 case DAHDI_EVENT_PULSEDIGIT: 02698 res = ANALOG_EVENT_PULSEDIGIT; 02699 break; 02700 case DAHDI_EVENT_DTMFDOWN: 02701 res = ANALOG_EVENT_DTMFDOWN; 02702 break; 02703 case DAHDI_EVENT_DTMFUP: 02704 res = ANALOG_EVENT_DTMFUP; 02705 break; 02706 default: 02707 switch(event & 0xFFFF0000) { 02708 case DAHDI_EVENT_PULSEDIGIT: 02709 case DAHDI_EVENT_DTMFDOWN: 02710 case DAHDI_EVENT_DTMFUP: 02711 /* The event includes a digit number in the low word. 02712 * Converting it to a 'enum analog_event' would remove 02713 * that information. Thus it is returned as-is. 02714 */ 02715 return event; 02716 } 02717 02718 res = ANALOG_EVENT_ERROR; 02719 break; 02720 } 02721 02722 return res; 02723 }
static enum analog_sigtype dahdisig_to_analogsig | ( | int | sig | ) | [static] |
Definition at line 1549 of file chan_dahdi.c.
References ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, 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_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, and SIG_SFWINK.
01550 { 01551 switch (sig) { 01552 case SIG_FXOLS: 01553 return ANALOG_SIG_FXOLS; 01554 case SIG_FXOGS: 01555 return ANALOG_SIG_FXOGS; 01556 case SIG_FXOKS: 01557 return ANALOG_SIG_FXOKS; 01558 case SIG_FXSLS: 01559 return ANALOG_SIG_FXSLS; 01560 case SIG_FXSGS: 01561 return ANALOG_SIG_FXSGS; 01562 case SIG_FXSKS: 01563 return ANALOG_SIG_FXSKS; 01564 case SIG_EMWINK: 01565 return ANALOG_SIG_EMWINK; 01566 case SIG_EM: 01567 return ANALOG_SIG_EM; 01568 case SIG_EM_E1: 01569 return ANALOG_SIG_EM_E1; 01570 case SIG_FEATD: 01571 return ANALOG_SIG_FEATD; 01572 case SIG_FEATDMF: 01573 return ANALOG_SIG_FEATDMF; 01574 case SIG_E911: 01575 return SIG_E911; 01576 case SIG_FGC_CAMA: 01577 return ANALOG_SIG_FGC_CAMA; 01578 case SIG_FGC_CAMAMF: 01579 return ANALOG_SIG_FGC_CAMAMF; 01580 case SIG_FEATB: 01581 return ANALOG_SIG_FEATB; 01582 case SIG_SFWINK: 01583 return ANALOG_SIG_SFWINK; 01584 case SIG_SF: 01585 return ANALOG_SIG_SF; 01586 case SIG_SF_FEATD: 01587 return ANALOG_SIG_SF_FEATD; 01588 case SIG_SF_FEATDMF: 01589 return ANALOG_SIG_SF_FEATDMF; 01590 case SIG_FEATDMF_TA: 01591 return ANALOG_SIG_FEATDMF_TA; 01592 case SIG_SF_FEATB: 01593 return ANALOG_SIG_FEATB; 01594 default: 01595 return -1; 01596 } 01597 }
static void deep_copy_dahdi_chan_conf | ( | struct dahdi_chan_conf * | dest, | |
const struct dahdi_chan_conf * | src | |||
) | [static] |
Definition at line 17534 of file chan_dahdi.c.
References ast_cc_copy_config_params(), dahdi_pvt::cc_params, and dahdi_chan_conf::chan.
Referenced by setup_dahdi_int().
17535 { 17536 struct ast_cc_config_params *cc_params; 17537 17538 cc_params = dest->chan.cc_params; 17539 *dest = *src; 17540 dest->chan.cc_params = cc_params; 17541 ast_cc_copy_config_params(dest->chan.cc_params, src->chan.cc_params); 17542 }
static void destroy_all_channels | ( | void | ) | [static] |
Definition at line 5686 of file chan_dahdi.c.
References ast_db_del(), ast_db_get(), ast_mutex_lock, ast_mutex_unlock, ast_verb, dahdi_pvt::channel, dahdi_db, destroy_dahdi_pvt(), ifcount, iflist, iflock, sig_pri_span::lock, sig_pri_span::no_b_chan_iflist, num_restart_pending, NUM_SPANS, dahdi_pri::pri, dahdi_pvt::pri, sig_pri_span::pri, pris, dahdi_pvt::span, and SRVST_DBKEY.
Referenced by __unload_module().
05687 { 05688 int chan; 05689 #if defined(HAVE_PRI) 05690 unsigned span; 05691 struct sig_pri_span *pri; 05692 #endif /* defined(HAVE_PRI) */ 05693 struct dahdi_pvt *p; 05694 05695 while (num_restart_pending) { 05696 usleep(1); 05697 } 05698 05699 ast_mutex_lock(&iflock); 05700 /* Destroy all the interfaces and free their memory */ 05701 while (iflist) { 05702 p = iflist; 05703 05704 chan = p->channel; 05705 #if defined(HAVE_PRI_SERVICE_MESSAGES) 05706 { 05707 char db_chan_name[20]; 05708 char db_answer[5]; 05709 char state; 05710 int why = -1; 05711 05712 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, p->span, chan); 05713 if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) { 05714 sscanf(db_answer, "%1c:%30d", &state, &why); 05715 } 05716 if (!why) { 05717 /* SRVST persistence is not required */ 05718 ast_db_del(db_chan_name, SRVST_DBKEY); 05719 } 05720 } 05721 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 05722 /* Free associated memory */ 05723 destroy_dahdi_pvt(p); 05724 ast_verb(3, "Unregistered channel %d\n", chan); 05725 } 05726 ifcount = 0; 05727 ast_mutex_unlock(&iflock); 05728 05729 #if defined(HAVE_PRI) 05730 /* Destroy all of the no B channel interface lists */ 05731 for (span = 0; span < NUM_SPANS; ++span) { 05732 if (!pris[span].dchannels[0]) { 05733 break; 05734 } 05735 pri = &pris[span].pri; 05736 ast_mutex_lock(&pri->lock); 05737 while (pri->no_b_chan_iflist) { 05738 p = pri->no_b_chan_iflist; 05739 05740 /* Free associated memory */ 05741 destroy_dahdi_pvt(p); 05742 } 05743 ast_mutex_unlock(&pri->lock); 05744 } 05745 #endif /* defined(HAVE_PRI) */ 05746 }
static void destroy_channel | ( | struct dahdi_pvt * | cur, | |
int | now | |||
) | [static] |
Definition at line 5668 of file chan_dahdi.c.
References dahdi_subchannel::owner, dahdi_pvt::owner, and dahdi_pvt::subs.
Referenced by dahdi_destroy_channel_bynum(), and dahdi_hangup().
05669 { 05670 int i; 05671 05672 if (!now) { 05673 /* Do not destroy the channel now if it is owned by someone. */ 05674 if (cur->owner) { 05675 return; 05676 } 05677 for (i = 0; i < 3; i++) { 05678 if (cur->subs[i].owner) { 05679 return; 05680 } 05681 } 05682 } 05683 destroy_dahdi_pvt(cur); 05684 }
static void destroy_dahdi_pvt | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5598 of file chan_dahdi.c.
References analog_delete(), analog_lib_handles(), ast_cc_config_params_destroy(), ast_event_unsubscribe(), ast_free, ast_mutex_destroy, ast_smdi_interface_unref(), ast_variables_destroy(), dahdi_pvt::cc_params, dahdi_pvt::cidspill, dahdi_close_sub(), dahdi_iflist_extract(), DAHDI_IFLIST_MAIN, DAHDI_IFLIST_NO_B_CHAN, DAHDI_IFLIST_NONE, dahdi_nobch_extract(), dahdi_unlink_pri_pvt(), dahdi_unlink_ss7_pvt(), find_next_iface_in_span(), dahdi_pvt::lock, dahdi_pvt::manages_span_alarms, dahdi_pvt::mwi_event_sub, dahdi_pvt::next, dahdi_pvt::owner, dahdi_pvt::pri, dahdi_pvt::sig, sig_pri_chan_delete(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, sig_ss7_chan_delete(), dahdi_pvt::smdi_iface, SUB_REAL, ast_channel::tech_pvt, dahdi_pvt::use_smdi, dahdi_pvt::vars, and dahdi_pvt::which_iflist.
Referenced by destroy_all_channels(), and duplicate_pseudo().
05599 { 05600 struct dahdi_pvt *p = pvt; 05601 05602 if (p->manages_span_alarms) { 05603 struct dahdi_pvt *next = find_next_iface_in_span(p); 05604 if (next) { 05605 next->manages_span_alarms = 1; 05606 } 05607 } 05608 05609 /* Remove channel from the list */ 05610 #if defined(HAVE_PRI) 05611 dahdi_unlink_pri_pvt(p); 05612 #endif /* defined(HAVE_PRI) */ 05613 #if defined(HAVE_SS7) 05614 dahdi_unlink_ss7_pvt(p); 05615 #endif /* defined(HAVE_SS7) */ 05616 switch (pvt->which_iflist) { 05617 case DAHDI_IFLIST_NONE: 05618 break; 05619 case DAHDI_IFLIST_MAIN: 05620 dahdi_iflist_extract(p); 05621 break; 05622 #if defined(HAVE_PRI) 05623 case DAHDI_IFLIST_NO_B_CHAN: 05624 if (p->pri) { 05625 dahdi_nobch_extract(p->pri, p); 05626 } 05627 break; 05628 #endif /* defined(HAVE_PRI) */ 05629 } 05630 05631 if (p->sig_pvt) { 05632 if (analog_lib_handles(p->sig, 0, 0)) { 05633 analog_delete(p->sig_pvt); 05634 } 05635 switch (p->sig) { 05636 #if defined(HAVE_PRI) 05637 case SIG_PRI_LIB_HANDLE_CASES: 05638 sig_pri_chan_delete(p->sig_pvt); 05639 break; 05640 #endif /* defined(HAVE_PRI) */ 05641 #if defined(HAVE_SS7) 05642 case SIG_SS7: 05643 sig_ss7_chan_delete(p->sig_pvt); 05644 break; 05645 #endif /* defined(HAVE_SS7) */ 05646 default: 05647 break; 05648 } 05649 } 05650 ast_free(p->cidspill); 05651 if (p->use_smdi) 05652 ast_smdi_interface_unref(p->smdi_iface); 05653 if (p->mwi_event_sub) 05654 ast_event_unsubscribe(p->mwi_event_sub); 05655 if (p->vars) { 05656 ast_variables_destroy(p->vars); 05657 } 05658 if (p->cc_params) { 05659 ast_cc_config_params_destroy(p->cc_params); 05660 } 05661 ast_mutex_destroy(&p->lock); 05662 dahdi_close_sub(p, SUB_REAL); 05663 if (p->owner) 05664 p->owner->tech_pvt = NULL; 05665 ast_free(p); 05666 }
static struct dahdi_pvt* determine_starting_point | ( | const char * | data, | |
struct dahdi_starting_point * | param | |||
) | [static] |
Definition at line 13100 of file chan_dahdi.c.
References args, ARRAY_LEN, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), CHAN_PSEUDO, errno, ifend, iflist, dahdi_pvt::next, dahdi_pvt::prev, and round_robin.
Referenced by dahdi_cc_callback(), and dahdi_request().
13101 { 13102 char *dest; 13103 char *s; 13104 int x; 13105 int res = 0; 13106 struct dahdi_pvt *p; 13107 char *subdir = NULL; 13108 AST_DECLARE_APP_ARGS(args, 13109 AST_APP_ARG(group); /* channel/group token */ 13110 //AST_APP_ARG(ext); /* extension token */ 13111 //AST_APP_ARG(opts); /* options token */ 13112 AST_APP_ARG(other); /* Any remining unused arguments */ 13113 ); 13114 13115 /* 13116 * data is ---v 13117 * Dial(DAHDI/pseudo[/extension[/options]]) 13118 * Dial(DAHDI/<channel#>[c|r<cadance#>|d][/extension[/options]]) 13119 * Dial(DAHDI/<subdir>!<channel#>[c|r<cadance#>|d][/extension[/options]]) 13120 * Dial(DAHDI/i<span>[/extension[/options]]) 13121 * Dial(DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]) 13122 * 13123 * i - ISDN span channel restriction. 13124 * Used by CC to ensure that the CC recall goes out the same span. 13125 * Also to make ISDN channel names dialable when the sequence number 13126 * is stripped off. (Used by DTMF attended transfer feature.) 13127 * 13128 * g - channel group allocation search forward 13129 * G - channel group allocation search backward 13130 * r - channel group allocation round robin search forward 13131 * R - channel group allocation round robin search backward 13132 * 13133 * c - Wait for DTMF digit to confirm answer 13134 * r<cadance#> - Set distintive ring cadance number 13135 * d - Force bearer capability for ISDN/SS7 call to digital. 13136 */ 13137 13138 if (data) { 13139 dest = ast_strdupa(data); 13140 } else { 13141 ast_log(LOG_WARNING, "Channel requested with no data\n"); 13142 return NULL; 13143 } 13144 AST_NONSTANDARD_APP_ARGS(args, dest, '/'); 13145 if (!args.argc || ast_strlen_zero(args.group)) { 13146 ast_log(LOG_WARNING, "No channel/group specified\n"); 13147 return NULL; 13148 } 13149 13150 /* Initialize the output parameters */ 13151 memset(param, 0, sizeof(*param)); 13152 param->channelmatch = -1; 13153 13154 if (strchr(args.group, '!') != NULL) { 13155 char *prev = args.group; 13156 while ((s = strchr(prev, '!')) != NULL) { 13157 *s++ = '/'; 13158 prev = s; 13159 } 13160 *(prev - 1) = '\0'; 13161 subdir = args.group; 13162 args.group = prev; 13163 } else if (args.group[0] == 'i') { 13164 /* Extract the ISDN span channel restriction specifier. */ 13165 res = sscanf(args.group + 1, "%30d", &x); 13166 if (res < 1) { 13167 ast_log(LOG_WARNING, "Unable to determine ISDN span for data %s\n", data); 13168 return NULL; 13169 } 13170 param->span = x; 13171 13172 /* Remove the ISDN span channel restriction specifier. */ 13173 s = strchr(args.group, '-'); 13174 if (!s) { 13175 /* Search all groups since we are ISDN span restricted. */ 13176 return iflist; 13177 } 13178 args.group = s + 1; 13179 res = 0; 13180 } 13181 if (toupper(args.group[0]) == 'G' || toupper(args.group[0])=='R') { 13182 /* Retrieve the group number */ 13183 s = args.group + 1; 13184 res = sscanf(s, "%30d%1c%30d", &x, ¶m->opt, ¶m->cadance); 13185 if (res < 1) { 13186 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", data); 13187 return NULL; 13188 } 13189 param->groupmatch = ((ast_group_t) 1 << x); 13190 13191 if (toupper(args.group[0]) == 'G') { 13192 if (args.group[0] == 'G') { 13193 param->backwards = 1; 13194 p = ifend; 13195 } else 13196 p = iflist; 13197 } else { 13198 if (ARRAY_LEN(round_robin) <= x) { 13199 ast_log(LOG_WARNING, "Round robin index %d out of range for data %s\n", 13200 x, data); 13201 return NULL; 13202 } 13203 if (args.group[0] == 'R') { 13204 param->backwards = 1; 13205 p = round_robin[x] ? round_robin[x]->prev : ifend; 13206 if (!p) 13207 p = ifend; 13208 } else { 13209 p = round_robin[x] ? round_robin[x]->next : iflist; 13210 if (!p) 13211 p = iflist; 13212 } 13213 param->roundrobin = 1; 13214 param->rr_starting_point = x; 13215 } 13216 } else { 13217 s = args.group; 13218 if (!strcasecmp(s, "pseudo")) { 13219 /* Special case for pseudo */ 13220 x = CHAN_PSEUDO; 13221 param->channelmatch = x; 13222 } else { 13223 res = sscanf(s, "%30d%1c%30d", &x, ¶m->opt, ¶m->cadance); 13224 if (res < 1) { 13225 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", data); 13226 return NULL; 13227 } else { 13228 param->channelmatch = x; 13229 } 13230 } 13231 if (subdir) { 13232 char path[PATH_MAX]; 13233 struct stat stbuf; 13234 13235 snprintf(path, sizeof(path), "/dev/dahdi/%s/%d", 13236 subdir, param->channelmatch); 13237 if (stat(path, &stbuf) < 0) { 13238 ast_log(LOG_WARNING, "stat(%s) failed: %s\n", 13239 path, strerror(errno)); 13240 return NULL; 13241 } 13242 if (!S_ISCHR(stbuf.st_mode)) { 13243 ast_log(LOG_ERROR, "%s: Not a character device file\n", 13244 path); 13245 return NULL; 13246 } 13247 param->channelmatch = minor(stbuf.st_rdev); 13248 } 13249 13250 p = iflist; 13251 } 13252 13253 if (param->opt == 'r' && res < 3) { 13254 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", data); 13255 param->opt = '\0'; 13256 } 13257 13258 return p; 13259 }
static int device2chan | ( | const char * | subdir, | |
int | channel, | |||
char * | path, | |||
int | pathlen | |||
) | [static] |
Definition at line 11883 of file chan_dahdi.c.
References ast_log(), errno, LOG_DEBUG, and LOG_ERROR.
Referenced by build_channels().
11884 { 11885 struct stat stbuf; 11886 int num; 11887 11888 snprintf(path, pathlen, "/dev/dahdi/%s/%d", subdir, channel); 11889 if (stat(path, &stbuf) < 0) { 11890 ast_log(LOG_ERROR, "stat(%s) failed: %s\n", path, strerror(errno)); 11891 return -errno; 11892 } 11893 if (!S_ISCHR(stbuf.st_mode)) { 11894 ast_log(LOG_ERROR, "%s: Not a character device file\n", path); 11895 return -EINVAL; 11896 } 11897 num = minor(stbuf.st_rdev); 11898 ast_log(LOG_DEBUG, "%s -> %d\n", path, num); 11899 return num; 11900 11901 }
static int digit_to_dtmfindex | ( | char | digit | ) | [static] |
Definition at line 4300 of file chan_dahdi.c.
Referenced by dahdi_digit_begin().
04301 { 04302 if (isdigit(digit)) 04303 return DAHDI_TONE_DTMF_BASE + (digit - '0'); 04304 else if (digit >= 'A' && digit <= 'D') 04305 return DAHDI_TONE_DTMF_A + (digit - 'A'); 04306 else if (digit >= 'a' && digit <= 'd') 04307 return DAHDI_TONE_DTMF_A + (digit - 'a'); 04308 else if (digit == '*') 04309 return DAHDI_TONE_DTMF_s; 04310 else if (digit == '#') 04311 return DAHDI_TONE_DTMF_p; 04312 else 04313 return -1; 04314 }
static void disable_dtmf_detect | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 6460 of file chan_dahdi.c.
References ast_dsp_set_features(), dahdi_pvt::dsp, DSP_FEATURE_DIGIT_DETECT, dahdi_pvt::dsp_features, dahdi_pvt::hardwaredtmf, dahdi_pvt::ignoredtmf, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_bridge(), and dahdi_setoption().
06461 { 06462 int val = 0; 06463 06464 p->ignoredtmf = 1; 06465 06466 ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val); 06467 06468 if (!p->hardwaredtmf && p->dsp) { 06469 p->dsp_features &= ~DSP_FEATURE_DIGIT_DETECT; 06470 ast_dsp_set_features(p->dsp, p->dsp_features); 06471 } 06472 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 11308 of file chan_dahdi.c.
References analog_lib_handles(), ast_calloc, ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::cid_start, CID_START_DTMF_NOALERT, dahdi_pvt::cidspill, ifcount, iflist, iflock, last, dahdi_pvt::lock, LOG_ERROR, dahdi_pvt::mwimonitor_fsk, dahdi_pvt::mwisendactive, dahdi_pvt::next, dahdi_pvt::oprmode, dahdi_pvt::radio, dahdi_pvt::sig, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_MFCR2, dahdi_pvt::sig_pvt, SUB_REAL, and dahdi_pvt::subs.
Referenced by restart_monitor().
11309 { 11310 int count, res, res2, spoint, pollres=0; 11311 struct dahdi_pvt *i; 11312 struct dahdi_pvt *last = NULL; 11313 struct dahdi_pvt *doomed; 11314 time_t thispass = 0, lastpass = 0; 11315 int found; 11316 char buf[1024]; 11317 struct pollfd *pfds=NULL; 11318 int lastalloc = -1; 11319 /* This thread monitors all the frame relay interfaces which are not yet in use 11320 (and thus do not have a separate thread) indefinitely */ 11321 /* From here on out, we die whenever asked */ 11322 #if 0 11323 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 11324 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 11325 return NULL; 11326 } 11327 ast_debug(1, "Monitor starting...\n"); 11328 #endif 11329 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 11330 11331 for (;;) { 11332 /* Lock the interface list */ 11333 ast_mutex_lock(&iflock); 11334 if (!pfds || (lastalloc != ifcount)) { 11335 if (pfds) { 11336 ast_free(pfds); 11337 pfds = NULL; 11338 } 11339 if (ifcount) { 11340 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) { 11341 ast_mutex_unlock(&iflock); 11342 return NULL; 11343 } 11344 } 11345 lastalloc = ifcount; 11346 } 11347 /* Build the stuff we're going to poll on, that is the socket of every 11348 dahdi_pvt that does not have an associated owner channel */ 11349 count = 0; 11350 for (i = iflist; i; i = i->next) { 11351 ast_mutex_lock(&i->lock); 11352 if ((i->subs[SUB_REAL].dfd > -1) && i->sig && (!i->radio) && !(i->sig & SIG_MFCR2)) { 11353 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) { 11354 struct analog_pvt *p = i->sig_pvt; 11355 11356 if (!p) 11357 ast_log(LOG_ERROR, "No sig_pvt?\n"); 11358 11359 if (!p->owner && !p->subs[SUB_REAL].owner) { 11360 /* This needs to be watched, as it lacks an owner */ 11361 pfds[count].fd = i->subs[SUB_REAL].dfd; 11362 pfds[count].events = POLLPRI; 11363 pfds[count].revents = 0; 11364 /* Message waiting or r2 channels also get watched for reading */ 11365 if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk || 11366 (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) { 11367 pfds[count].events |= POLLIN; 11368 } 11369 count++; 11370 } 11371 } else { 11372 if (!i->owner && !i->subs[SUB_REAL].owner && !i->mwimonitoractive ) { 11373 /* This needs to be watched, as it lacks an owner */ 11374 pfds[count].fd = i->subs[SUB_REAL].dfd; 11375 pfds[count].events = POLLPRI; 11376 pfds[count].revents = 0; 11377 /* If we are monitoring for VMWI or sending CID, we need to 11378 read from the channel as well */ 11379 if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk || 11380 (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) { 11381 pfds[count].events |= POLLIN; 11382 } 11383 count++; 11384 } 11385 } 11386 } 11387 ast_mutex_unlock(&i->lock); 11388 } 11389 /* Okay, now that we know what to do, release the interface lock */ 11390 ast_mutex_unlock(&iflock); 11391 11392 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 11393 pthread_testcancel(); 11394 /* Wait at least a second for something to happen */ 11395 res = poll(pfds, count, 1000); 11396 pthread_testcancel(); 11397 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 11398 11399 /* Okay, poll has finished. Let's see what happened. */ 11400 if (res < 0) { 11401 if ((errno != EAGAIN) && (errno != EINTR)) 11402 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 11403 continue; 11404 } 11405 /* Alright, lock the interface list again, and let's look and see what has 11406 happened */ 11407 ast_mutex_lock(&iflock); 11408 found = 0; 11409 spoint = 0; 11410 lastpass = thispass; 11411 thispass = time(NULL); 11412 doomed = NULL; 11413 for (i = iflist;; i = i->next) { 11414 if (doomed) { 11415 int res; 11416 res = dahdi_destroy_channel_bynum(doomed->channel); 11417 if (res != RESULT_SUCCESS) { 11418 ast_log(LOG_WARNING, "Couldn't find channel to destroy, hopefully another destroy operation just happened.\n"); 11419 } 11420 doomed = NULL; 11421 } 11422 if (!i) { 11423 break; 11424 } 11425 11426 if (thispass != lastpass) { 11427 if (!found && ((i == last) || ((i == iflist) && !last))) { 11428 last = i; 11429 if (last) { 11430 struct analog_pvt *analog_p = last->sig_pvt; 11431 /* Only allow MWI to be initiated on a quiescent fxs port */ 11432 if (analog_p 11433 && !last->mwisendactive 11434 && (last->sig & __DAHDI_SIG_FXO) 11435 && !analog_p->fxsoffhookstate 11436 && !last->owner 11437 && !ast_strlen_zero(last->mailbox) 11438 && (thispass - analog_p->onhooktime > 3)) { 11439 res = has_voicemail(last); 11440 if (analog_p->msgstate != res) { 11441 /* Set driver resources for signalling VMWI */ 11442 res2 = ioctl(last->subs[SUB_REAL].dfd, DAHDI_VMWI, &res); 11443 if (res2) { 11444 /* TODO: This message will ALWAYS be generated on some cards; any way to restrict it to those cards where it is interesting? */ 11445 ast_debug(3, "Unable to control message waiting led on channel %d: %s\n", last->channel, strerror(errno)); 11446 } 11447 /* If enabled for FSK spill then initiate it */ 11448 if (mwi_send_init(last)) { 11449 ast_log(LOG_WARNING, "Unable to initiate mwi send sequence on channel %d\n", last->channel); 11450 } 11451 analog_p->msgstate = res; 11452 found ++; 11453 } 11454 } 11455 last = last->next; 11456 } 11457 } 11458 } 11459 if ((i->subs[SUB_REAL].dfd > -1) && i->sig) { 11460 if (i->radio && !i->owner) 11461 { 11462 res = dahdi_get_event(i->subs[SUB_REAL].dfd); 11463 if (res) 11464 { 11465 ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 11466 /* Don't hold iflock while handling init events */ 11467 ast_mutex_unlock(&iflock); 11468 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) 11469 doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res)); 11470 else 11471 doomed = handle_init_event(i, res); 11472 ast_mutex_lock(&iflock); 11473 } 11474 continue; 11475 } 11476 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].dfd, count, &spoint); 11477 if (pollres & POLLIN) { 11478 if (i->owner || i->subs[SUB_REAL].owner) { 11479 #ifdef HAVE_PRI 11480 if (!i->pri) 11481 #endif 11482 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd); 11483 continue; 11484 } 11485 if (!i->mwimonitor_fsk && !i->mwisendactive && i->cid_start != CID_START_DTMF_NOALERT) { 11486 ast_log(LOG_WARNING, "Whoa.... I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd); 11487 continue; 11488 } 11489 res = read(i->subs[SUB_REAL].dfd, buf, sizeof(buf)); 11490 if (res > 0) { 11491 if (i->mwimonitor_fsk) { 11492 if (calc_energy((unsigned char *) buf, res, AST_LAW(i)) > mwilevel) { 11493 pthread_attr_t attr; 11494 pthread_t threadid; 11495 struct mwi_thread_data *mtd; 11496 11497 pthread_attr_init(&attr); 11498 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 11499 11500 ast_log(LOG_DEBUG, "Maybe some MWI on port %d!\n", i->channel); 11501 if ((mtd = ast_calloc(1, sizeof(*mtd)))) { 11502 mtd->pvt = i; 11503 memcpy(mtd->buf, buf, res); 11504 mtd->len = res; 11505 if (ast_pthread_create_background(&threadid, &attr, mwi_thread, mtd)) { 11506 ast_log(LOG_WARNING, "Unable to start mwi thread on channel %d\n", i->channel); 11507 ast_free(mtd); 11508 } 11509 i->mwimonitoractive = 1; 11510 } 11511 } 11512 /* If configured to check for a DTMF CID spill that comes without alert (e.g no polarity reversal) */ 11513 } else if (i->cid_start == CID_START_DTMF_NOALERT) { 11514 int energy; 11515 struct timeval now; 11516 /* State machine dtmfcid_holdoff_state allows for the line to settle 11517 * before checking agin for dtmf energy. Presently waits for 500 mS before checking again 11518 */ 11519 if (1 == i->dtmfcid_holdoff_state) { 11520 gettimeofday(&i->dtmfcid_delay, NULL); 11521 i->dtmfcid_holdoff_state = 2; 11522 } else if (2 == i->dtmfcid_holdoff_state) { 11523 gettimeofday(&now, NULL); 11524 if ((int)(now.tv_sec - i->dtmfcid_delay.tv_sec) * 1000000 + (int)now.tv_usec - (int)i->dtmfcid_delay.tv_usec > 500000) { 11525 i->dtmfcid_holdoff_state = 0; 11526 } 11527 } else { 11528 energy = calc_energy((unsigned char *) buf, res, AST_LAW(i)); 11529 if (!i->mwisendactive && energy > dtmfcid_level) { 11530 pthread_t threadid; 11531 struct ast_channel *chan; 11532 ast_mutex_unlock(&iflock); 11533 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) { 11534 /* just in case this event changes or somehow destroys a channel, set doomed here too */ 11535 doomed = analog_handle_init_event(i->sig_pvt, ANALOG_EVENT_DTMFCID); 11536 i->dtmfcid_holdoff_state = 1; 11537 } else { 11538 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11539 if (!chan) { 11540 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11541 } else { 11542 res = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan); 11543 if (res) { 11544 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11545 } else { 11546 i->dtmfcid_holdoff_state = 1; 11547 } 11548 } 11549 } 11550 ast_mutex_lock(&iflock); 11551 } 11552 } 11553 } 11554 if (i->mwisendactive) { 11555 mwi_send_process_buffer(i, res); 11556 } 11557 } else { 11558 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 11559 } 11560 } 11561 if (pollres & POLLPRI) { 11562 if (i->owner || i->subs[SUB_REAL].owner) { 11563 #ifdef HAVE_PRI 11564 if (!i->pri) 11565 #endif 11566 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].dfd); 11567 continue; 11568 } 11569 res = dahdi_get_event(i->subs[SUB_REAL].dfd); 11570 ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 11571 /* Don't hold iflock while handling init events */ 11572 ast_mutex_unlock(&iflock); 11573 if (0 == i->mwisendactive || 0 == mwi_send_process_event(i, res)) { 11574 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) 11575 doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res)); 11576 else 11577 doomed = handle_init_event(i, res); 11578 } 11579 ast_mutex_lock(&iflock); 11580 } 11581 } 11582 } 11583 ast_mutex_unlock(&iflock); 11584 } 11585 /* Never reached */ 11586 return NULL; 11587 11588 }
static int drc_sample | ( | int | sample, | |
float | drc | |||
) | [static] |
Definition at line 4839 of file chan_dahdi.c.
Referenced by fill_rxgain(), and fill_txgain().
04840 { 04841 float neg; 04842 float shallow, steep; 04843 float max = SHRT_MAX; 04844 04845 neg = (sample < 0 ? -1 : 1); 04846 steep = drc*sample; 04847 shallow = neg*(max-max/drc)+(float)sample/drc; 04848 if (abs(steep) < abs(shallow)) { 04849 sample = steep; 04850 } 04851 else { 04852 sample = shallow; 04853 } 04854 04855 return sample; 04856 }
Definition at line 13036 of file chan_dahdi.c.
References ast_cc_config_params_init, ast_cc_copy_config_params(), ast_free, ast_log(), ast_malloc, ast_mutex_init, dahdi_pvt::buf_no, dahdi_pvt::buf_policy, dahdi_pvt::cc_params, dahdi_iflist_insert(), DAHDI_IFLIST_NONE, dahdi_open(), destroy_dahdi_pvt(), errno, and SUB_REAL.
Referenced by dahdi_request().
13037 { 13038 struct dahdi_pvt *p; 13039 struct dahdi_bufferinfo bi; 13040 int res; 13041 13042 p = ast_malloc(sizeof(*p)); 13043 if (!p) { 13044 return NULL; 13045 } 13046 *p = *src; 13047 13048 /* Must deep copy the cc_params. */ 13049 p->cc_params = ast_cc_config_params_init(); 13050 if (!p->cc_params) { 13051 ast_free(p); 13052 return NULL; 13053 } 13054 ast_cc_copy_config_params(p->cc_params, src->cc_params); 13055 13056 p->which_iflist = DAHDI_IFLIST_NONE; 13057 p->next = NULL; 13058 p->prev = NULL; 13059 ast_mutex_init(&p->lock); 13060 p->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo"); 13061 if (p->subs[SUB_REAL].dfd < 0) { 13062 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 13063 destroy_dahdi_pvt(p); 13064 return NULL; 13065 } 13066 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi); 13067 if (!res) { 13068 bi.txbufpolicy = src->buf_policy; 13069 bi.rxbufpolicy = src->buf_policy; 13070 bi.numbufs = src->buf_no; 13071 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi); 13072 if (res < 0) { 13073 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel: %s\n", strerror(errno)); 13074 } 13075 } else 13076 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel: %s\n", strerror(errno)); 13077 p->destroy = 1; 13078 dahdi_iflist_insert(p); 13079 return p; 13080 }
static void enable_dtmf_detect | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 6474 of file chan_dahdi.c.
References ast_dsp_set_features(), CHAN_PSEUDO, dahdi_pvt::channel, dahdi_pvt::dsp, DSP_FEATURE_DIGIT_DETECT, dahdi_pvt::dsp_features, dahdi_pvt::hardwaredtmf, dahdi_pvt::ignoredtmf, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_bridge(), and dahdi_setoption().
06475 { 06476 int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE; 06477 06478 if (p->channel == CHAN_PSEUDO) 06479 return; 06480 06481 p->ignoredtmf = 0; 06482 06483 ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val); 06484 06485 if (!p->hardwaredtmf && p->dsp) { 06486 p->dsp_features |= DSP_FEATURE_DIGIT_DETECT; 06487 ast_dsp_set_features(p->dsp, p->dsp_features); 06488 } 06489 }
static const char * event2str | ( | int | event | ) | [static] |
Definition at line 4452 of file chan_dahdi.c.
References ARRAY_LEN.
Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_handle_event(), mwi_thread(), my_distinctive_ring(), my_handle_dchan_exception(), and my_handle_link_exception().
04453 { 04454 static char buf[256]; 04455 if ((event < (ARRAY_LEN(events))) && (event > -1)) 04456 return events[event]; 04457 sprintf(buf, "Event %d", event); /* safe */ 04458 return buf; 04459 }
static void fill_rxgain | ( | struct dahdi_gains * | g, | |
float | gain, | |||
float | drc, | |||
int | law | |||
) | [static] |
Definition at line 4903 of file chan_dahdi.c.
References ARRAY_LEN, AST_ALAW, AST_LIN2A, AST_LIN2MU, AST_MULAW, and drc_sample().
Referenced by set_actual_rxgain().
04904 { 04905 int j; 04906 int k; 04907 float linear_gain = pow(10.0, gain / 20.0); 04908 04909 switch (law) { 04910 case DAHDI_LAW_ALAW: 04911 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) { 04912 if (gain || drc) { 04913 k = AST_ALAW(j); 04914 if (drc) { 04915 k = drc_sample(k, drc); 04916 } 04917 k = (float)k*linear_gain; 04918 if (k > 32767) k = 32767; 04919 if (k < -32767) k = -32767; 04920 g->rxgain[j] = AST_LIN2A(k); 04921 } else { 04922 g->rxgain[j] = j; 04923 } 04924 } 04925 break; 04926 case DAHDI_LAW_MULAW: 04927 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) { 04928 if (gain || drc) { 04929 k = AST_MULAW(j); 04930 if (drc) { 04931 k = drc_sample(k, drc); 04932 } 04933 k = (float)k*linear_gain; 04934 if (k > 32767) k = 32767; 04935 if (k < -32767) k = -32767; 04936 g->rxgain[j] = AST_LIN2MU(k); 04937 } else { 04938 g->rxgain[j] = j; 04939 } 04940 } 04941 break; 04942 } 04943 }
static void fill_txgain | ( | struct dahdi_gains * | g, | |
float | gain, | |||
float | drc, | |||
int | law | |||
) | [static] |
Definition at line 4859 of file chan_dahdi.c.
References ARRAY_LEN, AST_ALAW, AST_LIN2A, AST_LIN2MU, AST_MULAW, and drc_sample().
Referenced by set_actual_txgain().
04860 { 04861 int j; 04862 int k; 04863 04864 float linear_gain = pow(10.0, gain / 20.0); 04865 04866 switch (law) { 04867 case DAHDI_LAW_ALAW: 04868 for (j = 0; j < ARRAY_LEN(g->txgain); j++) { 04869 if (gain || drc) { 04870 k = AST_ALAW(j); 04871 if (drc) { 04872 k = drc_sample(k, drc); 04873 } 04874 k = (float)k*linear_gain; 04875 if (k > 32767) k = 32767; 04876 if (k < -32767) k = -32767; 04877 g->txgain[j] = AST_LIN2A(k); 04878 } else { 04879 g->txgain[j] = j; 04880 } 04881 } 04882 break; 04883 case DAHDI_LAW_MULAW: 04884 for (j = 0; j < ARRAY_LEN(g->txgain); j++) { 04885 if (gain || drc) { 04886 k = AST_MULAW(j); 04887 if (drc) { 04888 k = drc_sample(k, drc); 04889 } 04890 k = (float)k*linear_gain; 04891 if (k > 32767) k = 32767; 04892 if (k < -32767) k = -32767; 04893 g->txgain[j] = AST_LIN2MU(k); 04894 04895 } else { 04896 g->txgain[j] = j; 04897 } 04898 } 04899 break; 04900 } 04901 }
static struct dahdi_pvt* find_channel | ( | int | channel | ) | [static] |
Definition at line 15438 of file chan_dahdi.c.
References ast_mutex_lock, dahdi_pvt::channel, iflist, and dahdi_pvt::next.
Referenced by action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_transfer(), and action_transferhangup().
15439 { 15440 struct dahdi_pvt *p; 15441 15442 ast_mutex_lock(&iflock); 15443 for (p = iflist; p; p = p->next) { 15444 if (p->channel == channel) { 15445 break; 15446 } 15447 } 15448 ast_mutex_unlock(&iflock); 15449 return p; 15450 }
Definition at line 5587 of file chan_dahdi.c.
References dahdi_pvt::next, dahdi_pvt::prev, and dahdi_pvt::span.
Referenced by destroy_dahdi_pvt().
05588 { 05589 if (cur->next && cur->next->span == cur->span) { 05590 return cur->next; 05591 } else if (cur->prev && cur->prev->span == cur->span) { 05592 return cur->prev; 05593 } 05594 05595 return NULL; 05596 }
static int get_alarms | ( | struct dahdi_pvt * | p | ) | [static] |
Checks channel for alarms
p | a channel to check for alarms. |
Definition at line 7498 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, errno, dahdi_pvt::span, SUB_REAL, and dahdi_pvt::subs.
Referenced by action_dahdishowchannels(), dahdi_handle_event(), dahdi_r2_on_hardware_alarm(), handle_init_event(), mwi_thread(), and my_get_and_handle_alarms().
07499 { 07500 int res; 07501 struct dahdi_spaninfo zi; 07502 struct dahdi_params params; 07503 07504 memset(&zi, 0, sizeof(zi)); 07505 zi.spanno = p->span; 07506 07507 if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SPANSTAT, &zi)) >= 0) { 07508 if (zi.alarms != DAHDI_ALARM_NONE) 07509 return zi.alarms; 07510 } else { 07511 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d: %s\n", p->channel, strerror(errno)); 07512 return 0; 07513 } 07514 07515 /* No alarms on the span. Check for channel alarms. */ 07516 memset(¶ms, 0, sizeof(params)); 07517 if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, ¶ms)) >= 0) 07518 return params.chan_alarms; 07519 07520 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 07521 07522 return DAHDI_ALARM_NONE; 07523 }
static void handle_alarms | ( | struct dahdi_pvt * | p, | |
int | alms | |||
) | [static] |
Definition at line 7623 of file chan_dahdi.c.
References alarm2str(), ast_log(), dahdi_pvt::channel, EVENT_FLAG_SYSTEM, manager_event, dahdi_pvt::manages_span_alarms, report_alarms, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, and dahdi_pvt::span.
Referenced by dahdi_handle_event(), dahdi_r2_on_hardware_alarm(), handle_init_event(), mwi_thread(), and my_get_and_handle_alarms().
07624 { 07625 const char *alarm_str = alarm2str(alms); 07626 07627 if (report_alarms & REPORT_CHANNEL_ALARMS) { 07628 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str); 07629 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 07630 "Alarm: %s\r\n" 07631 "Channel: %d\r\n", 07632 alarm_str, p->channel); 07633 } 07634 07635 if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) { 07636 ast_log(LOG_WARNING, "Detected alarm on span %d: %s\n", p->span, alarm_str); 07637 manager_event(EVENT_FLAG_SYSTEM, "SpanAlarm", 07638 "Alarm: %s\r\n" 07639 "Span: %d\r\n", 07640 alarm_str, p->span); 07641 } 07642 }
static void handle_clear_alarms | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 3675 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_event, dahdi_pvt::manages_span_alarms, report_alarms, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, and dahdi_pvt::span.
Referenced by dahdi_handle_event(), dahdi_r2_on_hardware_alarm(), handle_init_event(), and mwi_thread().
03676 { 03677 if (report_alarms & REPORT_CHANNEL_ALARMS) { 03678 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 03679 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel); 03680 } 03681 if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) { 03682 ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", p->span); 03683 manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear", "Span: %d\r\n", p->span); 03684 } 03685 }
static char* handle_dahdi_show_cadences | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15056 of file chan_dahdi.c.
References ast_cli(), cadences, cidrings, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, ast_cli_entry::command, ast_cli_args::fd, num_cadence, term_color(), and ast_cli_entry::usage.
15057 { 15058 int i, j; 15059 switch (cmd) { 15060 case CLI_INIT: 15061 e->command = "dahdi show cadences"; 15062 e->usage = 15063 "Usage: dahdi show cadences\n" 15064 " Shows all cadences currently defined\n"; 15065 return NULL; 15066 case CLI_GENERATE: 15067 return NULL; 15068 } 15069 for (i = 0; i < num_cadence; i++) { 15070 char output[1024]; 15071 char tmp[16], tmp2[64]; 15072 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 15073 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 15074 15075 for (j = 0; j < 16; j++) { 15076 if (cadences[i].ringcadence[j] == 0) 15077 break; 15078 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 15079 if (cidrings[i] * 2 - 1 == j) 15080 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 15081 else 15082 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 15083 if (j != 0) 15084 strncat(output, ",", sizeof(output) - strlen(output) - 1); 15085 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 15086 } 15087 ast_cli(a->fd,"%s\n",output); 15088 } 15089 return CLI_SUCCESS; 15090 }
Definition at line 11066 of file chan_dahdi.c.
References analog_ss_thread(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verb, dahdi_pvt::channel, dahdi_pvt::cid_start, CID_START_POLARITY, CID_START_POLARITY_IN, dahdi_pvt::cidspill, dahdi_disable_ec(), dahdi_enable_ec(), dahdi_new(), dahdi_set_hook(), errno, get_alarms(), handle_alarms(), handle_clear_alarms(), dahdi_pvt::hanguponpolarityswitch, has_voicemail(), dahdi_pvt::immediate, dahdi_pvt::inalarm, LOG_NOTICE, dahdi_pvt::mailbox, dahdi_pvt::mwimonitor_neon, notify_message(), dahdi_pvt::polarity, POLARITY_REV, dahdi_pvt::radio, restore_conference(), dahdi_pvt::ringt, dahdi_pvt::ringt_base, dahdi_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_chan_alarm_notify(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, SIG_SS7, sig_ss7_set_alarm(), SUB_REAL, and dahdi_pvt::subs.
11067 { 11068 int res; 11069 pthread_t threadid; 11070 struct ast_channel *chan; 11071 11072 /* Handle an event on a given channel for the monitor thread. */ 11073 11074 switch (event) { 11075 case DAHDI_EVENT_NONE: 11076 case DAHDI_EVENT_BITSCHANGED: 11077 break; 11078 case DAHDI_EVENT_WINKFLASH: 11079 case DAHDI_EVENT_RINGOFFHOOK: 11080 if (i->inalarm) break; 11081 if (i->radio) break; 11082 /* Got a ring/answer. What kind of channel are we? */ 11083 switch (i->sig) { 11084 case SIG_FXOLS: 11085 case SIG_FXOGS: 11086 case SIG_FXOKS: 11087 res = dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 11088 if (res && (errno == EBUSY)) 11089 break; 11090 11091 /* Cancel VMWI spill */ 11092 ast_free(i->cidspill); 11093 i->cidspill = NULL; 11094 restore_conference(i); 11095 11096 if (i->immediate) { 11097 dahdi_enable_ec(i); 11098 /* The channel is immediately up. Start right away */ 11099 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 11100 chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, NULL); 11101 if (!chan) { 11102 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 11103 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11104 if (res < 0) 11105 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11106 } 11107 } else { 11108 /* Check for callerid, digits, etc */ 11109 chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, NULL); 11110 if (chan) { 11111 if (has_voicemail(i)) 11112 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER); 11113 else 11114 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE); 11115 if (res < 0) 11116 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 11117 if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11118 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11119 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11120 if (res < 0) 11121 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11122 ast_hangup(chan); 11123 } 11124 } else 11125 ast_log(LOG_WARNING, "Unable to create channel\n"); 11126 } 11127 break; 11128 case SIG_FXSLS: 11129 case SIG_FXSGS: 11130 case SIG_FXSKS: 11131 i->ringt = i->ringt_base; 11132 /* Fall through */ 11133 case SIG_EMWINK: 11134 case SIG_FEATD: 11135 case SIG_FEATDMF: 11136 case SIG_FEATDMF_TA: 11137 case SIG_E911: 11138 case SIG_FGC_CAMA: 11139 case SIG_FGC_CAMAMF: 11140 case SIG_FEATB: 11141 case SIG_EM: 11142 case SIG_EM_E1: 11143 case SIG_SFWINK: 11144 case SIG_SF_FEATD: 11145 case SIG_SF_FEATDMF: 11146 case SIG_SF_FEATB: 11147 case SIG_SF: 11148 /* Check for callerid, digits, etc */ 11149 if (i->cid_start == CID_START_POLARITY_IN) { 11150 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11151 } else { 11152 chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, NULL); 11153 } 11154 11155 if (!chan) { 11156 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11157 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11158 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11159 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11160 if (res < 0) { 11161 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11162 } 11163 ast_hangup(chan); 11164 } 11165 break; 11166 default: 11167 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 11168 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11169 if (res < 0) 11170 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11171 return NULL; 11172 } 11173 break; 11174 case DAHDI_EVENT_NOALARM: 11175 switch (i->sig) { 11176 #if defined(HAVE_PRI) 11177 case SIG_PRI_LIB_HANDLE_CASES: 11178 sig_pri_chan_alarm_notify(i->sig_pvt, 1); 11179 break; 11180 #endif /* defined(HAVE_PRI) */ 11181 #if defined(HAVE_SS7) 11182 case SIG_SS7: 11183 sig_ss7_set_alarm(i->sig_pvt, 0); 11184 break; 11185 #endif /* defined(HAVE_SS7) */ 11186 default: 11187 i->inalarm = 0; 11188 break; 11189 } 11190 handle_clear_alarms(i); 11191 break; 11192 case DAHDI_EVENT_ALARM: 11193 switch (i->sig) { 11194 #if defined(HAVE_PRI) 11195 case SIG_PRI_LIB_HANDLE_CASES: 11196 sig_pri_chan_alarm_notify(i->sig_pvt, 0); 11197 break; 11198 #endif /* defined(HAVE_PRI) */ 11199 #if defined(HAVE_SS7) 11200 case SIG_SS7: 11201 sig_ss7_set_alarm(i->sig_pvt, 1); 11202 break; 11203 #endif /* defined(HAVE_SS7) */ 11204 default: 11205 i->inalarm = 1; 11206 break; 11207 } 11208 res = get_alarms(i); 11209 handle_alarms(i, res); 11210 /* fall thru intentionally */ 11211 case DAHDI_EVENT_ONHOOK: 11212 if (i->radio) 11213 break; 11214 /* Back on hook. Hang up. */ 11215 switch (i->sig) { 11216 case SIG_FXOLS: 11217 case SIG_FXOGS: 11218 case SIG_FEATD: 11219 case SIG_FEATDMF: 11220 case SIG_FEATDMF_TA: 11221 case SIG_E911: 11222 case SIG_FGC_CAMA: 11223 case SIG_FGC_CAMAMF: 11224 case SIG_FEATB: 11225 case SIG_EM: 11226 case SIG_EM_E1: 11227 case SIG_EMWINK: 11228 case SIG_SF_FEATD: 11229 case SIG_SF_FEATDMF: 11230 case SIG_SF_FEATB: 11231 case SIG_SF: 11232 case SIG_SFWINK: 11233 case SIG_FXSLS: 11234 case SIG_FXSGS: 11235 case SIG_FXSKS: 11236 case SIG_FXOKS: 11237 dahdi_disable_ec(i); 11238 /* Diddle the battery for the zhone */ 11239 #ifdef ZHONE_HACK 11240 dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 11241 usleep(1); 11242 #endif 11243 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11244 dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 11245 break; 11246 case SIG_SS7: 11247 case SIG_PRI_LIB_HANDLE_CASES: 11248 dahdi_disable_ec(i); 11249 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11250 break; 11251 default: 11252 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 11253 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11254 return NULL; 11255 } 11256 break; 11257 case DAHDI_EVENT_POLARITY: 11258 switch (i->sig) { 11259 case SIG_FXSLS: 11260 case SIG_FXSKS: 11261 case SIG_FXSGS: 11262 /* We have already got a PR before the channel was 11263 created, but it wasn't handled. We need polarity 11264 to be REV for remote hangup detection to work. 11265 At least in Spain */ 11266 if (i->hanguponpolarityswitch) 11267 i->polarity = POLARITY_REV; 11268 if (i->cid_start == CID_START_POLARITY || i->cid_start == CID_START_POLARITY_IN) { 11269 i->polarity = POLARITY_REV; 11270 ast_verb(2, "Starting post polarity " 11271 "CID detection on channel %d\n", 11272 i->channel); 11273 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11274 if (!chan) { 11275 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11276 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11277 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11278 } 11279 } 11280 break; 11281 default: 11282 ast_log(LOG_WARNING, "handle_init_event detected " 11283 "polarity reversal on non-FXO (SIG_FXS) " 11284 "interface %d\n", i->channel); 11285 } 11286 break; 11287 case DAHDI_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */ 11288 ast_log(LOG_NOTICE, 11289 "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n", 11290 i->channel); 11291 return i; 11292 case DAHDI_EVENT_NEONMWI_ACTIVE: 11293 if (i->mwimonitor_neon) { 11294 notify_message(i->mailbox, 1); 11295 ast_log(LOG_NOTICE, "NEON MWI set for channel %d, mailbox %s \n", i->channel, i->mailbox); 11296 } 11297 break; 11298 case DAHDI_EVENT_NEONMWI_INACTIVE: 11299 if (i->mwimonitor_neon) { 11300 notify_message(i->mailbox, 0); 11301 ast_log(LOG_NOTICE, "NEON MWI cleared for channel %d, mailbox %s\n", i->channel, i->mailbox); 11302 } 11303 break; 11304 } 11305 return NULL; 11306 }
static char* handle_mfcr2_call_files | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14427 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_mutex_lock, dahdi_pvt::channel, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, iflist, dahdi_pvt::next, dahdi_pvt::r2chan, dahdi_pvt::sig, SIG_MFCR2, and ast_cli_entry::usage.
14428 { 14429 struct dahdi_pvt *p = NULL; 14430 int channo = 0; 14431 switch (cmd) { 14432 case CLI_INIT: 14433 e->command = "mfcr2 call files [on|off]"; 14434 e->usage = 14435 "Usage: mfcr2 call files [on|off] <channel>\n" 14436 " Enable call files creation on the specified channel.\n" 14437 " If no channel is specified call files creation policy will be applied to all channels.\n"; 14438 return NULL; 14439 case CLI_GENERATE: 14440 return NULL; 14441 } 14442 if (a->argc < 4) { 14443 return CLI_SHOWUSAGE; 14444 } 14445 channo = (a->argc == 5) ? atoi(a->argv[4]) : -1; 14446 ast_mutex_lock(&iflock); 14447 for (p = iflist; p; p = p->next) { 14448 if (!(p->sig & SIG_MFCR2) || !p->r2chan) { 14449 continue; 14450 } 14451 if ((channo != -1) && (p->channel != channo )) { 14452 continue; 14453 } 14454 if (ast_true(a->argv[3])) { 14455 openr2_chan_enable_call_files(p->r2chan); 14456 } else { 14457 openr2_chan_disable_call_files(p->r2chan); 14458 } 14459 if (channo != -1) { 14460 if (ast_true(a->argv[3])) { 14461 ast_cli(a->fd, "MFC/R2 call files enabled for channel %d.\n", p->channel); 14462 } else { 14463 ast_cli(a->fd, "MFC/R2 call files disabled for channel %d.\n", p->channel); 14464 } 14465 break; 14466 } 14467 } 14468 if ((channo != -1) && !p) { 14469 ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo); 14470 } 14471 if (channo == -1) { 14472 if (ast_true(a->argv[3])) { 14473 ast_cli(a->fd, "MFC/R2 Call files enabled for all channels.\n"); 14474 } else { 14475 ast_cli(a->fd, "MFC/R2 Call files disabled for all channels.\n"); 14476 } 14477 } 14478 ast_mutex_unlock(&iflock); 14479 return CLI_SUCCESS; 14480 }
static char* handle_mfcr2_set_blocked | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14523 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_mutex_lock, dahdi_pvt::channel, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, iflist, dahdi_pvt::next, dahdi_pvt::r2chan, dahdi_pvt::sig, SIG_MFCR2, and ast_cli_entry::usage.
14524 { 14525 struct dahdi_pvt *p = NULL; 14526 int channo = 0; 14527 switch (cmd) { 14528 case CLI_INIT: 14529 e->command = "mfcr2 set blocked"; 14530 e->usage = 14531 "Usage: mfcr2 set blocked <channel>\n" 14532 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n" 14533 " Force the given channel into BLOCKED state.\n" 14534 " If no channel is specified, all channels will be set to BLOCKED.\n"; 14535 return NULL; 14536 case CLI_GENERATE: 14537 return NULL; 14538 } 14539 channo = (a->argc == 4) ? atoi(a->argv[3]) : -1; 14540 ast_mutex_lock(&iflock); 14541 for (p = iflist; p; p = p->next) { 14542 if (!(p->sig & SIG_MFCR2) || !p->r2chan) { 14543 continue; 14544 } 14545 if ((channo != -1) && (p->channel != channo )) { 14546 continue; 14547 } 14548 openr2_chan_set_blocked(p->r2chan); 14549 ast_mutex_lock(&p->lock); 14550 p->locallyblocked = 1; 14551 ast_mutex_unlock(&p->lock); 14552 if (channo != -1) { 14553 break; 14554 } 14555 } 14556 if ((channo != -1) && !p) { 14557 ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo); 14558 } 14559 ast_mutex_unlock(&iflock); 14560 return CLI_SUCCESS; 14561 }
static char* handle_mfcr2_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14362 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_strdupa, dahdi_pvt::channel, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, ast_cli_args::fd, iflist, dahdi_pvt::next, dahdi_pvt::r2chan, dahdi_pvt::sig, SIG_MFCR2, and ast_cli_entry::usage.
14363 { 14364 struct dahdi_pvt *p = NULL; 14365 int channo = 0; 14366 char *toklevel = NULL; 14367 char *saveptr = NULL; 14368 char *logval = NULL; 14369 openr2_log_level_t loglevel = OR2_LOG_NOTHING; 14370 openr2_log_level_t tmplevel = OR2_LOG_NOTHING; 14371 switch (cmd) { 14372 case CLI_INIT: 14373 e->command = "mfcr2 set debug"; 14374 e->usage = 14375 "Usage: mfcr2 set debug <loglevel> <channel>\n" 14376 " Set a new logging level for the specified channel.\n" 14377 " If no channel is specified the logging level will be applied to all channels.\n"; 14378 return NULL; 14379 case CLI_GENERATE: 14380 return NULL; 14381 } 14382 if (a->argc < 4) { 14383 return CLI_SHOWUSAGE; 14384 } 14385 channo = (a->argc == 5) ? atoi(a->argv[4]) : -1; 14386 logval = ast_strdupa(a->argv[3]); 14387 toklevel = strtok_r(logval, ",", &saveptr); 14388 if (-1 == (tmplevel = openr2_log_get_level(toklevel))) { 14389 ast_cli(a->fd, "Invalid MFC/R2 logging level '%s'.\n", a->argv[3]); 14390 return CLI_FAILURE; 14391 } else if (OR2_LOG_NOTHING == tmplevel) { 14392 loglevel = tmplevel; 14393 } else { 14394 loglevel |= tmplevel; 14395 while ((toklevel = strtok_r(NULL, ",", &saveptr))) { 14396 if (-1 == (tmplevel = openr2_log_get_level(toklevel))) { 14397 ast_cli(a->fd, "Ignoring invalid logging level: '%s'.\n", toklevel); 14398 continue; 14399 } 14400 loglevel |= tmplevel; 14401 } 14402 } 14403 ast_mutex_lock(&iflock); 14404 for (p = iflist; p; p = p->next) { 14405 if (!(p->sig & SIG_MFCR2) || !p->r2chan) { 14406 continue; 14407 } 14408 if ((channo != -1) && (p->channel != channo )) { 14409 continue; 14410 } 14411 openr2_chan_set_log_level(p->r2chan, loglevel); 14412 if (channo != -1) { 14413 ast_cli(a->fd, "MFC/R2 debugging set to '%s' for channel %d.\n", a->argv[3], p->channel); 14414 break; 14415 } 14416 } 14417 if ((channo != -1) && !p) { 14418 ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo); 14419 } 14420 if (channo == -1) { 14421 ast_cli(a->fd, "MFC/R2 debugging set to '%s' for all channels.\n", a->argv[3]); 14422 } 14423 ast_mutex_unlock(&iflock); 14424 return CLI_SUCCESS; 14425 }
static char* handle_mfcr2_set_idle | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14482 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_mutex_lock, dahdi_pvt::channel, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, iflist, dahdi_pvt::next, dahdi_pvt::r2chan, dahdi_pvt::sig, SIG_MFCR2, and ast_cli_entry::usage.
14483 { 14484 struct dahdi_pvt *p = NULL; 14485 int channo = 0; 14486 switch (cmd) { 14487 case CLI_INIT: 14488 e->command = "mfcr2 set idle"; 14489 e->usage = 14490 "Usage: mfcr2 set idle <channel>\n" 14491 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n" 14492 " Force the given channel into IDLE state.\n" 14493 " If no channel is specified, all channels will be set to IDLE.\n"; 14494 return NULL; 14495 case CLI_GENERATE: 14496 return NULL; 14497 } 14498 channo = (a->argc == 4) ? atoi(a->argv[3]) : -1; 14499 ast_mutex_lock(&iflock); 14500 for (p = iflist; p; p = p->next) { 14501 if (!(p->sig & SIG_MFCR2) || !p->r2chan) { 14502 continue; 14503 } 14504 if ((channo != -1) && (p->channel != channo )) { 14505 continue; 14506 } 14507 openr2_chan_set_idle(p->r2chan); 14508 ast_mutex_lock(&p->lock); 14509 p->locallyblocked = 0; 14510 p->mfcr2call = 0; 14511 ast_mutex_unlock(&p->lock); 14512 if (channo != -1) { 14513 break; 14514 } 14515 } 14516 if ((channo != -1) && !p) { 14517 ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo); 14518 } 14519 ast_mutex_unlock(&iflock); 14520 return CLI_SUCCESS; 14521 }
static char* handle_mfcr2_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14288 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, dahdi_pvt::context, ast_cli_args::fd, FORMAT, dahdi_pvt::group, iflist, dahdi_pvt::next, dahdi_pvt::r2chan, dahdi_pvt::sig, SIG_MFCR2, and ast_cli_entry::usage.
14289 { 14290 #define FORMAT "%4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n" 14291 int filtertype = 0; 14292 int targetnum = 0; 14293 char channo[5]; 14294 char anino[5]; 14295 char dnisno[5]; 14296 struct dahdi_pvt *p; 14297 openr2_context_t *r2context; 14298 openr2_variant_t r2variant; 14299 switch (cmd) { 14300 case CLI_INIT: 14301 e->command = "mfcr2 show channels [group|context]"; 14302 e->usage = 14303 "Usage: mfcr2 show channels [group <group> | context <context>]\n" 14304 " Shows the DAHDI channels configured with MFC/R2 signaling.\n"; 14305 return NULL; 14306 case CLI_GENERATE: 14307 return NULL; 14308 } 14309 if (!((a->argc == 3) || (a->argc == 5))) { 14310 return CLI_SHOWUSAGE; 14311 } 14312 if (a->argc == 5) { 14313 if (!strcasecmp(a->argv[3], "group")) { 14314 targetnum = atoi(a->argv[4]); 14315 if ((targetnum < 0) || (targetnum > 63)) 14316 return CLI_SHOWUSAGE; 14317 targetnum = 1 << targetnum; 14318 filtertype = 1; 14319 } else if (!strcasecmp(a->argv[3], "context")) { 14320 filtertype = 2; 14321 } else { 14322 return CLI_SHOWUSAGE; 14323 } 14324 } 14325 ast_cli(a->fd, FORMAT, "Chan", "Variant", "Max ANI", "Max DNIS", "ANI First", "Immediate Accept", "Tx CAS", "Rx CAS"); 14326 ast_mutex_lock(&iflock); 14327 for (p = iflist; p; p = p->next) { 14328 if (!(p->sig & SIG_MFCR2) || !p->r2chan) { 14329 continue; 14330 } 14331 if (filtertype) { 14332 switch(filtertype) { 14333 case 1: /* mfcr2 show channels group <group> */ 14334 if (p->group != targetnum) { 14335 continue; 14336 } 14337 break; 14338 case 2: /* mfcr2 show channels context <context> */ 14339 if (strcasecmp(p->context, a->argv[4])) { 14340 continue; 14341 } 14342 break; 14343 default: 14344 ; 14345 } 14346 } 14347 r2context = openr2_chan_get_context(p->r2chan); 14348 r2variant = openr2_context_get_variant(r2context); 14349 snprintf(channo, sizeof(channo), "%d", p->channel); 14350 snprintf(anino, sizeof(anino), "%d", openr2_context_get_max_ani(r2context)); 14351 snprintf(dnisno, sizeof(dnisno), "%d", openr2_context_get_max_dnis(r2context)); 14352 ast_cli(a->fd, FORMAT, channo, openr2_proto_get_variant_string(r2variant), 14353 anino, dnisno, openr2_context_get_ani_first(r2context) ? "Yes" : "No", 14354 openr2_context_get_immediate_accept(r2context) ? "Yes" : "No", 14355 openr2_chan_get_tx_cas_string(p->r2chan), openr2_chan_get_rx_cas_string(p->r2chan)); 14356 } 14357 ast_mutex_unlock(&iflock); 14358 return CLI_SUCCESS; 14359 #undef FORMAT 14360 }
static char* handle_mfcr2_show_variants | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14260 of file chan_dahdi.c.
References ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, and ast_cli_entry::usage.
14261 { 14262 #define FORMAT "%4s %40s\n" 14263 int i = 0; 14264 int numvariants = 0; 14265 const openr2_variant_entry_t *variants; 14266 switch (cmd) { 14267 case CLI_INIT: 14268 e->command = "mfcr2 show variants"; 14269 e->usage = 14270 "Usage: mfcr2 show variants\n" 14271 " Shows the list of MFC/R2 variants supported.\n"; 14272 return NULL; 14273 case CLI_GENERATE: 14274 return NULL; 14275 } 14276 if (!(variants = openr2_proto_get_variant_list(&numvariants))) { 14277 ast_cli(a->fd, "Failed to get list of variants.\n"); 14278 return CLI_FAILURE; 14279 } 14280 ast_cli(a->fd, FORMAT, "Variant Code", "Country"); 14281 for (i = 0; i < numvariants; i++) { 14282 ast_cli(a->fd, FORMAT, variants[i].name, variants[i].country); 14283 } 14284 return CLI_SUCCESS; 14285 #undef FORMAT 14286 }
static char* handle_mfcr2_version | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14244 of file chan_dahdi.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
14245 { 14246 switch (cmd) { 14247 case CLI_INIT: 14248 e->command = "mfcr2 show version"; 14249 e->usage = 14250 "Usage: mfcr2 show version\n" 14251 " Shows the version of the OpenR2 library being used.\n"; 14252 return NULL; 14253 case CLI_GENERATE: 14254 return NULL; 14255 } 14256 ast_cli(a->fd, "OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision()); 14257 return CLI_SUCCESS; 14258 }
static char* handle_pri_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 13890 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_span_4(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, dahdi_pri::pri, pris, SIG_PRI_DEBUG_INTENSE, SIG_PRI_DEBUG_NORMAL, ast_cli_entry::usage, and ast_cli_args::word.
13891 { 13892 int span; 13893 int x; 13894 int level = 0; 13895 switch (cmd) { 13896 case CLI_INIT: 13897 e->command = "pri set debug {on|off|0|1|2} span"; 13898 e->usage = 13899 "Usage: pri set debug {<level>|on|off} span <span>\n" 13900 " Enables debugging on a given PRI span\n"; 13901 return NULL; 13902 case CLI_GENERATE: 13903 return complete_span_4(a->line, a->word, a->pos, a->n); 13904 } 13905 if (a->argc < 6) { 13906 return CLI_SHOWUSAGE; 13907 } 13908 13909 if (!strcasecmp(a->argv[3], "on")) { 13910 level = 1; 13911 } else if (!strcasecmp(a->argv[3], "off")) { 13912 level = 0; 13913 } else { 13914 level = atoi(a->argv[3]); 13915 } 13916 span = atoi(a->argv[5]); 13917 if ((span < 1) || (span > NUM_SPANS)) { 13918 ast_cli(a->fd, "Invalid span %s. Should be a number %d to %d\n", a->argv[5], 1, NUM_SPANS); 13919 return CLI_SUCCESS; 13920 } 13921 if (!pris[span-1].pri.pri) { 13922 ast_cli(a->fd, "No PRI running on span %d\n", span); 13923 return CLI_SUCCESS; 13924 } 13925 13926 /* Set debug level in libpri */ 13927 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 13928 if (pris[span - 1].pri.dchans[x]) { 13929 switch (level) { 13930 case 0: 13931 pri_set_debug(pris[span - 1].pri.dchans[x], 0); 13932 break; 13933 case 1: 13934 pri_set_debug(pris[span - 1].pri.dchans[x], SIG_PRI_DEBUG_NORMAL); 13935 break; 13936 default: 13937 pri_set_debug(pris[span - 1].pri.dchans[x], SIG_PRI_DEBUG_INTENSE); 13938 break; 13939 } 13940 } 13941 } 13942 if (level == 0) { 13943 /* Close the debugging file if it's set */ 13944 ast_mutex_lock(&pridebugfdlock); 13945 if (0 <= pridebugfd) { 13946 close(pridebugfd); 13947 pridebugfd = -1; 13948 ast_cli(a->fd, "Disabled PRI debug output to file '%s'\n", 13949 pridebugfilename); 13950 } 13951 ast_mutex_unlock(&pridebugfdlock); 13952 } 13953 pris[span - 1].pri.debug = (level) ? 1 : 0; 13954 ast_cli(a->fd, "%s debugging on span %d\n", (level) ? "Enabled" : "Disabled", span); 13955 return CLI_SUCCESS; 13956 }
static char* handle_pri_service_disable_channel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14085 of file chan_dahdi.c.
References CLI_GENERATE, CLI_INIT, ast_cli_entry::command, handle_pri_service_generic(), and ast_cli_entry::usage.
14086 { 14087 switch (cmd) { 14088 case CLI_INIT: 14089 e->command = "pri service disable channel"; 14090 e->usage = 14091 "Usage: pri service disable channel <chan num> [<interface id>]\n" 14092 " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n" 14093 " to remove a channel from service, with optional interface id\n" 14094 " as agreed upon with remote switch operator\n"; 14095 return NULL; 14096 case CLI_GENERATE: 14097 return NULL; 14098 } 14099 return handle_pri_service_generic(e, cmd, a, 2); 14100 }
static char* handle_pri_service_enable_channel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14068 of file chan_dahdi.c.
References CLI_GENERATE, CLI_INIT, ast_cli_entry::command, handle_pri_service_generic(), and ast_cli_entry::usage.
14069 { 14070 switch (cmd) { 14071 case CLI_INIT: 14072 e->command = "pri service enable channel"; 14073 e->usage = 14074 "Usage: pri service enable channel <channel> [<interface id>]\n" 14075 " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n" 14076 " to restore a channel to service, with optional interface id\n" 14077 " as agreed upon with remote switch operator\n"; 14078 return NULL; 14079 case CLI_GENERATE: 14080 return NULL; 14081 } 14082 return handle_pri_service_generic(e, cmd, a, 0); 14083 }
static char* handle_pri_service_generic | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a, | |||
int | changestatus | |||
) | [static] |
Definition at line 13960 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_FAILURE, CLI_SHOWUSAGE, ast_cli_args::fd, dahdi_pri::pri, pris, and sig_pri_span::trunkgroup.
Referenced by handle_pri_service_disable_channel(), and handle_pri_service_enable_channel().
13961 { 13962 unsigned *why; 13963 int channel; 13964 int trunkgroup; 13965 int x, y, fd = a->fd; 13966 int interfaceid = 0; 13967 char *c; 13968 char db_chan_name[20], db_answer[5]; 13969 struct dahdi_pvt *tmp; 13970 struct dahdi_pri *pri; 13971 13972 if (a->argc < 5 || a->argc > 6) 13973 return CLI_SHOWUSAGE; 13974 if ((c = strchr(a->argv[4], ':'))) { 13975 if (sscanf(a->argv[4], "%30d:%30d", &trunkgroup, &channel) != 2) 13976 return CLI_SHOWUSAGE; 13977 if ((trunkgroup < 1) || (channel < 1)) 13978 return CLI_SHOWUSAGE; 13979 pri = NULL; 13980 for (x=0;x<NUM_SPANS;x++) { 13981 if (pris[x].pri.trunkgroup == trunkgroup) { 13982 pri = pris + x; 13983 break; 13984 } 13985 } 13986 if (!pri) { 13987 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 13988 return CLI_FAILURE; 13989 } 13990 } else 13991 channel = atoi(a->argv[4]); 13992 13993 if (a->argc == 6) 13994 interfaceid = atoi(a->argv[5]); 13995 13996 /* either servicing a D-Channel */ 13997 for (x = 0; x < NUM_SPANS; x++) { 13998 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 13999 if (pris[x].dchannels[y] == channel) { 14000 pri = pris + x; 14001 if (pri->pri.enable_service_message_support) { 14002 ast_mutex_lock(&pri->pri.lock); 14003 pri_maintenance_service(pri->pri.pri, interfaceid, -1, changestatus); 14004 ast_mutex_unlock(&pri->pri.lock); 14005 } else { 14006 ast_cli(fd, 14007 "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n" 14008 "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n"); 14009 } 14010 return CLI_SUCCESS; 14011 } 14012 } 14013 } 14014 14015 /* or servicing a B-Channel */ 14016 ast_mutex_lock(&iflock); 14017 for (tmp = iflist; tmp; tmp = tmp->next) { 14018 if (tmp->pri && tmp->channel == channel) { 14019 ast_mutex_unlock(&iflock); 14020 ast_mutex_lock(&tmp->pri->lock); 14021 if (!tmp->pri->enable_service_message_support) { 14022 ast_mutex_unlock(&tmp->pri->lock); 14023 ast_cli(fd, 14024 "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n" 14025 "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n"); 14026 return CLI_SUCCESS; 14027 } 14028 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, tmp->span, channel); 14029 why = &((struct sig_pri_chan *) tmp->sig_pvt)->service_status; 14030 switch(changestatus) { 14031 case 0: /* enable */ 14032 /* Near end wants to be in service now. */ 14033 ast_db_del(db_chan_name, SRVST_DBKEY); 14034 *why &= ~SRVST_NEAREND; 14035 if (*why) { 14036 snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS, *why); 14037 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer); 14038 } else { 14039 dahdi_pri_update_span_devstate(tmp->pri); 14040 } 14041 break; 14042 /* case 1: -- loop */ 14043 case 2: /* disable */ 14044 /* Near end wants to be out-of-service now. */ 14045 ast_db_del(db_chan_name, SRVST_DBKEY); 14046 *why |= SRVST_NEAREND; 14047 snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS, *why); 14048 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer); 14049 dahdi_pri_update_span_devstate(tmp->pri); 14050 break; 14051 /* case 3: -- continuity */ 14052 /* case 4: -- shutdown */ 14053 default: 14054 ast_log(LOG_WARNING, "Unsupported changestatus: '%d'\n", changestatus); 14055 break; 14056 } 14057 pri_maintenance_bservice(tmp->pri->pri, tmp->sig_pvt, changestatus); 14058 ast_mutex_unlock(&tmp->pri->lock); 14059 return CLI_SUCCESS; 14060 } 14061 } 14062 ast_mutex_unlock(&iflock); 14063 14064 ast_cli(fd, "Unable to find given channel %d, possibly not a PRI\n", channel); 14065 return CLI_FAILURE; 14066 }
static char* handle_pri_set_debug_file | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 13852 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), AST_FILE_MODE, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, pridebugfd, pridebugfdlock, pridebugfilename, and ast_cli_entry::usage.
13853 { 13854 int myfd; 13855 switch (cmd) { 13856 case CLI_INIT: 13857 e->command = "pri set debug file"; 13858 e->usage = "Usage: pri set debug file [output-file]\n" 13859 " Sends PRI debug output to the specified output file\n"; 13860 return NULL; 13861 case CLI_GENERATE: 13862 return NULL; 13863 } 13864 if (a->argc < 5) 13865 return CLI_SHOWUSAGE; 13866 13867 if (ast_strlen_zero(a->argv[4])) 13868 return CLI_SHOWUSAGE; 13869 13870 myfd = open(a->argv[4], O_CREAT|O_WRONLY, AST_FILE_MODE); 13871 if (myfd < 0) { 13872 ast_cli(a->fd, "Unable to open '%s' for writing\n", a->argv[4]); 13873 return CLI_SUCCESS; 13874 } 13875 13876 ast_mutex_lock(&pridebugfdlock); 13877 13878 if (pridebugfd >= 0) 13879 close(pridebugfd); 13880 13881 pridebugfd = myfd; 13882 ast_copy_string(pridebugfilename,a->argv[4],sizeof(pridebugfilename)); 13883 ast_mutex_unlock(&pridebugfdlock); 13884 ast_cli(a->fd, "PRI debug output will be sent to '%s'\n", a->argv[4]); 13885 return CLI_SUCCESS; 13886 }
static char* handle_pri_show_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14166 of file chan_dahdi.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, ast_cli_entry::command, sig_pri_span::dchans, debug, ast_cli_args::fd, sig_pri_span::pri, sig_pri_chan::pri, pris, and ast_cli_entry::usage.
14167 { 14168 int x; 14169 int span; 14170 int count=0; 14171 int debug; 14172 14173 switch (cmd) { 14174 case CLI_INIT: 14175 e->command = "pri show debug"; 14176 e->usage = 14177 "Usage: pri show debug\n" 14178 " Show the debug state of pri spans\n"; 14179 return NULL; 14180 case CLI_GENERATE: 14181 return NULL; 14182 } 14183 14184 for (span = 0; span < NUM_SPANS; span++) { 14185 if (pris[span].pri.pri) { 14186 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 14187 if (pris[span].pri.dchans[x]) { 14188 debug = pri_get_debug(pris[span].pri.dchans[x]); 14189 ast_cli(a->fd, "Span %d: Debug: %s\tIntense: %s\n", span+1, (debug&PRI_DEBUG_Q931_STATE)? "Yes" : "No" ,(debug&PRI_DEBUG_Q921_RAW)? "Yes" : "No" ); 14190 count++; 14191 } 14192 } 14193 } 14194 14195 } 14196 ast_mutex_lock(&pridebugfdlock); 14197 if (pridebugfd >= 0) 14198 ast_cli(a->fd, "Logging PRI debug to file %s\n", pridebugfilename); 14199 ast_mutex_unlock(&pridebugfdlock); 14200 14201 if (!count) 14202 ast_cli(a->fd, "No PRI running\n"); 14203 return CLI_SUCCESS; 14204 }
static char* handle_pri_show_span | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14132 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_span_4(), dahdi_pri::dchannels, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, dahdi_pri::pri, sig_pri_span::pri, sig_pri_chan::pri, pris, sig_pri_cli_show_span(), ast_cli_entry::usage, and ast_cli_args::word.
14133 { 14134 int span; 14135 14136 switch (cmd) { 14137 case CLI_INIT: 14138 e->command = "pri show span"; 14139 e->usage = 14140 "Usage: pri show span <span>\n" 14141 " Displays PRI Information on a given PRI span\n"; 14142 return NULL; 14143 case CLI_GENERATE: 14144 return complete_span_4(a->line, a->word, a->pos, a->n); 14145 } 14146 14147 if (a->argc < 4) 14148 return CLI_SHOWUSAGE; 14149 span = atoi(a->argv[3]); 14150 if ((span < 1) || (span > NUM_SPANS)) { 14151 ast_cli(a->fd, "Invalid span '%s'. Should be a number from %d to %d\n", a->argv[3], 1, NUM_SPANS); 14152 return CLI_SUCCESS; 14153 } 14154 if (!pris[span-1].pri.pri) { 14155 ast_cli(a->fd, "No PRI running on span %d\n", span); 14156 return CLI_SUCCESS; 14157 } 14158 14159 sig_pri_cli_show_span(a->fd, pris[span-1].dchannels, &pris[span-1].pri); 14160 14161 return CLI_SUCCESS; 14162 }
static char* handle_pri_show_spans | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14104 of file chan_dahdi.c.
References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, ast_cli_args::fd, dahdi_pri::pri, sig_pri_span::pri, sig_pri_chan::pri, pris, sig_pri_cli_show_spans(), and ast_cli_entry::usage.
14105 { 14106 int span; 14107 14108 switch (cmd) { 14109 case CLI_INIT: 14110 e->command = "pri show spans"; 14111 e->usage = 14112 "Usage: pri show spans\n" 14113 " Displays PRI Information\n"; 14114 return NULL; 14115 case CLI_GENERATE: 14116 return NULL; 14117 } 14118 14119 if (a->argc != 3) 14120 return CLI_SHOWUSAGE; 14121 14122 for (span = 0; span < NUM_SPANS; span++) { 14123 if (pris[span].pri.pri) { 14124 sig_pri_cli_show_spans(a->fd, span + 1, &pris[span].pri); 14125 } 14126 } 14127 return CLI_SUCCESS; 14128 }
static char* handle_pri_version | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14208 of file chan_dahdi.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
14209 { 14210 switch (cmd) { 14211 case CLI_INIT: 14212 e->command = "pri show version"; 14213 e->usage = 14214 "Usage: pri show version\n" 14215 "Show libpri version information\n"; 14216 return NULL; 14217 case CLI_GENERATE: 14218 return NULL; 14219 } 14220 14221 ast_cli(a->fd, "libpri version: %s\n", pri_get_version()); 14222 14223 return CLI_SUCCESS; 14224 }
static char* handle_ss7_block_cic | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15796 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, sig_ss7_linkset::ss7, dahdi_ss7::ss7, and ast_cli_entry::usage.
15797 { 15798 int linkset, cic; 15799 int blocked = -1, i; 15800 switch (cmd) { 15801 case CLI_INIT: 15802 e->command = "ss7 block cic"; 15803 e->usage = 15804 "Usage: ss7 block cic <linkset> <CIC>\n" 15805 " Sends a remote blocking request for the given CIC on the specified linkset\n"; 15806 return NULL; 15807 case CLI_GENERATE: 15808 return NULL; 15809 } 15810 if (a->argc == 5) 15811 linkset = atoi(a->argv[3]); 15812 else 15813 return CLI_SHOWUSAGE; 15814 15815 if ((linkset < 1) || (linkset > NUM_SPANS)) { 15816 ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS); 15817 return CLI_SUCCESS; 15818 } 15819 15820 if (!linksets[linkset-1].ss7.ss7) { 15821 ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset); 15822 return CLI_SUCCESS; 15823 } 15824 15825 cic = atoi(a->argv[4]); 15826 15827 if (cic < 1) { 15828 ast_cli(a->fd, "Invalid CIC specified!\n"); 15829 return CLI_SUCCESS; 15830 } 15831 15832 for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) { 15833 if (linksets[linkset-1].ss7.pvts[i]->cic == cic) { 15834 blocked = linksets[linkset-1].ss7.pvts[i]->locallyblocked; 15835 if (!blocked) { 15836 ast_mutex_lock(&linksets[linkset-1].ss7.lock); 15837 isup_blo(linksets[linkset-1].ss7.ss7, cic, linksets[linkset-1].ss7.pvts[i]->dpc); 15838 ast_mutex_unlock(&linksets[linkset-1].ss7.lock); 15839 } 15840 } 15841 } 15842 15843 if (blocked < 0) { 15844 ast_cli(a->fd, "Invalid CIC specified!\n"); 15845 return CLI_SUCCESS; 15846 } 15847 15848 if (!blocked) 15849 ast_cli(a->fd, "Sent blocking request for linkset %d on CIC %d\n", linkset, cic); 15850 else 15851 ast_cli(a->fd, "CIC %d already locally blocked\n", cic); 15852 15853 /* Break poll on the linkset so it sends our messages */ 15854 pthread_kill(linksets[linkset-1].ss7.master, SIGURG); 15855 15856 return CLI_SUCCESS; 15857 }
static char* handle_ss7_block_linkset | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15861 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, sig_ss7_linkset::ss7, dahdi_ss7::ss7, and ast_cli_entry::usage.
15862 { 15863 int linkset; 15864 int i; 15865 switch (cmd) { 15866 case CLI_INIT: 15867 e->command = "ss7 block linkset"; 15868 e->usage = 15869 "Usage: ss7 block linkset <linkset number>\n" 15870 " Sends a remote blocking request for all CICs on the given linkset\n"; 15871 return NULL; 15872 case CLI_GENERATE: 15873 return NULL; 15874 } 15875 if (a->argc == 4) 15876 linkset = atoi(a->argv[3]); 15877 else 15878 return CLI_SHOWUSAGE; 15879 15880 if ((linkset < 1) || (linkset > NUM_SPANS)) { 15881 ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS); 15882 return CLI_SUCCESS; 15883 } 15884 15885 if (!linksets[linkset-1].ss7.ss7) { 15886 ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset); 15887 return CLI_SUCCESS; 15888 } 15889 15890 for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) { 15891 ast_cli(a->fd, "Sending remote blocking request on CIC %d\n", linksets[linkset-1].ss7.pvts[i]->cic); 15892 ast_mutex_lock(&linksets[linkset-1].ss7.lock); 15893 isup_blo(linksets[linkset-1].ss7.ss7, linksets[linkset-1].ss7.pvts[i]->cic, linksets[linkset-1].ss7.pvts[i]->dpc); 15894 ast_mutex_unlock(&linksets[linkset-1].ss7.lock); 15895 } 15896 15897 /* Break poll on the linkset so it sends our messages */ 15898 pthread_kill(linksets[linkset-1].ss7.master, SIGURG); 15899 15900 return CLI_SUCCESS; 15901 }
static char* handle_ss7_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15759 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, SIG_SS7_DEBUG, dahdi_ss7::ss7, and ast_cli_entry::usage.
15760 { 15761 int span; 15762 switch (cmd) { 15763 case CLI_INIT: 15764 e->command = "ss7 set debug {on|off} linkset"; 15765 e->usage = 15766 "Usage: ss7 set debug {on|off} linkset <linkset>\n" 15767 " Enables debugging on a given SS7 linkset\n"; 15768 return NULL; 15769 case CLI_GENERATE: 15770 return NULL; 15771 } 15772 if (a->argc < 6) 15773 return CLI_SHOWUSAGE; 15774 span = atoi(a->argv[5]); 15775 if ((span < 1) || (span > NUM_SPANS)) { 15776 ast_cli(a->fd, "Invalid linkset %s. Should be a number from %d to %d\n", a->argv[5], 1, NUM_SPANS); 15777 return CLI_SUCCESS; 15778 } 15779 if (!linksets[span-1].ss7.ss7) { 15780 ast_cli(a->fd, "No SS7 running on linkset %d\n", span); 15781 } else { 15782 if (!strcasecmp(a->argv[3], "on")) { 15783 ss7_set_debug(linksets[span-1].ss7.ss7, SIG_SS7_DEBUG); 15784 ast_cli(a->fd, "Enabled debugging on linkset %d\n", span); 15785 } else { 15786 ss7_set_debug(linksets[span-1].ss7.ss7, 0); 15787 ast_cli(a->fd, "Disabled debugging on linkset %d\n", span); 15788 } 15789 } 15790 15791 return CLI_SUCCESS; 15792 }
static char* handle_ss7_show_linkset | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 16009 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, sig_ss7_linkset::LINKSET_STATE_UP, sig_ss7_linkset::ss7, and ast_cli_entry::usage.
16010 { 16011 int linkset; 16012 struct sig_ss7_linkset *ss7; 16013 switch (cmd) { 16014 case CLI_INIT: 16015 e->command = "ss7 show linkset"; 16016 e->usage = 16017 "Usage: ss7 show linkset <span>\n" 16018 " Shows the status of an SS7 linkset.\n"; 16019 return NULL; 16020 case CLI_GENERATE: 16021 return NULL; 16022 } 16023 16024 if (a->argc < 4) 16025 return CLI_SHOWUSAGE; 16026 linkset = atoi(a->argv[3]); 16027 if ((linkset < 1) || (linkset > NUM_SPANS)) { 16028 ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS); 16029 return CLI_SUCCESS; 16030 } 16031 ss7 = &linksets[linkset - 1].ss7; 16032 if (!ss7->ss7) { 16033 ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset); 16034 return CLI_SUCCESS; 16035 } 16036 16037 ast_cli(a->fd, "SS7 linkset %d status: %s\n", linkset, (ss7->state == LINKSET_STATE_UP) ? "Up" : "Down"); 16038 16039 return CLI_SUCCESS; 16040 }
static char* handle_ss7_unblock_cic | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15905 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, sig_ss7_linkset::ss7, dahdi_ss7::ss7, and ast_cli_entry::usage.
15906 { 15907 int linkset, cic; 15908 int i, blocked = -1; 15909 switch (cmd) { 15910 case CLI_INIT: 15911 e->command = "ss7 unblock cic"; 15912 e->usage = 15913 "Usage: ss7 unblock cic <linkset> <CIC>\n" 15914 " Sends a remote unblocking request for the given CIC on the specified linkset\n"; 15915 return NULL; 15916 case CLI_GENERATE: 15917 return NULL; 15918 } 15919 15920 if (a->argc == 5) 15921 linkset = atoi(a->argv[3]); 15922 else 15923 return CLI_SHOWUSAGE; 15924 15925 if ((linkset < 1) || (linkset > NUM_SPANS)) { 15926 ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS); 15927 return CLI_SUCCESS; 15928 } 15929 15930 if (!linksets[linkset-1].ss7.ss7) { 15931 ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset); 15932 return CLI_SUCCESS; 15933 } 15934 15935 cic = atoi(a->argv[4]); 15936 15937 if (cic < 1) { 15938 ast_cli(a->fd, "Invalid CIC specified!\n"); 15939 return CLI_SUCCESS; 15940 } 15941 15942 for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) { 15943 if (linksets[linkset-1].ss7.pvts[i]->cic == cic) { 15944 blocked = linksets[linkset-1].ss7.pvts[i]->locallyblocked; 15945 if (blocked) { 15946 ast_mutex_lock(&linksets[linkset-1].ss7.lock); 15947 isup_ubl(linksets[linkset-1].ss7.ss7, cic, linksets[linkset-1].ss7.pvts[i]->dpc); 15948 ast_mutex_unlock(&linksets[linkset-1].ss7.lock); 15949 } 15950 } 15951 } 15952 15953 if (blocked > 0) 15954 ast_cli(a->fd, "Sent unblocking request for linkset %d on CIC %d\n", linkset, cic); 15955 15956 /* Break poll on the linkset so it sends our messages */ 15957 pthread_kill(linksets[linkset-1].ss7.master, SIGURG); 15958 15959 return CLI_SUCCESS; 15960 }
static char* handle_ss7_unblock_linkset | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15964 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, sig_ss7_linkset::ss7, dahdi_ss7::ss7, and ast_cli_entry::usage.
15965 { 15966 int linkset; 15967 int i; 15968 switch (cmd) { 15969 case CLI_INIT: 15970 e->command = "ss7 unblock linkset"; 15971 e->usage = 15972 "Usage: ss7 unblock linkset <linkset number>\n" 15973 " Sends a remote unblocking request for all CICs on the specified linkset\n"; 15974 return NULL; 15975 case CLI_GENERATE: 15976 return NULL; 15977 } 15978 15979 if (a->argc == 4) 15980 linkset = atoi(a->argv[3]); 15981 else 15982 return CLI_SHOWUSAGE; 15983 15984 if ((linkset < 1) || (linkset > NUM_SPANS)) { 15985 ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS); 15986 return CLI_SUCCESS; 15987 } 15988 15989 if (!linksets[linkset-1].ss7.ss7) { 15990 ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset); 15991 return CLI_SUCCESS; 15992 } 15993 15994 for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) { 15995 ast_cli(a->fd, "Sending remote unblock request on CIC %d\n", linksets[linkset-1].ss7.pvts[i]->cic); 15996 ast_mutex_lock(&linksets[linkset-1].ss7.lock); 15997 isup_ubl(linksets[linkset-1].ss7.ss7, linksets[linkset-1].ss7.pvts[i]->cic, linksets[linkset-1].ss7.pvts[i]->dpc); 15998 ast_mutex_unlock(&linksets[linkset-1].ss7.lock); 15999 } 16000 16001 /* Break poll on the linkset so it sends our messages */ 16002 pthread_kill(linksets[linkset-1].ss7.master, SIGURG); 16003 16004 return CLI_SUCCESS; 16005 }
static char* handle_ss7_version | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 16044 of file chan_dahdi.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
16045 { 16046 switch (cmd) { 16047 case CLI_INIT: 16048 e->command = "ss7 show version"; 16049 e->usage = 16050 "Usage: ss7 show version\n" 16051 " Show the libss7 version\n"; 16052 return NULL; 16053 case CLI_GENERATE: 16054 return NULL; 16055 } 16056 16057 ast_cli(a->fd, "libss7 version: %s\n", ss7_get_version()); 16058 16059 return CLI_SUCCESS; 16060 }
static int has_voicemail | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5122 of file chan_dahdi.c.
References ast_app_has_voicemail(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_strdupa, ast_strlen_zero(), context, dahdi_pvt::mailbox, mailbox, and strsep().
05123 { 05124 int new_msgs; 05125 struct ast_event *event; 05126 char *mailbox, *context; 05127 05128 mailbox = context = ast_strdupa(p->mailbox); 05129 strsep(&context, "@"); 05130 if (ast_strlen_zero(context)) 05131 context = "default"; 05132 05133 event = ast_event_get_cached(AST_EVENT_MWI, 05134 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 05135 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 05136 AST_EVENT_IE_END); 05137 05138 if (event) { 05139 new_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 05140 ast_event_destroy(event); 05141 } else 05142 new_msgs = ast_app_has_voicemail(p->mailbox, NULL); 05143 05144 return new_msgs; 05145 }
static int is_group_or_channel_match | ( | struct dahdi_pvt * | p, | |
int | span, | |||
ast_group_t | groupmatch, | |||
int * | groupmatched, | |||
int | channelmatch, | |||
int * | channelmatched | |||
) | [static] |
Definition at line 12796 of file chan_dahdi.c.
References dahdi_pvt::channel, dahdi_pvt::group, dahdi_pvt::pri, and sig_pri_span::span.
Referenced by dahdi_cc_callback(), and dahdi_request().
12797 { 12798 #if defined(HAVE_PRI) 12799 if (0 < span) { 12800 /* The channel must be on the specified PRI span. */ 12801 if (!p->pri || p->pri->span != span) { 12802 return 0; 12803 } 12804 if (!groupmatch && channelmatch == -1) { 12805 /* Match any group since it only needs to be on the PRI span. */ 12806 *groupmatched = 1; 12807 return 1; 12808 } 12809 } 12810 #endif /* defined(HAVE_PRI) */ 12811 /* check group matching */ 12812 if (groupmatch) { 12813 if ((p->group & groupmatch) != groupmatch) 12814 /* Doesn't match the specified group, try the next one */ 12815 return 0; 12816 *groupmatched = 1; 12817 } 12818 /* Check to see if we have a channel match */ 12819 if (channelmatch != -1) { 12820 if (p->channel != channelmatch) 12821 /* Doesn't match the specified channel, try the next one */ 12822 return 0; 12823 *channelmatched = 1; 12824 } 12825 12826 return 1; 12827 }
static int isourconf | ( | struct dahdi_pvt * | p, | |
struct dahdi_subchannel * | c | |||
) | [static] |
Definition at line 4604 of file chan_dahdi.c.
References dahdi_pvt::channel, dahdi_pvt::confno, and dahdi_subchannel::curconf.
Referenced by conf_del().
04605 { 04606 /* If they're listening to our channel, they're ours */ 04607 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON)) 04608 return 1; 04609 /* If they're a talker on our (allocated) conference, they're ours */ 04610 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER)) 04611 return 1; 04612 return 0; 04613 }
Definition at line 4634 of file chan_dahdi.c.
References dahdi_subchannel::dfd, dahdi_subchannel::inthreeway, MAX_SLAVES, dahdi_pvt::slaves, and dahdi_pvt::subs.
Referenced by my_complete_conference_update(), and update_conf().
04635 { 04636 int x; 04637 int useslavenative; 04638 struct dahdi_pvt *slave = NULL; 04639 /* Start out optimistic */ 04640 useslavenative = 1; 04641 /* Update conference state in a stateless fashion */ 04642 for (x = 0; x < 3; x++) { 04643 /* Any three-way calling makes slave native mode *definitely* out 04644 of the question */ 04645 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) 04646 useslavenative = 0; 04647 } 04648 /* If we don't have any 3-way calls, check to see if we have 04649 precisely one slave */ 04650 if (useslavenative) { 04651 for (x = 0; x < MAX_SLAVES; x++) { 04652 if (p->slaves[x]) { 04653 if (slave) { 04654 /* Whoops already have a slave! No 04655 slave native and stop right away */ 04656 slave = NULL; 04657 useslavenative = 0; 04658 break; 04659 } else { 04660 /* We have one slave so far */ 04661 slave = p->slaves[x]; 04662 } 04663 } 04664 } 04665 } 04666 /* If no slave, slave native definitely out */ 04667 if (!slave) 04668 useslavenative = 0; 04669 else if (slave->law != p->law) { 04670 useslavenative = 0; 04671 slave = NULL; 04672 } 04673 if (out) 04674 *out = slave; 04675 return useslavenative; 04676 }
static int linkset_addsigchan | ( | int | sigchan | ) | [static] |
Definition at line 15644 of file chan_dahdi.c.
References ast_log(), cur_adjpointcode, cur_defaultdpc, cur_linkset, cur_networkindicator, cur_pointcode, cur_ss7type, dahdi_close_ss7_fd(), errno, sig_ss7_linkset::fds, sig_ss7_linkset::numsigchans, sig_ss7_add_sigchan(), dahdi_ss7::ss7, and ss7_resolve_linkset().
15645 { 15646 struct dahdi_ss7 *link; 15647 int res; 15648 int curfd; 15649 struct dahdi_params params; 15650 struct dahdi_bufferinfo bi; 15651 struct dahdi_spaninfo si; 15652 15653 if (sigchan < 0) { 15654 ast_log(LOG_ERROR, "Invalid sigchan!\n"); 15655 return -1; 15656 } 15657 if (cur_ss7type < 0) { 15658 ast_log(LOG_ERROR, "Unspecified or invalid ss7type\n"); 15659 return -1; 15660 } 15661 if (cur_pointcode < 0) { 15662 ast_log(LOG_ERROR, "Unspecified pointcode!\n"); 15663 return -1; 15664 } 15665 if (cur_adjpointcode < 0) { 15666 ast_log(LOG_ERROR, "Unspecified adjpointcode!\n"); 15667 return -1; 15668 } 15669 if (cur_defaultdpc < 0) { 15670 ast_log(LOG_ERROR, "Unspecified defaultdpc!\n"); 15671 return -1; 15672 } 15673 if (cur_networkindicator < 0) { 15674 ast_log(LOG_ERROR, "Invalid networkindicator!\n"); 15675 return -1; 15676 } 15677 link = ss7_resolve_linkset(cur_linkset); 15678 if (!link) { 15679 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1); 15680 return -1; 15681 } 15682 if (link->ss7.numsigchans >= SIG_SS7_NUM_DCHANS) { 15683 ast_log(LOG_ERROR, "Too many sigchans on linkset %d\n", cur_linkset); 15684 return -1; 15685 } 15686 15687 curfd = link->ss7.numsigchans; 15688 15689 /* Open signaling channel */ 15690 link->ss7.fds[curfd] = open("/dev/dahdi/channel", O_RDWR, 0600); 15691 if (link->ss7.fds[curfd] < 0) { 15692 ast_log(LOG_ERROR, "Unable to open SS7 sigchan %d (%s)\n", sigchan, 15693 strerror(errno)); 15694 return -1; 15695 } 15696 if (ioctl(link->ss7.fds[curfd], DAHDI_SPECIFY, &sigchan) == -1) { 15697 dahdi_close_ss7_fd(link, curfd); 15698 ast_log(LOG_ERROR, "Unable to specify SS7 sigchan %d (%s)\n", sigchan, 15699 strerror(errno)); 15700 return -1; 15701 } 15702 15703 /* Get signaling channel parameters */ 15704 memset(¶ms, 0, sizeof(params)); 15705 res = ioctl(link->ss7.fds[curfd], DAHDI_GET_PARAMS, ¶ms); 15706 if (res) { 15707 dahdi_close_ss7_fd(link, curfd); 15708 ast_log(LOG_ERROR, "Unable to get parameters for sigchan %d (%s)\n", sigchan, 15709 strerror(errno)); 15710 return -1; 15711 } 15712 if (params.sigtype != DAHDI_SIG_HDLCFCS 15713 && params.sigtype != DAHDI_SIG_HARDHDLC 15714 && params.sigtype != DAHDI_SIG_MTP2) { 15715 dahdi_close_ss7_fd(link, curfd); 15716 ast_log(LOG_ERROR, "sigchan %d is not in HDLC/FCS mode.\n", sigchan); 15717 return -1; 15718 } 15719 15720 /* Set signaling channel buffer policy. */ 15721 memset(&bi, 0, sizeof(bi)); 15722 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; 15723 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; 15724 bi.numbufs = 32; 15725 bi.bufsize = 512; 15726 if (ioctl(link->ss7.fds[curfd], DAHDI_SET_BUFINFO, &bi)) { 15727 ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d: %s\n", 15728 sigchan, strerror(errno)); 15729 dahdi_close_ss7_fd(link, curfd); 15730 return -1; 15731 } 15732 15733 /* Get current signaling channel alarm status. */ 15734 memset(&si, 0, sizeof(si)); 15735 res = ioctl(link->ss7.fds[curfd], DAHDI_SPANSTAT, &si); 15736 if (res) { 15737 dahdi_close_ss7_fd(link, curfd); 15738 ast_log(LOG_ERROR, "Unable to get span state for sigchan %d (%s)\n", sigchan, 15739 strerror(errno)); 15740 } 15741 15742 res = sig_ss7_add_sigchan(&link->ss7, curfd, cur_ss7type, 15743 (params.sigtype == DAHDI_SIG_MTP2) 15744 ? SS7_TRANSPORT_DAHDIMTP2 15745 : SS7_TRANSPORT_DAHDIDCHAN, 15746 si.alarms, cur_networkindicator, cur_pointcode, cur_adjpointcode); 15747 if (res) { 15748 dahdi_close_ss7_fd(link, curfd); 15749 return -1; 15750 } 15751 15752 ++link->ss7.numsigchans; 15753 15754 return 0; 15755 }
static int load_module | ( | void | ) | [static] |
Definition at line 17970 of file chan_dahdi.c.
References __unload_module(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_dahdishowchannels(), action_transfer(), action_transferhangup(), ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_channel_register(), ast_cli_register_multiple(), ast_cond_init, ast_data_register_multiple, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, ast_register_application_xml, dahdi_accept_r2_call_exec(), dahdi_cli, dahdi_data_providers, dahdi_mfcr2_cli, dahdi_pri_cli, dahdi_pri_error(), dahdi_pri_message(), dahdi_send_callrerouting_facility_exec(), dahdi_send_keypad_facility_exec(), dahdi_ss7_cli, dahdi_ss7_error(), dahdi_ss7_message(), dahdi_tech, round_robin, setup_dahdi(), sig_pri_init_pri(), sig_pri_load(), sig_ss7_init_linkset(), and ss_thread_complete.
17971 { 17972 int res; 17973 #if defined(HAVE_PRI) || defined(HAVE_SS7) 17974 int y; 17975 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 17976 17977 #ifdef HAVE_PRI 17978 memset(pris, 0, sizeof(pris)); 17979 for (y = 0; y < NUM_SPANS; y++) { 17980 sig_pri_init_pri(&pris[y].pri); 17981 } 17982 pri_set_error(dahdi_pri_error); 17983 pri_set_message(dahdi_pri_message); 17984 ast_register_application_xml(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec); 17985 #ifdef HAVE_PRI_PROG_W_CAUSE 17986 ast_register_application_xml(dahdi_send_callrerouting_facility_app, dahdi_send_callrerouting_facility_exec); 17987 #endif 17988 #if defined(HAVE_PRI_CCSS) 17989 if (ast_cc_agent_register(&dahdi_pri_cc_agent_callbacks) 17990 || ast_cc_monitor_register(&dahdi_pri_cc_monitor_callbacks)) { 17991 __unload_module(); 17992 return AST_MODULE_LOAD_FAILURE; 17993 } 17994 #endif /* defined(HAVE_PRI_CCSS) */ 17995 if (sig_pri_load( 17996 #if defined(HAVE_PRI_CCSS) 17997 dahdi_pri_cc_type 17998 #else 17999 NULL 18000 #endif /* defined(HAVE_PRI_CCSS) */ 18001 )) { 18002 __unload_module(); 18003 return AST_MODULE_LOAD_FAILURE; 18004 } 18005 #endif 18006 #if defined(HAVE_SS7) 18007 memset(linksets, 0, sizeof(linksets)); 18008 for (y = 0; y < NUM_SPANS; y++) { 18009 sig_ss7_init_linkset(&linksets[y].ss7); 18010 } 18011 ss7_set_error(dahdi_ss7_error); 18012 ss7_set_message(dahdi_ss7_message); 18013 #endif /* defined(HAVE_SS7) */ 18014 res = setup_dahdi(0); 18015 /* Make sure we can register our DAHDI channel type */ 18016 if (res) 18017 return AST_MODULE_LOAD_DECLINE; 18018 if (ast_channel_register(&dahdi_tech)) { 18019 ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n"); 18020 __unload_module(); 18021 return AST_MODULE_LOAD_FAILURE; 18022 } 18023 #ifdef HAVE_PRI 18024 ast_cli_register_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli)); 18025 #endif 18026 #if defined(HAVE_SS7) 18027 ast_cli_register_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli)); 18028 #endif /* defined(HAVE_SS7) */ 18029 #ifdef HAVE_OPENR2 18030 ast_cli_register_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli)); 18031 ast_register_application_xml(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec); 18032 #endif 18033 18034 ast_cli_register_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli)); 18035 /* register all the data providers */ 18036 ast_data_register_multiple(dahdi_data_providers, ARRAY_LEN(dahdi_data_providers)); 18037 memset(round_robin, 0, sizeof(round_robin)); 18038 ast_manager_register_xml("DAHDITransfer", 0, action_transfer); 18039 ast_manager_register_xml("DAHDIHangup", 0, action_transferhangup); 18040 ast_manager_register_xml("DAHDIDialOffhook", 0, action_dahdidialoffhook); 18041 ast_manager_register_xml("DAHDIDNDon", 0, action_dahdidndon); 18042 ast_manager_register_xml("DAHDIDNDoff", 0, action_dahdidndoff); 18043 ast_manager_register_xml("DAHDIShowChannels", 0, action_dahdishowchannels); 18044 ast_manager_register_xml("DAHDIRestart", 0, action_dahdirestart); 18045 18046 ast_cond_init(&ss_thread_complete, NULL); 18047 18048 return res; 18049 }
static void* mfcr2_monitor | ( | void * | data | ) | [static] |
Definition at line 13600 of file chan_dahdi.c.
References ast_log(), LOG_DEBUG, and SUB_REAL.
13601 { 13602 struct dahdi_mfcr2 *mfcr2 = data; 13603 /* we should be using pthread_key_create 13604 and allocate pollers dynamically. 13605 I think do_monitor() could be leaking, since it 13606 could be cancelled at any time and is not 13607 using thread keys, why?, */ 13608 struct pollfd pollers[ARRAY_LEN(mfcr2->pvts)]; 13609 int res = 0; 13610 int i = 0; 13611 int oldstate = 0; 13612 int quit_loop = 0; 13613 int maxsleep = 20; 13614 int was_idle = 0; 13615 int pollsize = 0; 13616 /* now that we're ready to get calls, unblock our side and 13617 get current line state */ 13618 for (i = 0; i < mfcr2->numchans; i++) { 13619 openr2_chan_set_idle(mfcr2->pvts[i]->r2chan); 13620 openr2_chan_handle_cas(mfcr2->pvts[i]->r2chan); 13621 } 13622 while (1) { 13623 /* we trust here that the mfcr2 channel list will not ever change once 13624 the module is loaded */ 13625 pollsize = 0; 13626 for (i = 0; i < mfcr2->numchans; i++) { 13627 pollers[i].revents = 0; 13628 pollers[i].events = 0; 13629 if (mfcr2->pvts[i]->owner) { 13630 continue; 13631 } 13632 if (!mfcr2->pvts[i]->r2chan) { 13633 ast_log(LOG_DEBUG, "Wow, no r2chan on channel %d\n", mfcr2->pvts[i]->channel); 13634 quit_loop = 1; 13635 break; 13636 } 13637 openr2_chan_enable_read(mfcr2->pvts[i]->r2chan); 13638 pollers[i].events = POLLIN | POLLPRI; 13639 pollers[i].fd = mfcr2->pvts[i]->subs[SUB_REAL].dfd; 13640 pollsize++; 13641 } 13642 if (quit_loop) { 13643 break; 13644 } 13645 if (pollsize == 0) { 13646 if (!was_idle) { 13647 ast_log(LOG_DEBUG, "Monitor thread going idle since everybody has an owner\n"); 13648 was_idle = 1; 13649 } 13650 poll(NULL, 0, maxsleep); 13651 continue; 13652 } 13653 was_idle = 0; 13654 /* probably poll() is a valid cancel point, lets just be on the safe side 13655 by calling pthread_testcancel */ 13656 pthread_testcancel(); 13657 res = poll(pollers, mfcr2->numchans, maxsleep); 13658 pthread_testcancel(); 13659 if ((res < 0) && (errno != EINTR)) { 13660 ast_log(LOG_ERROR, "going out, poll failed: %s\n", strerror(errno)); 13661 break; 13662 } 13663 /* do we want to allow to cancel while processing events? */ 13664 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); 13665 for (i = 0; i < mfcr2->numchans; i++) { 13666 if (pollers[i].revents & POLLPRI || pollers[i].revents & POLLIN) { 13667 openr2_chan_process_event(mfcr2->pvts[i]->r2chan); 13668 } 13669 } 13670 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); 13671 } 13672 ast_log(LOG_NOTICE, "Quitting MFC/R2 monitor thread\n"); 13673 return 0; 13674 }
static struct dahdi_pvt* mkintf | ( | int | channel, | |
const struct dahdi_chan_conf * | conf, | |||
int | reloading | |||
) | [static] |
Definition at line 11917 of file chan_dahdi.c.
References dahdi_pvt::channel, dahdi_pvt::destroy, iflist, and dahdi_pvt::next.
Referenced by build_channels().
11918 { 11919 /* Make a dahdi_pvt structure for this interface */ 11920 struct dahdi_pvt *tmp;/*!< Current channel structure initializing */ 11921 char fn[80]; 11922 struct dahdi_bufferinfo bi; 11923 11924 int res; 11925 int span = 0; 11926 int here = 0;/*!< TRUE if the channel interface already exists. */ 11927 int x; 11928 struct analog_pvt *analog_p = NULL; 11929 struct dahdi_params p; 11930 #if defined(HAVE_PRI) 11931 struct dahdi_spaninfo si; 11932 struct sig_pri_chan *pri_chan = NULL; 11933 #endif /* defined(HAVE_PRI) */ 11934 #if defined(HAVE_SS7) 11935 struct sig_ss7_chan *ss7_chan = NULL; 11936 #endif /* defined(HAVE_SS7) */ 11937 11938 /* Search channel interface list to see if it already exists. */ 11939 for (tmp = iflist; tmp; tmp = tmp->next) { 11940 if (!tmp->destroy) { 11941 if (tmp->channel == channel) { 11942 /* The channel interface already exists. */ 11943 here = 1; 11944 break; 11945 } 11946 if (tmp->channel > channel) { 11947 /* No way it can be in the sorted list. */ 11948 tmp = NULL; 11949 break; 11950 } 11951 } 11952 } 11953 11954 if (!here && reloading != 1) { 11955 tmp = ast_calloc(1, sizeof(*tmp)); 11956 if (!tmp) { 11957 return NULL; 11958 } 11959 tmp->cc_params = ast_cc_config_params_init(); 11960 if (!tmp->cc_params) { 11961 ast_free(tmp); 11962 return NULL; 11963 } 11964 ast_mutex_init(&tmp->lock); 11965 ifcount++; 11966 for (x = 0; x < 3; x++) 11967 tmp->subs[x].dfd = -1; 11968 tmp->channel = channel; 11969 tmp->priindication_oob = conf->chan.priindication_oob; 11970 } 11971 11972 if (tmp) { 11973 int chan_sig = conf->chan.sig; 11974 11975 if (!here) { 11976 /* Can only get here if this is a new channel interface being created. */ 11977 if ((channel != CHAN_PSEUDO)) { 11978 int count = 0; 11979 11980 snprintf(fn, sizeof(fn), "%d", channel); 11981 /* Open non-blocking */ 11982 tmp->subs[SUB_REAL].dfd = dahdi_open(fn); 11983 while (tmp->subs[SUB_REAL].dfd < 0 && reloading == 2 && count < 1000) { /* the kernel may not call dahdi_release fast enough for the open flagbit to be cleared in time */ 11984 usleep(1); 11985 tmp->subs[SUB_REAL].dfd = dahdi_open(fn); 11986 count++; 11987 } 11988 /* Allocate a DAHDI structure */ 11989 if (tmp->subs[SUB_REAL].dfd < 0) { 11990 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); 11991 destroy_dahdi_pvt(tmp); 11992 return NULL; 11993 } 11994 memset(&p, 0, sizeof(p)); 11995 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 11996 if (res < 0) { 11997 ast_log(LOG_ERROR, "Unable to get parameters: %s\n", strerror(errno)); 11998 destroy_dahdi_pvt(tmp); 11999 return NULL; 12000 } 12001 if (conf->is_sig_auto) 12002 chan_sig = sigtype_to_signalling(p.sigtype); 12003 if (p.sigtype != (chan_sig & 0x3ffff)) { 12004 ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(chan_sig), sig2str(p.sigtype)); 12005 destroy_dahdi_pvt(tmp); 12006 return NULL; 12007 } 12008 tmp->law_default = p.curlaw; 12009 tmp->law = p.curlaw; 12010 tmp->span = p.spanno; 12011 span = p.spanno - 1; 12012 } else { 12013 chan_sig = 0; 12014 } 12015 tmp->sig = chan_sig; 12016 tmp->outsigmod = conf->chan.outsigmod; 12017 12018 if (analog_lib_handles(chan_sig, tmp->radio, tmp->oprmode)) { 12019 analog_p = analog_new(dahdisig_to_analogsig(chan_sig), &dahdi_analog_callbacks, tmp); 12020 if (!analog_p) { 12021 destroy_dahdi_pvt(tmp); 12022 return NULL; 12023 } 12024 tmp->sig_pvt = analog_p; 12025 } 12026 #if defined(HAVE_SS7) 12027 if (chan_sig == SIG_SS7) { 12028 struct dahdi_ss7 *ss7; 12029 int clear = 0; 12030 12031 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &clear)) { 12032 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 12033 destroy_dahdi_pvt(tmp); 12034 return NULL; 12035 } 12036 12037 ss7 = ss7_resolve_linkset(cur_linkset); 12038 if (!ss7) { 12039 ast_log(LOG_ERROR, "Unable to find linkset %d\n", cur_linkset); 12040 destroy_dahdi_pvt(tmp); 12041 return NULL; 12042 } 12043 ss7->ss7.span = cur_linkset; 12044 if (cur_cicbeginswith < 0) { 12045 ast_log(LOG_ERROR, "Need to set cicbeginswith for the channels!\n"); 12046 destroy_dahdi_pvt(tmp); 12047 return NULL; 12048 } 12049 ss7_chan = sig_ss7_chan_new(tmp, &dahdi_ss7_callbacks, &ss7->ss7); 12050 if (!ss7_chan) { 12051 destroy_dahdi_pvt(tmp); 12052 return NULL; 12053 } 12054 tmp->sig_pvt = ss7_chan; 12055 tmp->ss7 = &ss7->ss7; 12056 12057 ss7_chan->channel = tmp->channel; 12058 ss7_chan->cic = cur_cicbeginswith++; 12059 12060 /* DB: Add CIC's DPC information */ 12061 ss7_chan->dpc = cur_defaultdpc; 12062 12063 ss7->ss7.pvts[ss7->ss7.numchans++] = ss7_chan; 12064 12065 ast_copy_string(ss7->ss7.internationalprefix, conf->ss7.ss7.internationalprefix, sizeof(ss7->ss7.internationalprefix)); 12066 ast_copy_string(ss7->ss7.nationalprefix, conf->ss7.ss7.nationalprefix, sizeof(ss7->ss7.nationalprefix)); 12067 ast_copy_string(ss7->ss7.subscriberprefix, conf->ss7.ss7.subscriberprefix, sizeof(ss7->ss7.subscriberprefix)); 12068 ast_copy_string(ss7->ss7.unknownprefix, conf->ss7.ss7.unknownprefix, sizeof(ss7->ss7.unknownprefix)); 12069 12070 ss7->ss7.called_nai = conf->ss7.ss7.called_nai; 12071 ss7->ss7.calling_nai = conf->ss7.ss7.calling_nai; 12072 } 12073 #endif /* defined(HAVE_SS7) */ 12074 #ifdef HAVE_OPENR2 12075 if (chan_sig == SIG_MFCR2) { 12076 struct dahdi_mfcr2 *r2_link; 12077 r2_link = dahdi_r2_get_link(); 12078 if (!r2_link) { 12079 ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n"); 12080 destroy_dahdi_pvt(tmp); 12081 return NULL; 12082 } 12083 if (!r2_link->protocol_context && dahdi_r2_set_context(r2_link, conf)) { 12084 ast_log(LOG_ERROR, "Cannot create OpenR2 protocol context.\n"); 12085 destroy_dahdi_pvt(tmp); 12086 return NULL; 12087 } 12088 if (r2_link->numchans == ARRAY_LEN(r2_link->pvts)) { 12089 ast_log(LOG_ERROR, "Cannot add more channels to this link!\n"); 12090 destroy_dahdi_pvt(tmp); 12091 return NULL; 12092 } 12093 r2_link->pvts[r2_link->numchans++] = tmp; 12094 tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context, 12095 tmp->subs[SUB_REAL].dfd, 12096 NULL, NULL); 12097 if (!tmp->r2chan) { 12098 openr2_liberr_t err = openr2_context_get_last_error(r2_link->protocol_context); 12099 ast_log(LOG_ERROR, "Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err)); 12100 destroy_dahdi_pvt(tmp); 12101 return NULL; 12102 } 12103 tmp->mfcr2 = r2_link; 12104 if (conf->mfcr2.call_files) { 12105 openr2_chan_enable_call_files(tmp->r2chan); 12106 } 12107 openr2_chan_set_client_data(tmp->r2chan, tmp); 12108 /* cast seems to be needed to get rid of the annoying warning regarding format attribute */ 12109 openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log); 12110 openr2_chan_set_log_level(tmp->r2chan, conf->mfcr2.loglevel); 12111 tmp->mfcr2_category = conf->mfcr2.category; 12112 tmp->mfcr2_charge_calls = conf->mfcr2.charge_calls; 12113 tmp->mfcr2_allow_collect_calls = conf->mfcr2.allow_collect_calls; 12114 tmp->mfcr2_forced_release = conf->mfcr2.forced_release; 12115 tmp->mfcr2_accept_on_offer = conf->mfcr2.accept_on_offer; 12116 tmp->mfcr2call = 0; 12117 tmp->mfcr2_dnis_index = 0; 12118 tmp->mfcr2_ani_index = 0; 12119 r2_link->monitored_count++; 12120 } 12121 #endif 12122 #ifdef HAVE_PRI 12123 if (dahdi_sig_pri_lib_handles(chan_sig)) { 12124 int offset; 12125 int matchesdchan; 12126 int x,y; 12127 int myswitchtype = 0; 12128 12129 offset = 0; 12130 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &offset)) { 12131 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 12132 destroy_dahdi_pvt(tmp); 12133 return NULL; 12134 } 12135 if (span >= NUM_SPANS) { 12136 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 12137 destroy_dahdi_pvt(tmp); 12138 return NULL; 12139 } else { 12140 si.spanno = 0; 12141 if (ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SPANSTAT,&si) == -1) { 12142 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 12143 destroy_dahdi_pvt(tmp); 12144 return NULL; 12145 } 12146 /* Store the logical span first based upon the real span */ 12147 tmp->logicalspan = pris[span].prilogicalspan; 12148 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 12149 if (span < 0) { 12150 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 12151 destroy_dahdi_pvt(tmp); 12152 return NULL; 12153 } 12154 myswitchtype = conf->pri.pri.switchtype; 12155 /* Make sure this isn't a d-channel */ 12156 matchesdchan=0; 12157 for (x = 0; x < NUM_SPANS; x++) { 12158 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 12159 if (pris[x].dchannels[y] == tmp->channel) { 12160 matchesdchan = 1; 12161 break; 12162 } 12163 } 12164 } 12165 if (!matchesdchan) { 12166 if (pris[span].pri.nodetype && (pris[span].pri.nodetype != conf->pri.pri.nodetype)) { 12167 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].pri.nodetype)); 12168 destroy_dahdi_pvt(tmp); 12169 return NULL; 12170 } 12171 if (pris[span].pri.switchtype && (pris[span].pri.switchtype != myswitchtype)) { 12172 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].pri.switchtype)); 12173 destroy_dahdi_pvt(tmp); 12174 return NULL; 12175 } 12176 if ((pris[span].pri.dialplan) && (pris[span].pri.dialplan != conf->pri.pri.dialplan)) { 12177 ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, pris[span].pri.dialplan == -1 ? "Dynamically set dialplan in ISDN" : pri_plan2str(pris[span].pri.dialplan)); 12178 destroy_dahdi_pvt(tmp); 12179 return NULL; 12180 } 12181 if (!ast_strlen_zero(pris[span].pri.idledial) && strcmp(pris[span].pri.idledial, conf->pri.pri.idledial)) { 12182 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.pri.idledial); 12183 destroy_dahdi_pvt(tmp); 12184 return NULL; 12185 } 12186 if (!ast_strlen_zero(pris[span].pri.idleext) && strcmp(pris[span].pri.idleext, conf->pri.pri.idleext)) { 12187 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.pri.idleext); 12188 destroy_dahdi_pvt(tmp); 12189 return NULL; 12190 } 12191 if (pris[span].pri.minunused && (pris[span].pri.minunused != conf->pri.pri.minunused)) { 12192 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.pri.minunused); 12193 destroy_dahdi_pvt(tmp); 12194 return NULL; 12195 } 12196 if (pris[span].pri.minidle && (pris[span].pri.minidle != conf->pri.pri.minidle)) { 12197 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.pri.minidle); 12198 destroy_dahdi_pvt(tmp); 12199 return NULL; 12200 } 12201 if (pris[span].pri.numchans >= ARRAY_LEN(pris[span].pri.pvts)) { 12202 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 12203 pris[span].pri.trunkgroup); 12204 destroy_dahdi_pvt(tmp); 12205 return NULL; 12206 } 12207 12208 ast_debug(4, "Adding callbacks %p to chan %d\n", &dahdi_pri_callbacks, tmp->channel); 12209 pri_chan = sig_pri_chan_new(tmp, &dahdi_pri_callbacks, &pris[span].pri, tmp->logicalspan, p.chanpos, pris[span].mastertrunkgroup); 12210 if (!pri_chan) { 12211 destroy_dahdi_pvt(tmp); 12212 return NULL; 12213 } 12214 tmp->sig_pvt = pri_chan; 12215 tmp->pri = &pris[span].pri; 12216 12217 tmp->priexclusive = conf->chan.priexclusive; 12218 12219 if (!tmp->pri->cc_params) { 12220 tmp->pri->cc_params = ast_cc_config_params_init(); 12221 if (!tmp->pri->cc_params) { 12222 destroy_dahdi_pvt(tmp); 12223 return NULL; 12224 } 12225 } 12226 ast_cc_copy_config_params(tmp->pri->cc_params, 12227 conf->chan.cc_params); 12228 12229 pris[span].pri.sig = chan_sig; 12230 pris[span].pri.nodetype = conf->pri.pri.nodetype; 12231 pris[span].pri.switchtype = myswitchtype; 12232 pris[span].pri.nsf = conf->pri.pri.nsf; 12233 pris[span].pri.dialplan = conf->pri.pri.dialplan; 12234 pris[span].pri.localdialplan = conf->pri.pri.localdialplan; 12235 pris[span].pri.pvts[pris[span].pri.numchans++] = tmp->sig_pvt; 12236 pris[span].pri.minunused = conf->pri.pri.minunused; 12237 pris[span].pri.minidle = conf->pri.pri.minidle; 12238 pris[span].pri.overlapdial = conf->pri.pri.overlapdial; 12239 pris[span].pri.qsigchannelmapping = conf->pri.pri.qsigchannelmapping; 12240 pris[span].pri.discardremoteholdretrieval = conf->pri.pri.discardremoteholdretrieval; 12241 #if defined(HAVE_PRI_SERVICE_MESSAGES) 12242 pris[span].pri.enable_service_message_support = conf->pri.pri.enable_service_message_support; 12243 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 12244 #ifdef HAVE_PRI_INBANDDISCONNECT 12245 pris[span].pri.inbanddisconnect = conf->pri.pri.inbanddisconnect; 12246 #endif 12247 #if defined(HAVE_PRI_CALL_HOLD) 12248 pris[span].pri.hold_disconnect_transfer = 12249 conf->pri.pri.hold_disconnect_transfer; 12250 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 12251 #if defined(HAVE_PRI_CCSS) 12252 pris[span].pri.cc_ptmp_recall_mode = 12253 conf->pri.pri.cc_ptmp_recall_mode; 12254 pris[span].pri.cc_qsig_signaling_link_req = 12255 conf->pri.pri.cc_qsig_signaling_link_req; 12256 pris[span].pri.cc_qsig_signaling_link_rsp = 12257 conf->pri.pri.cc_qsig_signaling_link_rsp; 12258 #endif /* defined(HAVE_PRI_CCSS) */ 12259 #if defined(HAVE_PRI_CALL_WAITING) 12260 pris[span].pri.max_call_waiting_calls = 12261 conf->pri.pri.max_call_waiting_calls; 12262 pris[span].pri.allow_call_waiting_calls = 12263 conf->pri.pri.allow_call_waiting_calls; 12264 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 12265 pris[span].pri.transfer = conf->chan.transfer; 12266 pris[span].pri.facilityenable = conf->pri.pri.facilityenable; 12267 #if defined(HAVE_PRI_AOC_EVENTS) 12268 pris[span].pri.aoc_passthrough_flag = conf->pri.pri.aoc_passthrough_flag; 12269 pris[span].pri.aoce_delayhangup = conf->pri.pri.aoce_delayhangup; 12270 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 12271 pris[span].pri.append_msn_to_user_tag = conf->pri.pri.append_msn_to_user_tag; 12272 ast_copy_string(pris[span].pri.initial_user_tag, conf->chan.cid_tag, sizeof(pris[span].pri.initial_user_tag)); 12273 ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list)); 12274 #if defined(HAVE_PRI_MWI) 12275 ast_copy_string(pris[span].pri.mwi_mailboxes, 12276 conf->pri.pri.mwi_mailboxes, 12277 sizeof(pris[span].pri.mwi_mailboxes)); 12278 #endif /* defined(HAVE_PRI_MWI) */ 12279 ast_copy_string(pris[span].pri.idledial, conf->pri.pri.idledial, sizeof(pris[span].pri.idledial)); 12280 ast_copy_string(pris[span].pri.idleext, conf->pri.pri.idleext, sizeof(pris[span].pri.idleext)); 12281 ast_copy_string(pris[span].pri.internationalprefix, conf->pri.pri.internationalprefix, sizeof(pris[span].pri.internationalprefix)); 12282 ast_copy_string(pris[span].pri.nationalprefix, conf->pri.pri.nationalprefix, sizeof(pris[span].pri.nationalprefix)); 12283 ast_copy_string(pris[span].pri.localprefix, conf->pri.pri.localprefix, sizeof(pris[span].pri.localprefix)); 12284 ast_copy_string(pris[span].pri.privateprefix, conf->pri.pri.privateprefix, sizeof(pris[span].pri.privateprefix)); 12285 ast_copy_string(pris[span].pri.unknownprefix, conf->pri.pri.unknownprefix, sizeof(pris[span].pri.unknownprefix)); 12286 pris[span].pri.resetinterval = conf->pri.pri.resetinterval; 12287 12288 for (x = 0; x < PRI_MAX_TIMERS; x++) { 12289 pris[span].pri.pritimers[x] = conf->pri.pri.pritimers[x]; 12290 } 12291 12292 #if defined(HAVE_PRI_CALL_WAITING) 12293 /* Channel initial config parameters. */ 12294 pris[span].pri.ch_cfg.stripmsd = conf->chan.stripmsd; 12295 pris[span].pri.ch_cfg.hidecallerid = conf->chan.hidecallerid; 12296 pris[span].pri.ch_cfg.hidecalleridname = conf->chan.hidecalleridname; 12297 pris[span].pri.ch_cfg.immediate = conf->chan.immediate; 12298 pris[span].pri.ch_cfg.priexclusive = conf->chan.priexclusive; 12299 pris[span].pri.ch_cfg.priindication_oob = conf->chan.priindication_oob; 12300 pris[span].pri.ch_cfg.use_callerid = conf->chan.use_callerid; 12301 pris[span].pri.ch_cfg.use_callingpres = conf->chan.use_callingpres; 12302 ast_copy_string(pris[span].pri.ch_cfg.context, conf->chan.context, sizeof(pris[span].pri.ch_cfg.context)); 12303 ast_copy_string(pris[span].pri.ch_cfg.mohinterpret, conf->chan.mohinterpret, sizeof(pris[span].pri.ch_cfg.mohinterpret)); 12304 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 12305 } else { 12306 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", p.chanpos); 12307 destroy_dahdi_pvt(tmp); 12308 return NULL; 12309 } 12310 } 12311 } 12312 #endif 12313 } else { 12314 /* already exists in interface list */ 12315 ast_log(LOG_WARNING, "Attempt to configure channel %d with signaling %s ignored because it is already configured to be %s.\n", tmp->channel, dahdi_sig2str(chan_sig), dahdi_sig2str(tmp->sig)); 12316 chan_sig = tmp->sig; 12317 if (tmp->subs[SUB_REAL].dfd > -1) { 12318 memset(&p, 0, sizeof(p)); 12319 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 12320 } 12321 } 12322 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 12323 switch (chan_sig) { 12324 case SIG_FXSKS: 12325 case SIG_FXSLS: 12326 case SIG_EM: 12327 case SIG_EM_E1: 12328 case SIG_EMWINK: 12329 case SIG_FEATD: 12330 case SIG_FEATDMF: 12331 case SIG_FEATDMF_TA: 12332 case SIG_FEATB: 12333 case SIG_E911: 12334 case SIG_SF: 12335 case SIG_SFWINK: 12336 case SIG_FGC_CAMA: 12337 case SIG_FGC_CAMAMF: 12338 case SIG_SF_FEATD: 12339 case SIG_SF_FEATDMF: 12340 case SIG_SF_FEATB: 12341 p.starttime = 250; 12342 break; 12343 } 12344 12345 if (tmp->radio) { 12346 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 12347 p.channo = channel; 12348 p.rxwinktime = 1; 12349 p.rxflashtime = 1; 12350 p.starttime = 1; 12351 p.debouncetime = 5; 12352 } else { 12353 p.channo = channel; 12354 /* Override timing settings based on config file */ 12355 if (conf->timing.prewinktime >= 0) 12356 p.prewinktime = conf->timing.prewinktime; 12357 if (conf->timing.preflashtime >= 0) 12358 p.preflashtime = conf->timing.preflashtime; 12359 if (conf->timing.winktime >= 0) 12360 p.winktime = conf->timing.winktime; 12361 if (conf->timing.flashtime >= 0) 12362 p.flashtime = conf->timing.flashtime; 12363 if (conf->timing.starttime >= 0) 12364 p.starttime = conf->timing.starttime; 12365 if (conf->timing.rxwinktime >= 0) 12366 p.rxwinktime = conf->timing.rxwinktime; 12367 if (conf->timing.rxflashtime >= 0) 12368 p.rxflashtime = conf->timing.rxflashtime; 12369 if (conf->timing.debouncetime >= 0) 12370 p.debouncetime = conf->timing.debouncetime; 12371 } 12372 12373 /* don't set parms on a pseudo-channel */ 12374 if (tmp->subs[SUB_REAL].dfd >= 0) 12375 { 12376 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_PARAMS, &p); 12377 if (res < 0) { 12378 ast_log(LOG_ERROR, "Unable to set parameters: %s\n", strerror(errno)); 12379 destroy_dahdi_pvt(tmp); 12380 return NULL; 12381 } 12382 } 12383 #if 1 12384 if (!here && (tmp->subs[SUB_REAL].dfd > -1)) { 12385 memset(&bi, 0, sizeof(bi)); 12386 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi); 12387 if (!res) { 12388 bi.txbufpolicy = conf->chan.buf_policy; 12389 bi.rxbufpolicy = conf->chan.buf_policy; 12390 bi.numbufs = conf->chan.buf_no; 12391 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi); 12392 if (res < 0) { 12393 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", channel, strerror(errno)); 12394 } 12395 } else { 12396 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", channel, strerror(errno)); 12397 } 12398 tmp->buf_policy = conf->chan.buf_policy; 12399 tmp->buf_no = conf->chan.buf_no; 12400 tmp->usefaxbuffers = conf->chan.usefaxbuffers; 12401 tmp->faxbuf_policy = conf->chan.faxbuf_policy; 12402 tmp->faxbuf_no = conf->chan.faxbuf_no; 12403 /* This is not as gnarly as it may first appear. If the ioctl above failed, we'd be setting 12404 * tmp->bufsize to zero which would cause subsequent faxbuffer-related ioctl calls to fail. 12405 * The reason the ioctl call above failed should to be determined before worrying about the 12406 * faxbuffer-related ioctl calls */ 12407 tmp->bufsize = bi.bufsize; 12408 } 12409 #endif 12410 tmp->immediate = conf->chan.immediate; 12411 tmp->transfertobusy = conf->chan.transfertobusy; 12412 if (chan_sig & __DAHDI_SIG_FXS) { 12413 tmp->mwimonitor_fsk = conf->chan.mwimonitor_fsk; 12414 tmp->mwimonitor_neon = conf->chan.mwimonitor_neon; 12415 tmp->mwimonitor_rpas = conf->chan.mwimonitor_rpas; 12416 } 12417 tmp->ringt_base = ringt_base; 12418 tmp->firstradio = 0; 12419 if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS)) 12420 tmp->permcallwaiting = conf->chan.callwaiting; 12421 else 12422 tmp->permcallwaiting = 0; 12423 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 12424 tmp->destroy = 0; 12425 tmp->drings = conf->chan.drings; 12426 12427 /* 10 is a nice default. */ 12428 if (tmp->drings.ringnum[0].range == 0) 12429 tmp->drings.ringnum[0].range = 10; 12430 if (tmp->drings.ringnum[1].range == 0) 12431 tmp->drings.ringnum[1].range = 10; 12432 if (tmp->drings.ringnum[2].range == 0) 12433 tmp->drings.ringnum[2].range = 10; 12434 12435 tmp->usedistinctiveringdetection = usedistinctiveringdetection; 12436 tmp->callwaitingcallerid = conf->chan.callwaitingcallerid; 12437 tmp->threewaycalling = conf->chan.threewaycalling; 12438 tmp->adsi = conf->chan.adsi; 12439 tmp->use_smdi = conf->chan.use_smdi; 12440 tmp->permhidecallerid = conf->chan.hidecallerid; 12441 tmp->hidecalleridname = conf->chan.hidecalleridname; 12442 tmp->callreturn = conf->chan.callreturn; 12443 tmp->echocancel = conf->chan.echocancel; 12444 tmp->echotraining = conf->chan.echotraining; 12445 tmp->pulse = conf->chan.pulse; 12446 if (tmp->echocancel.head.tap_length) { 12447 tmp->echocanbridged = conf->chan.echocanbridged; 12448 } else { 12449 if (conf->chan.echocanbridged) 12450 ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n"); 12451 tmp->echocanbridged = 0; 12452 } 12453 tmp->busydetect = conf->chan.busydetect; 12454 tmp->busycount = conf->chan.busycount; 12455 tmp->busycompare = conf->chan.busycompare; 12456 tmp->busytonelength = conf->chan.busytonelength; 12457 tmp->busyquietlength = conf->chan.busyquietlength; 12458 tmp->busyfuzziness = conf->chan.busyfuzziness; 12459 tmp->silencethreshold = conf->chan.silencethreshold; 12460 tmp->callprogress = conf->chan.callprogress; 12461 tmp->waitfordialtone = conf->chan.waitfordialtone; 12462 tmp->cancallforward = conf->chan.cancallforward; 12463 tmp->dtmfrelax = conf->chan.dtmfrelax; 12464 tmp->callwaiting = tmp->permcallwaiting; 12465 tmp->hidecallerid = tmp->permhidecallerid; 12466 tmp->channel = channel; 12467 tmp->stripmsd = conf->chan.stripmsd; 12468 tmp->use_callerid = conf->chan.use_callerid; 12469 tmp->cid_signalling = conf->chan.cid_signalling; 12470 tmp->cid_start = conf->chan.cid_start; 12471 tmp->dahditrcallerid = conf->chan.dahditrcallerid; 12472 tmp->restrictcid = conf->chan.restrictcid; 12473 tmp->use_callingpres = conf->chan.use_callingpres; 12474 if (tmp->usedistinctiveringdetection) { 12475 if (!tmp->use_callerid) { 12476 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 12477 tmp->use_callerid = 1; 12478 } 12479 } 12480 12481 if (tmp->cid_signalling == CID_SIG_SMDI) { 12482 if (!tmp->use_smdi) { 12483 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n"); 12484 tmp->use_smdi = 1; 12485 } 12486 } 12487 if (tmp->use_smdi) { 12488 tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port); 12489 if (!(tmp->smdi_iface)) { 12490 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n"); 12491 tmp->use_smdi = 0; 12492 } 12493 } 12494 12495 ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode)); 12496 tmp->amaflags = conf->chan.amaflags; 12497 if (!here) { 12498 tmp->confno = -1; 12499 tmp->propconfno = -1; 12500 } 12501 tmp->canpark = conf->chan.canpark; 12502 tmp->transfer = conf->chan.transfer; 12503 ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext)); 12504 ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language)); 12505 ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret)); 12506 ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest)); 12507 ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context)); 12508 ast_copy_string(tmp->parkinglot, conf->chan.parkinglot, sizeof(tmp->parkinglot)); 12509 tmp->cid_ton = 0; 12510 if (analog_lib_handles(tmp->sig, tmp->radio, tmp->oprmode)) { 12511 ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num)); 12512 ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name)); 12513 } else { 12514 tmp->cid_num[0] = '\0'; 12515 tmp->cid_name[0] = '\0'; 12516 } 12517 #if defined(HAVE_PRI) 12518 if (dahdi_sig_pri_lib_handles(tmp->sig)) { 12519 tmp->cid_tag[0] = '\0'; 12520 } else 12521 #endif /* defined(HAVE_PRI) */ 12522 { 12523 ast_copy_string(tmp->cid_tag, conf->chan.cid_tag, sizeof(tmp->cid_tag)); 12524 } 12525 tmp->cid_subaddr[0] = '\0'; 12526 ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox)); 12527 if (channel != CHAN_PSEUDO && !ast_strlen_zero(tmp->mailbox)) { 12528 char *mailbox, *context; 12529 mailbox = context = ast_strdupa(tmp->mailbox); 12530 strsep(&context, "@"); 12531 if (ast_strlen_zero(context)) 12532 context = "default"; 12533 tmp->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "Dahdi MWI subscription", NULL, 12534 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12535 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12536 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS, 12537 AST_EVENT_IE_END); 12538 } 12539 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 12540 tmp->mwisend_setting = conf->chan.mwisend_setting; 12541 tmp->mwisend_fsk = conf->chan.mwisend_fsk; 12542 tmp->mwisend_rpas = conf->chan.mwisend_rpas; 12543 #endif 12544 12545 tmp->group = conf->chan.group; 12546 tmp->callgroup = conf->chan.callgroup; 12547 tmp->pickupgroup= conf->chan.pickupgroup; 12548 if (conf->chan.vars) { 12549 struct ast_variable *v, *tmpvar; 12550 for (v = conf->chan.vars ; v ; v = v->next) { 12551 if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 12552 tmpvar->next = tmp->vars; 12553 tmp->vars = tmpvar; 12554 } 12555 } 12556 } 12557 tmp->cid_rxgain = conf->chan.cid_rxgain; 12558 tmp->rxgain = conf->chan.rxgain; 12559 tmp->txgain = conf->chan.txgain; 12560 tmp->txdrc = conf->chan.txdrc; 12561 tmp->rxdrc = conf->chan.rxdrc; 12562 tmp->tonezone = conf->chan.tonezone; 12563 if (tmp->subs[SUB_REAL].dfd > -1) { 12564 set_actual_gain(tmp->subs[SUB_REAL].dfd, tmp->rxgain, tmp->txgain, tmp->rxdrc, tmp->txdrc, tmp->law); 12565 if (tmp->dsp) 12566 ast_dsp_set_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 12567 update_conf(tmp); 12568 if (!here) { 12569 switch (chan_sig) { 12570 case SIG_PRI_LIB_HANDLE_CASES: 12571 case SIG_SS7: 12572 case SIG_MFCR2: 12573 break; 12574 default: 12575 /* Hang it up to be sure it's good */ 12576 dahdi_set_hook(tmp->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 12577 break; 12578 } 12579 } 12580 ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SETTONEZONE,&tmp->tonezone); 12581 #ifdef HAVE_PRI 12582 memset(&si, 0, sizeof(si)); 12583 if (ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SPANSTAT,&si) == -1) { 12584 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 12585 destroy_dahdi_pvt(tmp); 12586 return NULL; 12587 } 12588 #endif 12589 if ((res = get_alarms(tmp)) != DAHDI_ALARM_NONE) { 12590 /* the dchannel is down so put the channel in alarm */ 12591 switch (tmp->sig) { 12592 #ifdef HAVE_PRI 12593 case SIG_PRI_LIB_HANDLE_CASES: 12594 sig_pri_chan_alarm_notify(tmp->sig_pvt, si.alarms); 12595 break; 12596 #endif 12597 #if defined(HAVE_SS7) 12598 case SIG_SS7: 12599 sig_ss7_set_alarm(tmp->sig_pvt, 1); 12600 break; 12601 #endif /* defined(HAVE_SS7) */ 12602 default: 12603 /* The only sig submodule left should be sig_analog. */ 12604 analog_p = tmp->sig_pvt; 12605 if (analog_p) { 12606 analog_p->inalarm = 1; 12607 } 12608 tmp->inalarm = 1; 12609 break; 12610 } 12611 handle_alarms(tmp, res); 12612 } 12613 } 12614 12615 tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay; 12616 tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch; 12617 tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch; 12618 tmp->sendcalleridafter = conf->chan.sendcalleridafter; 12619 ast_cc_copy_config_params(tmp->cc_params, conf->chan.cc_params); 12620 12621 if (!here) { 12622 tmp->locallyblocked = 0; 12623 tmp->remotelyblocked = 0; 12624 switch (tmp->sig) { 12625 #if defined(HAVE_PRI) 12626 case SIG_PRI_LIB_HANDLE_CASES: 12627 tmp->inservice = 1;/* Inservice until actually implemented. */ 12628 #if defined(HAVE_PRI_SERVICE_MESSAGES) 12629 ((struct sig_pri_chan *) tmp->sig_pvt)->service_status = 0; 12630 if (chan_sig == SIG_PRI) { 12631 char db_chan_name[20]; 12632 char db_answer[5]; 12633 12634 /* 12635 * Initialize the active out-of-service status 12636 * and delete any record if the feature is not enabled. 12637 */ 12638 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, tmp->span, tmp->channel); 12639 if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) { 12640 unsigned *why; 12641 12642 why = &((struct sig_pri_chan *) tmp->sig_pvt)->service_status; 12643 if (tmp->pri->enable_service_message_support) { 12644 char state; 12645 12646 sscanf(db_answer, "%1c:%30u", &state, why); 12647 12648 /* Ensure that only the implemented bits could be set.*/ 12649 *why &= (SRVST_NEAREND | SRVST_FAREND); 12650 } 12651 if (!*why) { 12652 ast_db_del(db_chan_name, SRVST_DBKEY); 12653 } 12654 } 12655 } 12656 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 12657 break; 12658 #endif /* defined(HAVE_PRI) */ 12659 #if defined(HAVE_SS7) 12660 case SIG_SS7: 12661 tmp->inservice = 0; 12662 break; 12663 #endif /* defined(HAVE_SS7) */ 12664 default: 12665 /* We default to in service on protocols that don't have a reset */ 12666 tmp->inservice = 1; 12667 break; 12668 } 12669 } 12670 12671 switch (tmp->sig) { 12672 #if defined(HAVE_PRI) 12673 case SIG_PRI_LIB_HANDLE_CASES: 12674 if (pri_chan) { 12675 pri_chan->channel = tmp->channel; 12676 pri_chan->hidecallerid = tmp->hidecallerid; 12677 pri_chan->hidecalleridname = tmp->hidecalleridname; 12678 pri_chan->immediate = tmp->immediate; 12679 pri_chan->inalarm = tmp->inalarm; 12680 pri_chan->priexclusive = tmp->priexclusive; 12681 pri_chan->priindication_oob = tmp->priindication_oob; 12682 pri_chan->use_callerid = tmp->use_callerid; 12683 pri_chan->use_callingpres = tmp->use_callingpres; 12684 ast_copy_string(pri_chan->context, tmp->context, 12685 sizeof(pri_chan->context)); 12686 ast_copy_string(pri_chan->mohinterpret, tmp->mohinterpret, 12687 sizeof(pri_chan->mohinterpret)); 12688 pri_chan->stripmsd = tmp->stripmsd; 12689 } 12690 break; 12691 #endif /* defined(HAVE_PRI) */ 12692 #if defined(HAVE_SS7) 12693 case SIG_SS7: 12694 if (ss7_chan) { 12695 ss7_chan->inalarm = tmp->inalarm; 12696 12697 ss7_chan->stripmsd = tmp->stripmsd; 12698 ss7_chan->hidecallerid = tmp->hidecallerid; 12699 ss7_chan->use_callerid = tmp->use_callerid; 12700 ss7_chan->use_callingpres = tmp->use_callingpres; 12701 ss7_chan->immediate = tmp->immediate; 12702 ss7_chan->locallyblocked = tmp->locallyblocked; 12703 ss7_chan->remotelyblocked = tmp->remotelyblocked; 12704 ast_copy_string(ss7_chan->context, tmp->context, 12705 sizeof(ss7_chan->context)); 12706 ast_copy_string(ss7_chan->mohinterpret, tmp->mohinterpret, 12707 sizeof(ss7_chan->mohinterpret)); 12708 } 12709 break; 12710 #endif /* defined(HAVE_SS7) */ 12711 default: 12712 /* The only sig submodule left should be sig_analog. */ 12713 analog_p = tmp->sig_pvt; 12714 if (analog_p) { 12715 analog_p->channel = tmp->channel; 12716 analog_p->polarityonanswerdelay = conf->chan.polarityonanswerdelay; 12717 analog_p->answeronpolarityswitch = conf->chan.answeronpolarityswitch; 12718 analog_p->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch; 12719 analog_p->permcallwaiting = conf->chan.callwaiting; /* permcallwaiting possibly modified in analog_config_complete */ 12720 analog_p->callreturn = conf->chan.callreturn; 12721 analog_p->cancallforward = conf->chan.cancallforward; 12722 analog_p->canpark = conf->chan.canpark; 12723 analog_p->dahditrcallerid = conf->chan.dahditrcallerid; 12724 analog_p->immediate = conf->chan.immediate; 12725 analog_p->permhidecallerid = conf->chan.permhidecallerid; 12726 analog_p->pulse = conf->chan.pulse; 12727 analog_p->threewaycalling = conf->chan.threewaycalling; 12728 analog_p->transfer = conf->chan.transfer; 12729 analog_p->transfertobusy = conf->chan.transfertobusy; 12730 analog_p->use_callerid = tmp->use_callerid; 12731 analog_p->use_smdi = tmp->use_smdi; 12732 analog_p->smdi_iface = tmp->smdi_iface; 12733 analog_p->outsigmod = ANALOG_SIG_NONE; 12734 analog_p->echotraining = conf->chan.echotraining; 12735 analog_p->cid_signalling = conf->chan.cid_signalling; 12736 analog_p->stripmsd = conf->chan.stripmsd; 12737 switch (conf->chan.cid_start) { 12738 case CID_START_POLARITY: 12739 analog_p->cid_start = ANALOG_CID_START_POLARITY; 12740 break; 12741 case CID_START_POLARITY_IN: 12742 analog_p->cid_start = ANALOG_CID_START_POLARITY_IN; 12743 break; 12744 case CID_START_DTMF_NOALERT: 12745 analog_p->cid_start = ANALOG_CID_START_DTMF_NOALERT; 12746 break; 12747 default: 12748 analog_p->cid_start = ANALOG_CID_START_RING; 12749 break; 12750 } 12751 analog_p->callwaitingcallerid = conf->chan.callwaitingcallerid; 12752 analog_p->ringt = conf->chan.ringt; 12753 analog_p->ringt_base = ringt_base; 12754 analog_p->chan_tech = &dahdi_tech; 12755 analog_p->onhooktime = time(NULL); 12756 if (chan_sig & __DAHDI_SIG_FXO) { 12757 memset(&p, 0, sizeof(p)); 12758 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 12759 if (!res) { 12760 analog_p->fxsoffhookstate = p.rxisoffhook; 12761 } 12762 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 12763 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting); 12764 #endif 12765 } 12766 analog_p->msgstate = -1; 12767 12768 ast_copy_string(analog_p->mohsuggest, conf->chan.mohsuggest, sizeof(analog_p->mohsuggest)); 12769 ast_copy_string(analog_p->cid_num, conf->chan.cid_num, sizeof(analog_p->cid_num)); 12770 ast_copy_string(analog_p->cid_name, conf->chan.cid_name, sizeof(analog_p->cid_name)); 12771 12772 analog_config_complete(analog_p); 12773 } 12774 break; 12775 } 12776 #if defined(HAVE_PRI) 12777 if (tmp->channel == CHAN_PSEUDO) { 12778 /* 12779 * Save off pseudo channel buffer policy values for dynamic creation of 12780 * no B channel interfaces. 12781 */ 12782 dahdi_pseudo_parms.buf_no = tmp->buf_no; 12783 dahdi_pseudo_parms.buf_policy = tmp->buf_policy; 12784 dahdi_pseudo_parms.faxbuf_no = tmp->faxbuf_no; 12785 dahdi_pseudo_parms.faxbuf_policy = tmp->faxbuf_policy; 12786 } 12787 #endif /* defined(HAVE_PRI) */ 12788 } 12789 if (tmp && !here) { 12790 /* Add the new channel interface to the sorted channel interface list. */ 12791 dahdi_iflist_insert(tmp); 12792 } 12793 return tmp; 12794 }
static void mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 460 of file chan_dahdi.c.
Referenced by add_peer_mwi_subs(), build_peer(), config_line(), and skinny_register().
00461 { 00462 /* This module does not handle MWI in an event-based manner. However, it 00463 * subscribes to MWI for each mailbox that is configured so that the core 00464 * knows that we care about it. Then, chan_dahdi will get the MWI from the 00465 * event cache instead of checking the mailbox directly. */ 00466 }
static int mwi_send_init | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 10860 of file chan_dahdi.c.
References ast_callerid_vmwi_generate(), ast_calloc, ast_free, AST_LAW, ast_log(), CID_MWI_TYPE_MDMF_FULL, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, has_voicemail(), MAX_CALLERID_SIZE, MWI_SEND_SA, MWI_SEND_SPILL, mwisend_info::mwisend_current, dahdi_pvt::mwisend_data, dahdi_pvt::mwisend_fsk, dahdi_pvt::mwisend_rpas, dahdi_pvt::mwisendactive, SUB_REAL, and dahdi_pvt::subs.
10861 { 10862 int x, res; 10863 10864 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 10865 /* Determine how this spill is to be sent */ 10866 if (pvt->mwisend_rpas) { 10867 pvt->mwisend_data.mwisend_current = MWI_SEND_SA; 10868 pvt->mwisendactive = 1; 10869 } else if (pvt->mwisend_fsk) { 10870 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 10871 pvt->mwisendactive = 1; 10872 } else { 10873 pvt->mwisendactive = 0; 10874 return 0; 10875 } 10876 #else 10877 if (mwisend_rpas) { 10878 pvt->mwisend_data.mwisend_current = MWI_SEND_SA; 10879 } else { 10880 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 10881 } 10882 pvt->mwisendactive = 1; 10883 #endif 10884 10885 if (pvt->cidspill) { 10886 ast_log(LOG_WARNING, "cidspill already exists when trying to send FSK MWI\n"); 10887 ast_free(pvt->cidspill); 10888 pvt->cidspill = NULL; 10889 pvt->cidpos = 0; 10890 pvt->cidlen = 0; 10891 } 10892 pvt->cidspill = ast_calloc(1, MAX_CALLERID_SIZE); 10893 if (!pvt->cidspill) { 10894 pvt->mwisendactive = 0; 10895 return -1; 10896 } 10897 x = DAHDI_FLUSH_BOTH; 10898 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x); 10899 x = 3000; 10900 ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_ONHOOKTRANSFER, &x); 10901 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 10902 if (pvt->mwisend_fsk) { 10903 #endif 10904 pvt->cidlen = ast_callerid_vmwi_generate(pvt->cidspill, has_voicemail(pvt), CID_MWI_TYPE_MDMF_FULL, 10905 AST_LAW(pvt), pvt->cid_name, pvt->cid_num, 0); 10906 pvt->cidpos = 0; 10907 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 10908 } 10909 #endif 10910 return 0; 10911 }
static int mwi_send_process_buffer | ( | struct dahdi_pvt * | pvt, | |
int | num_read | |||
) | [static] |
Definition at line 10913 of file chan_dahdi.c.
References AS_RP_cadence, ast_free, ast_log(), dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, dahdi_set_hook(), errno, MWI_SEND_CLEANUP, MWI_SEND_DONE, MWI_SEND_PAUSE, MWI_SEND_SA, MWI_SEND_SA_WAIT, MWI_SEND_SPILL, mwisend_info::mwisend_current, dahdi_pvt::mwisend_data, dahdi_pvt::mwisend_fsk, dahdi_pvt::mwisendactive, mwisend_info::pause, SUB_REAL, and dahdi_pvt::subs.
10914 { 10915 struct timeval now; 10916 int res; 10917 10918 /* sanity check to catch if this had been interrupted previously 10919 * i.e. state says there is more to do but there is no spill allocated 10920 */ 10921 if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current && !pvt->cidspill) { 10922 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 10923 } else if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) { 10924 /* Normal processing -- Perform mwi send action */ 10925 switch ( pvt->mwisend_data.mwisend_current) { 10926 case MWI_SEND_SA: 10927 /* Send the Ring Pulse Signal Alert */ 10928 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &AS_RP_cadence); 10929 if (res) { 10930 ast_log(LOG_WARNING, "Unable to set RP-AS ring cadence: %s\n", strerror(errno)); 10931 goto quit; 10932 } 10933 res = dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RING); 10934 pvt->mwisend_data.mwisend_current = MWI_SEND_SA_WAIT; 10935 break; 10936 case MWI_SEND_SA_WAIT: /* do nothing until I get RINGEROFF event */ 10937 break; 10938 case MWI_SEND_PAUSE: /* Wait between alert and spill - min of 500 mS*/ 10939 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 10940 if (pvt->mwisend_fsk) { 10941 #endif 10942 gettimeofday(&now, NULL); 10943 if ((int)(now.tv_sec - pvt->mwisend_data.pause.tv_sec) * 1000000 + (int)now.tv_usec - (int)pvt->mwisend_data.pause.tv_usec > 500000) { 10944 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 10945 } 10946 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 10947 } else { /* support for mwisendtype=nofsk */ 10948 pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP; 10949 } 10950 #endif 10951 break; 10952 case MWI_SEND_SPILL: 10953 /* We read some number of bytes. Write an equal amount of data */ 10954 if(0 < num_read) { 10955 if (num_read > pvt->cidlen - pvt->cidpos) 10956 num_read = pvt->cidlen - pvt->cidpos; 10957 res = write(pvt->subs[SUB_REAL].dfd, pvt->cidspill + pvt->cidpos, num_read); 10958 if (res > 0) { 10959 pvt->cidpos += res; 10960 if (pvt->cidpos >= pvt->cidlen) { 10961 pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP; 10962 } 10963 } else { 10964 ast_log(LOG_WARNING, "MWI FSK Send Write failed: %s\n", strerror(errno)); 10965 goto quit; 10966 } 10967 } 10968 break; 10969 case MWI_SEND_CLEANUP: 10970 /* For now, do nothing */ 10971 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 10972 break; 10973 default: 10974 /* Should not get here, punt*/ 10975 goto quit; 10976 } 10977 } 10978 10979 if (MWI_SEND_DONE == pvt->mwisend_data.mwisend_current) { 10980 if (pvt->cidspill) { 10981 ast_free(pvt->cidspill); 10982 pvt->cidspill = NULL; 10983 pvt->cidpos = 0; 10984 pvt->cidlen = 0; 10985 } 10986 pvt->mwisendactive = 0; 10987 } 10988 return 0; 10989 quit: 10990 if (pvt->cidspill) { 10991 ast_free(pvt->cidspill); 10992 pvt->cidspill = NULL; 10993 pvt->cidpos = 0; 10994 pvt->cidlen = 0; 10995 } 10996 pvt->mwisendactive = 0; 10997 return -1; 10998 }
static int mwi_send_process_event | ( | struct dahdi_pvt * | pvt, | |
int | event | |||
) | [static] |
Definition at line 11000 of file chan_dahdi.c.
References ast_free, ast_log(), dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, dahdi_set_hook(), errno, MWI_SEND_DONE, MWI_SEND_PAUSE, MWI_SEND_SA_WAIT, mwisend_info::mwisend_current, dahdi_pvt::mwisend_data, dahdi_pvt::mwisendactive, mwisend_info::pause, SUB_REAL, and dahdi_pvt::subs.
11001 { 11002 int handled = 0; 11003 11004 if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) { 11005 switch (event) { 11006 case DAHDI_EVENT_RINGEROFF: 11007 if(pvt->mwisend_data.mwisend_current == MWI_SEND_SA_WAIT) { 11008 handled = 1; 11009 11010 if (dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RINGOFF) ) { 11011 ast_log(LOG_WARNING, "Unable to finish RP-AS: %s mwi send aborted\n", strerror(errno)); 11012 ast_free(pvt->cidspill); 11013 pvt->cidspill = NULL; 11014 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11015 pvt->mwisendactive = 0; 11016 } else { 11017 pvt->mwisend_data.mwisend_current = MWI_SEND_PAUSE; 11018 gettimeofday(&pvt->mwisend_data.pause, NULL); 11019 } 11020 } 11021 break; 11022 /* Going off hook, I need to punt this spill */ 11023 case DAHDI_EVENT_RINGOFFHOOK: 11024 if (pvt->cidspill) { 11025 ast_free(pvt->cidspill); 11026 pvt->cidspill = NULL; 11027 pvt->cidpos = 0; 11028 pvt->cidlen = 0; 11029 } 11030 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11031 pvt->mwisendactive = 0; 11032 break; 11033 case DAHDI_EVENT_RINGERON: 11034 case DAHDI_EVENT_HOOKCOMPLETE: 11035 break; 11036 default: 11037 break; 11038 } 11039 } 11040 return handled; 11041 }
static void* mwi_thread | ( | void * | data | ) | [static] |
Definition at line 10704 of file chan_dahdi.c.
References analog_lib_handles(), analog_ss_thread(), analog_ss_thread_start(), ast_hangup(), AST_LAW, ast_log(), ast_pthread_create_detached, AST_STATE_RING, mwi_thread_data::buf, bump_gains(), calc_energy(), callerid_feed(), callerid_free(), callerid_new(), dahdi_pvt::channel, dahdi_pvt::cid_signalling, dahdi_get_event(), dahdi_new(), errno, event2str(), get_alarms(), handle_alarms(), handle_clear_alarms(), dahdi_pvt::inalarm, analog_pvt::inalarm, mwi_thread_data::len, LOG_NOTICE, mwilevel, dahdi_pvt::mwimonitoractive, name, dahdi_pvt::oprmode, mwi_thread_data::pvt, dahdi_pvt::radio, restore_gains(), dahdi_pvt::ringt, dahdi_pvt::ringt_base, dahdi_pvt::sig, dahdi_pvt::sig_pvt, SUB_REAL, and dahdi_pvt::subs.
10705 { 10706 struct mwi_thread_data *mtd = data; 10707 struct callerid_state *cs; 10708 pthread_t threadid; 10709 int samples = 0; 10710 char *name, *number; 10711 int flags; 10712 int i, res; 10713 unsigned int spill_done = 0; 10714 int spill_result = -1; 10715 10716 if (!(cs = callerid_new(mtd->pvt->cid_signalling))) { 10717 mtd->pvt->mwimonitoractive = 0; 10718 10719 return NULL; 10720 } 10721 10722 callerid_feed(cs, mtd->buf, mtd->len, AST_LAW(mtd->pvt)); 10723 10724 bump_gains(mtd->pvt); 10725 10726 for (;;) { 10727 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10728 if ((res = ioctl(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_IOMUX, &i))) { 10729 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10730 goto quit; 10731 } 10732 10733 if (i & DAHDI_IOMUX_SIGEVENT) { 10734 struct ast_channel *chan; 10735 10736 /* If we get an event, screen out events that we do not act on. 10737 * Otherwise, cancel and go to the simple switch to let it deal with it. 10738 */ 10739 res = dahdi_get_event(mtd->pvt->subs[SUB_REAL].dfd); 10740 10741 switch (res) { 10742 case DAHDI_EVENT_NEONMWI_ACTIVE: 10743 case DAHDI_EVENT_NEONMWI_INACTIVE: 10744 case DAHDI_EVENT_NONE: 10745 case DAHDI_EVENT_BITSCHANGED: 10746 break; 10747 case DAHDI_EVENT_NOALARM: 10748 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 10749 struct analog_pvt *analog_p = mtd->pvt->sig_pvt; 10750 10751 analog_p->inalarm = 0; 10752 } 10753 mtd->pvt->inalarm = 0; 10754 handle_clear_alarms(mtd->pvt); 10755 break; 10756 case DAHDI_EVENT_ALARM: 10757 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 10758 struct analog_pvt *analog_p = mtd->pvt->sig_pvt; 10759 10760 analog_p->inalarm = 1; 10761 } 10762 mtd->pvt->inalarm = 1; 10763 res = get_alarms(mtd->pvt); 10764 handle_alarms(mtd->pvt, res); 10765 break; /* What to do on channel alarm ???? -- fall thru intentionally?? */ 10766 default: 10767 ast_log(LOG_NOTICE, "Got event %d (%s)... Passing along to analog_ss_thread\n", res, event2str(res)); 10768 callerid_free(cs); 10769 10770 restore_gains(mtd->pvt); 10771 mtd->pvt->ringt = mtd->pvt->ringt_base; 10772 10773 if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, NULL))) { 10774 int result; 10775 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 10776 result = analog_ss_thread_start(mtd->pvt->sig_pvt, chan); 10777 } else { 10778 result = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan); 10779 } 10780 if (result) { 10781 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", mtd->pvt->channel); 10782 res = tone_zone_play_tone(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 10783 if (res < 0) 10784 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", mtd->pvt->channel); 10785 ast_hangup(chan); 10786 goto quit; 10787 } 10788 goto quit_no_clean; 10789 10790 } else { 10791 ast_log(LOG_WARNING, "Could not create channel to handle call\n"); 10792 } 10793 } 10794 } else if (i & DAHDI_IOMUX_READ) { 10795 if ((res = read(mtd->pvt->subs[SUB_REAL].dfd, mtd->buf, sizeof(mtd->buf))) < 0) { 10796 if (errno != ELAST) { 10797 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10798 goto quit; 10799 } 10800 break; 10801 } 10802 samples += res; 10803 if (!spill_done) { 10804 if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) { 10805 /* 10806 * The previous diagnostic message output likely 10807 * explains why it failed. 10808 */ 10809 ast_log(LOG_WARNING, "Failed to decode CallerID\n"); 10810 break; 10811 } else if (spill_result) { 10812 spill_done = 1; 10813 } 10814 } else { 10815 /* keep reading data until the energy level drops below the threshold 10816 so we don't get another 'trigger' on the remaining carrier signal 10817 */ 10818 if (calc_energy(mtd->buf, res, AST_LAW(mtd->pvt)) <= mwilevel) 10819 break; 10820 } 10821 if (samples > (8000 * 4)) /*Termination case - time to give up*/ 10822 break; 10823 } 10824 } 10825 10826 if (spill_result == 1) { 10827 callerid_get(cs, &name, &number, &flags); 10828 if (flags & CID_MSGWAITING) { 10829 ast_log(LOG_NOTICE, "mwi: Have Messages on channel %d\n", mtd->pvt->channel); 10830 notify_message(mtd->pvt->mailbox, 1); 10831 } else if (flags & CID_NOMSGWAITING) { 10832 ast_log(LOG_NOTICE, "mwi: No Messages on channel %d\n", mtd->pvt->channel); 10833 notify_message(mtd->pvt->mailbox, 0); 10834 } else { 10835 ast_log(LOG_NOTICE, "mwi: Status unknown on channel %d\n", mtd->pvt->channel); 10836 } 10837 } 10838 10839 10840 quit: 10841 callerid_free(cs); 10842 10843 restore_gains(mtd->pvt); 10844 10845 quit_no_clean: 10846 mtd->pvt->mwimonitoractive = 0; 10847 10848 ast_free(mtd); 10849 10850 return NULL; 10851 }
static void my_all_subchannels_hungup | ( | void * | pvt | ) | [static] |
Definition at line 2326 of file chan_dahdi.c.
References ast_dsp_free(), ast_log(), dahdi_pvt::channel, dahdi_setlinear(), dahdi_pvt::didtdd, dahdi_pvt::dsp, errno, dahdi_pvt::faxhandled, dahdi_pvt::law, dahdi_pvt::law_default, LOG_WARNING, num_restart_pending, dahdi_subchannel::owner, dahdi_pvt::owner, reset_conf(), restart_monitor(), SUB_REAL, and dahdi_pvt::subs.
02327 { 02328 struct dahdi_pvt *p = pvt; 02329 int res, law; 02330 02331 p->faxhandled = 0; 02332 p->didtdd = 0; 02333 02334 if (p->dsp) { 02335 ast_dsp_free(p->dsp); 02336 p->dsp = NULL; 02337 } 02338 02339 p->law = p->law_default; 02340 law = p->law_default; 02341 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 02342 if (res < 0) 02343 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno)); 02344 02345 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 02346 02347 #if 1 02348 { 02349 int i; 02350 p->owner = NULL; 02351 /* Cleanup owners here */ 02352 for (i = 0; i < 3; i++) { 02353 p->subs[i].owner = NULL; 02354 } 02355 } 02356 #endif 02357 02358 reset_conf(p); 02359 if (num_restart_pending == 0) { 02360 restart_monitor(); 02361 } 02362 }
static int my_allocate_sub | ( | void * | pvt, | |
enum analog_sub | analogsub | |||
) | [static] |
Definition at line 2604 of file chan_dahdi.c.
References alloc_sub(), and analogsub_to_dahdisub().
02605 { 02606 struct dahdi_pvt *p = pvt; 02607 02608 return alloc_sub(p, analogsub_to_dahdisub(analogsub)); 02609 }
static void my_answer_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2842 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, and my_set_polarity().
02843 { 02844 struct dahdi_pvt *p = pvt; 02845 02846 if (!p->answeronpolarityswitch) { 02847 return; 02848 } 02849 02850 my_set_polarity(pvt, 1); 02851 }
static int my_callwait | ( | void * | pvt | ) | [static] |
Definition at line 1884 of file chan_dahdi.c.
References ast_free, ast_gen_cas(), AST_LAW, ast_log(), ast_malloc, dahdi_pvt::callwaitcas, CALLWAITING_REPEAT_SAMPLES, dahdi_pvt::callwaitingcallerid, dahdi_pvt::callwaitingrepeat, dahdi_pvt::callwaitrings, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, LOG_WARNING, READ_SIZE, save_conference(), and send_callerid().
01885 { 01886 struct dahdi_pvt *p = pvt; 01887 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 01888 if (p->cidspill) { 01889 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 01890 ast_free(p->cidspill); 01891 } 01892 01893 /* 01894 * SAS: Subscriber Alert Signal, 440Hz for 300ms 01895 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves 01896 */ 01897 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 01898 return -1; 01899 save_conference(p); 01900 /* Silence */ 01901 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 01902 if (!p->callwaitrings && p->callwaitingcallerid) { 01903 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 01904 p->callwaitcas = 1; 01905 p->cidlen = 2400 + 680 + READ_SIZE * 4; 01906 } else { 01907 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 01908 p->callwaitcas = 0; 01909 p->cidlen = 2400 + READ_SIZE * 4; 01910 } 01911 p->cidpos = 0; 01912 send_callerid(p); 01913 01914 return 0; 01915 }
static void my_cancel_cidspill | ( | void * | pvt | ) | [static] |
Definition at line 2276 of file chan_dahdi.c.
References ast_free, dahdi_pvt::cidspill, and restore_conference().
02277 { 02278 struct dahdi_pvt *p = pvt; 02279 02280 ast_free(p->cidspill); 02281 p->cidspill = NULL; 02282 restore_conference(p); 02283 }
static int my_check_confirmanswer | ( | void * | pvt | ) | [static] |
Definition at line 2259 of file chan_dahdi.c.
References dahdi_pvt::confirmanswer.
02260 { 02261 struct dahdi_pvt *p = pvt; 02262 if (p->confirmanswer) { 02263 return 1; 02264 } 02265 02266 return 0; 02267 }
static int my_check_for_conference | ( | void * | pvt | ) | [static] |
Definition at line 2436 of file chan_dahdi.c.
References check_for_conference().
02437 { 02438 struct dahdi_pvt *p = pvt; 02439 return check_for_conference(p); 02440 }
static int my_check_waitingfordt | ( | void * | pvt | ) | [static] |
Definition at line 2242 of file chan_dahdi.c.
References dahdi_pvt::waitingfordt.
02243 { 02244 struct dahdi_pvt *p = pvt; 02245 02246 if (p->waitingfordt.tv_usec) { 02247 return 1; 02248 } 02249 02250 return 0; 02251 }
static int my_complete_conference_update | ( | void * | pvt, | |
int | needconference | |||
) | [static] |
Definition at line 2386 of file chan_dahdi.c.
References conf_add(), GET_CHANNEL, isslavenative(), MAX_SLAVES, dahdi_pvt::slaves, SUB_REAL, and dahdi_pvt::subs.
02387 { 02388 struct dahdi_pvt *p = pvt; 02389 int needconf = needconference; 02390 int x; 02391 int useslavenative; 02392 struct dahdi_pvt *slave = NULL; 02393 02394 useslavenative = isslavenative(p, &slave); 02395 02396 /* If we have a slave, add him to our conference now. or DAX 02397 if this is slave native */ 02398 for (x = 0; x < MAX_SLAVES; x++) { 02399 if (p->slaves[x]) { 02400 if (useslavenative) 02401 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 02402 else { 02403 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 02404 needconf++; 02405 } 02406 } 02407 } 02408 /* If we're supposed to be in there, do so now */ 02409 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 02410 if (useslavenative) 02411 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 02412 else { 02413 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 02414 needconf++; 02415 } 02416 } 02417 /* If we have a master, add ourselves to his conference */ 02418 if (p->master) { 02419 if (isslavenative(p->master, NULL)) { 02420 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 02421 } else { 02422 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 02423 } 02424 } 02425 if (!needconf) { 02426 /* Nobody is left (or should be left) in our conference. 02427 Kill it. */ 02428 p->confno = -1; 02429 } 02430 02431 return 0; 02432 }
static int my_conf_add | ( | void * | pvt, | |
enum analog_sub | sub | |||
) | [static] |
Definition at line 2376 of file chan_dahdi.c.
References analogsub_to_dahdisub(), conf_add(), and dahdi_pvt::subs.
02377 { 02378 struct dahdi_pvt *p = pvt; 02379 int x = analogsub_to_dahdisub(sub); 02380 02381 return conf_add(p, &p->subs[x], x, 0); 02382 }
static int my_conf_del | ( | void * | pvt, | |
enum analog_sub | sub | |||
) | [static] |
Definition at line 2366 of file chan_dahdi.c.
References analogsub_to_dahdisub(), conf_del(), and dahdi_pvt::subs.
02367 { 02368 struct dahdi_pvt *p = pvt; 02369 int x = analogsub_to_dahdisub(sub); 02370 02371 return conf_del(p, &p->subs[x], x); 02372 }
static int my_confmute | ( | void * | pvt, | |
int | mute | |||
) | [static] |
Definition at line 2285 of file chan_dahdi.c.
References dahdi_confmute().
02286 { 02287 struct dahdi_pvt *p = pvt; 02288 return dahdi_confmute(p, mute); 02289 }
static int my_dahdi_write | ( | struct dahdi_pvt * | p, | |
unsigned char * | buf, | |||
int | len, | |||
int | idx, | |||
int | linear | |||
) | [static] |
Definition at line 9039 of file chan_dahdi.c.
References ast_debug, dahdi_pvt::channel, dahdi_subchannel::dfd, errno, READ_SIZE, and dahdi_pvt::subs.
Referenced by dahdi_write().
09040 { 09041 int sent=0; 09042 int size; 09043 int res; 09044 int fd; 09045 fd = p->subs[idx].dfd; 09046 while (len) { 09047 size = len; 09048 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 09049 size = (linear ? READ_SIZE * 2 : READ_SIZE); 09050 res = write(fd, buf, size); 09051 if (res != size) { 09052 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 09053 return sent; 09054 } 09055 len -= size; 09056 buf += size; 09057 } 09058 return sent; 09059 }
static void my_deadlock_avoidance_private | ( | void * | pvt | ) | [static] |
Definition at line 2102 of file chan_dahdi.c.
References DEADLOCK_AVOIDANCE, and dahdi_pvt::lock.
02103 { 02104 struct dahdi_pvt *p = pvt; 02105 02106 DEADLOCK_AVOIDANCE(&p->lock); 02107 }
static void my_decrease_ss_count | ( | void | ) | [static] |
Definition at line 2318 of file chan_dahdi.c.
References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, ss_thread_complete, ss_thread_count, and ss_thread_lock.
02319 { 02320 ast_mutex_lock(&ss_thread_lock); 02321 ss_thread_count--; 02322 ast_cond_signal(&ss_thread_complete); 02323 ast_mutex_unlock(&ss_thread_lock); 02324 }
static int my_dial_digits | ( | void * | pvt, | |
enum analog_sub | sub, | |||
struct analog_dialoperation * | dop | |||
) | [static] |
Definition at line 2876 of file chan_dahdi.c.
References ANALOG_DIAL_OP_REPLACE, ANALOG_SUB_REAL, analogsub_to_dahdisub(), ast_log(), dahdi_pvt::channel, dahdi_subchannel::dfd, analog_dialoperation::dialstr, errno, LOG_DEBUG, LOG_ERROR, ast_channel::name, analog_dialoperation::op, dahdi_pvt::owner, and dahdi_pvt::subs.
02877 { 02878 int index = analogsub_to_dahdisub(sub); 02879 int res; 02880 struct dahdi_pvt *p = pvt; 02881 struct dahdi_dialoperation ddop; 02882 02883 if (dop->op != ANALOG_DIAL_OP_REPLACE) { 02884 ast_log(LOG_ERROR, "Fix the dial_digits callback!\n"); 02885 return -1; 02886 } 02887 02888 if (sub != ANALOG_SUB_REAL) 02889 printf("Trying to dial digits on sub %d\n", sub); 02890 02891 ddop.op = DAHDI_DIAL_OP_REPLACE; 02892 strncpy(ddop.dialstr, dop->dialstr, sizeof(ddop.dialstr)); 02893 02894 printf("Dialing %s on %d\n", ddop.dialstr, p->channel); 02895 02896 res = ioctl(p->subs[index].dfd, DAHDI_DIAL, &ddop); 02897 02898 if (res == -1) 02899 ast_log(LOG_DEBUG, "DAHDI_DIAL ioctl failed on %s: %s\n", p->owner->name, strerror(errno)); 02900 02901 return res; 02902 }
static int my_distinctive_ring | ( | struct ast_channel * | chan, | |
void * | pvt, | |||
int | idx, | |||
int * | ringdata | |||
) | [static] |
Definition at line 1748 of file chan_dahdi.c.
References ast_copy_string(), ast_hangup(), ast_log(), ast_verb, ast_channel::context, dahdi_pvt::context, dahdi_get_event(), dahdi_pvt::defcontext, dahdi_subchannel::dfd, errno, event2str(), analog_pvt::inalarm, dahdi_pvt::inalarm, LOG_NOTICE, LOG_WARNING, RING_PATTERNS, analog_pvt::ringt, analog_pvt::ringt_base, dahdi_pvt::sig_pvt, and dahdi_pvt::subs.
01749 { 01750 unsigned char buf[256]; 01751 int distMatches; 01752 int curRingData[RING_PATTERNS]; 01753 int receivedRingT; 01754 int counter1; 01755 int counter; 01756 int i; 01757 int res; 01758 int checkaftercid = 0; 01759 01760 struct dahdi_pvt *p = pvt; 01761 struct analog_pvt *analog_p = p->sig_pvt; 01762 01763 if (ringdata == NULL) { 01764 ringdata = curRingData; 01765 } else { 01766 checkaftercid = 1; 01767 } 01768 01769 /* We must have a ring by now, so, if configured, lets try to listen for 01770 * distinctive ringing */ 01771 if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) { 01772 /* Clear the current ring data array so we don't have old data in it. */ 01773 for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++) 01774 ringdata[receivedRingT] = 0; 01775 receivedRingT = 0; 01776 if (checkaftercid && distinctiveringaftercid) 01777 ast_verb(3, "Detecting post-CID distinctive ring\n"); 01778 /* Check to see if context is what it should be, if not set to be. */ 01779 else if (strcmp(p->context,p->defcontext) != 0) { 01780 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 01781 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 01782 } 01783 01784 for (;;) { 01785 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 01786 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 01787 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 01788 ast_hangup(chan); 01789 return 1; 01790 } 01791 if (i & DAHDI_IOMUX_SIGEVENT) { 01792 res = dahdi_get_event(p->subs[idx].dfd); 01793 if (res == DAHDI_EVENT_NOALARM) { 01794 p->inalarm = 0; 01795 analog_p->inalarm = 0; 01796 } 01797 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 01798 res = 0; 01799 /* Let us detect distinctive ring */ 01800 01801 ringdata[receivedRingT] = analog_p->ringt; 01802 01803 if (analog_p->ringt < analog_p->ringt_base/2) 01804 break; 01805 /* Increment the ringT counter so we can match it against 01806 values in chan_dahdi.conf for distinctive ring */ 01807 if (++receivedRingT == RING_PATTERNS) 01808 break; 01809 } else if (i & DAHDI_IOMUX_READ) { 01810 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 01811 if (res < 0) { 01812 if (errno != ELAST) { 01813 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 01814 ast_hangup(chan); 01815 return 1; 01816 } 01817 break; 01818 } 01819 if (analog_p->ringt > 0) { 01820 if (!(--analog_p->ringt)) { 01821 res = -1; 01822 break; 01823 } 01824 } 01825 } 01826 } 01827 } 01828 if ((checkaftercid && usedistinctiveringdetection) || !checkaftercid) { 01829 /* this only shows up if you have n of the dring patterns filled in */ 01830 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",ringdata[0],ringdata[1],ringdata[2]); 01831 for (counter = 0; counter < 3; counter++) { 01832 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */ 01833 distMatches = 0; 01834 /* this only shows up if you have n of the dring patterns filled in */ 01835 ast_verb(3, "Checking %d,%d,%d\n", 01836 p->drings.ringnum[counter].ring[0], 01837 p->drings.ringnum[counter].ring[1], 01838 p->drings.ringnum[counter].ring[2]); 01839 for (counter1 = 0; counter1 < 3; counter1++) { 01840 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 01841 if (p->drings.ringnum[counter].ring[counter1] == -1) { 01842 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 01843 ringdata[counter1]); 01844 distMatches++; 01845 } else if (ringdata[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 01846 ringdata[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 01847 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 01848 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 01849 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 01850 distMatches++; 01851 } 01852 } 01853 01854 if (distMatches == 3) { 01855 /* The ring matches, set the context to whatever is for distinctive ring.. */ 01856 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 01857 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 01858 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 01859 break; 01860 } 01861 } 01862 } 01863 /* Restore linear mode (if appropriate) for Caller*ID processing */ 01864 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 01865 restore_gains(p); 01866 01867 return 0; 01868 }
static int my_dsp_reset_and_flush_digits | ( | void * | pvt | ) | [static] |
Definition at line 1952 of file chan_dahdi.c.
References ast_dsp_digitreset(), and dahdi_pvt::dsp.
01953 { 01954 struct dahdi_pvt *p = pvt; 01955 if (p->dsp) 01956 ast_dsp_digitreset(p->dsp); 01957 01958 return 0; 01959 }
static int my_dsp_set_digitmode | ( | void * | pvt, | |
enum analog_dsp_digitmode | mode | |||
) | [static] |
Definition at line 1961 of file chan_dahdi.c.
References ANALOG_DIGITMODE_DTMF, ANALOG_DIGITMODE_MF, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_digitmode(), ast_log(), CHAN_PSEUDO, dahdi_pvt::channel, dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, dahdi_pvt::dtmfrelax, dahdi_pvt::hardwaredtmf, and LOG_ERROR.
01962 { 01963 struct dahdi_pvt *p = pvt; 01964 01965 if (p->channel == CHAN_PSEUDO) 01966 ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n"); 01967 01968 if (mode == ANALOG_DIGITMODE_DTMF) { 01969 /* If we do hardware dtmf, no need for a DSP */ 01970 if (p->hardwaredtmf) { 01971 if (p->dsp) { 01972 ast_dsp_free(p->dsp); 01973 p->dsp = NULL; 01974 } 01975 return 0; 01976 } 01977 01978 if (!p->dsp) { 01979 p->dsp = ast_dsp_new(); 01980 if (!p->dsp) { 01981 ast_log(LOG_ERROR, "Unable to allocate DSP\n"); 01982 return -1; 01983 } 01984 } 01985 01986 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 01987 } else if (mode == ANALOG_DIGITMODE_MF) { 01988 if (!p->dsp) { 01989 p->dsp = ast_dsp_new(); 01990 if (!p->dsp) { 01991 ast_log(LOG_ERROR, "Unable to allocate DSP\n"); 01992 return -1; 01993 } 01994 } 01995 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 01996 } 01997 return 0; 01998 }
static int my_flash | ( | void * | pvt | ) | [static] |
Definition at line 2801 of file chan_dahdi.c.
References SUB_REAL, and dahdi_pvt::subs.
02802 { 02803 struct dahdi_pvt *p = pvt; 02804 int func = DAHDI_FLASH; 02805 return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func); 02806 }
static void my_get_and_handle_alarms | ( | void * | pvt | ) | [static] |
Definition at line 2134 of file chan_dahdi.c.
References get_alarms(), and handle_alarms().
02135 { 02136 int res; 02137 struct dahdi_pvt *p = pvt; 02138 02139 res = get_alarms(p); 02140 handle_alarms(p, res); 02141 }
static int my_get_callerid | ( | void * | pvt, | |
char * | namebuf, | |||
char * | numbuf, | |||
enum analog_event * | ev, | |||
size_t | timeout | |||
) | [static] |
Definition at line 1671 of file chan_dahdi.c.
References ANALOG_EVENT_NONE, ANALOG_MAX_CID, ast_copy_string(), AST_LAW, ast_log(), callerid_feed(), callerid_feed_jp(), callerid_free(), callerid_get(), CID_SIG_V23_JP, dahdi_pvt::cid_signalling, dahdi_pvt::cs, dahdi_get_event(), dahdievent_to_analogevent(), dahdi_subchannel::dfd, errno, LOG_DEBUG, LOG_WARNING, name, analog_pvt::ringt, dahdi_pvt::sig_pvt, SUB_REAL, and dahdi_pvt::subs.
01672 { 01673 struct dahdi_pvt *p = pvt; 01674 struct analog_pvt *analog_p = p->sig_pvt; 01675 struct pollfd poller; 01676 char *name, *num; 01677 int index = SUB_REAL; 01678 int res; 01679 unsigned char buf[256]; 01680 int flags; 01681 01682 poller.fd = p->subs[SUB_REAL].dfd; 01683 poller.events = POLLPRI | POLLIN; 01684 poller.revents = 0; 01685 01686 res = poll(&poller, 1, timeout); 01687 01688 if (poller.revents & POLLPRI) { 01689 *ev = dahdievent_to_analogevent(dahdi_get_event(p->subs[SUB_REAL].dfd)); 01690 return 1; 01691 } 01692 01693 if (poller.revents & POLLIN) { 01694 /*** NOTES ***/ 01695 /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function 01696 * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until 01697 * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be 01698 * a failure and die, and returning 2 means no event was received. */ 01699 res = read(p->subs[index].dfd, buf, sizeof(buf)); 01700 if (res < 0) { 01701 if (errno != ELAST) { 01702 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 01703 callerid_free(p->cs); 01704 return -1; 01705 } 01706 } 01707 01708 if (analog_p->ringt > 0) { 01709 if (!(--analog_p->ringt)) { 01710 /* only return if we timeout from a ring event */ 01711 return -1; 01712 } 01713 } 01714 01715 if (p->cid_signalling == CID_SIG_V23_JP) { 01716 res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p)); 01717 } else { 01718 res = callerid_feed(p->cs, buf, res, AST_LAW(p)); 01719 } 01720 if (res < 0) { 01721 /* 01722 * The previous diagnostic message output likely 01723 * explains why it failed. 01724 */ 01725 ast_log(LOG_WARNING, "Failed to decode CallerID\n"); 01726 return -1; 01727 } 01728 01729 if (res == 1) { 01730 callerid_get(p->cs, &name, &num, &flags); 01731 if (name) 01732 ast_copy_string(namebuf, name, ANALOG_MAX_CID); 01733 if (num) 01734 ast_copy_string(numbuf, num, ANALOG_MAX_CID); 01735 01736 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags); 01737 return 0; 01738 } 01739 } 01740 01741 *ev = ANALOG_EVENT_NONE; 01742 return 2; 01743 }
static int my_get_event | ( | void * | pvt | ) | [static] |
Definition at line 2734 of file chan_dahdi.c.
References dahdi_get_event(), dahdievent_to_analogevent(), dahdi_pvt::fake_event, SUB_REAL, and dahdi_pvt::subs.
02735 { 02736 struct dahdi_pvt *p = pvt; 02737 int res; 02738 02739 if (p->fake_event) { 02740 res = p->fake_event; 02741 p->fake_event = 0; 02742 } else 02743 res = dahdi_get_event(p->subs[SUB_REAL].dfd); 02744 02745 return dahdievent_to_analogevent(res); 02746 }
static const char* my_get_orig_dialstring | ( | void * | pvt | ) | [static] |
Definition at line 2304 of file chan_dahdi.c.
References dahdi_pvt::dialstring.
02305 { 02306 struct dahdi_pvt *p = pvt; 02307 02308 return p->dialstring; 02309 }
static void* my_get_sigpvt_bridged_channel | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 2143 of file chan_dahdi.c.
References ast_bridged_channel(), dahdi_pvt::sig_pvt, and ast_channel::tech_pvt.
02144 { 02145 struct dahdi_pvt *p = ast_bridged_channel(chan)->tech_pvt; 02146 if (p) 02147 return p->sig_pvt; 02148 else 02149 return NULL; 02150 }
static int my_get_sub_fd | ( | void * | pvt, | |
enum analog_sub | sub | |||
) | [static] |
Definition at line 2152 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
02153 { 02154 struct dahdi_pvt *p = pvt; 02155 int dahdi_sub = analogsub_to_dahdisub(sub); 02156 return p->subs[dahdi_sub].dfd; 02157 }
static int my_getsigstr | ( | struct ast_channel * | chan, | |
char * | str, | |||
const char * | term, | |||
int | ms | |||
) | [static] |
Definition at line 9496 of file chan_dahdi.c.
References ast_waitfordigit().
Referenced by analog_ss_thread().
09497 { 09498 char c; 09499 09500 *str = 0; /* start with empty output buffer */ 09501 for (;;) 09502 { 09503 /* Wait for the first digit (up to specified ms). */ 09504 c = ast_waitfordigit(chan, ms); 09505 /* if timeout, hangup or error, return as such */ 09506 if (c < 1) 09507 return c; 09508 *str++ = c; 09509 *str = 0; 09510 if (strchr(term, c)) 09511 return 1; 09512 } 09513 }
static void my_handle_dchan_exception | ( | struct sig_pri_span * | pri, | |
int | index | |||
) | [static] |
Definition at line 2996 of file chan_dahdi.c.
References ast_log(), event2str(), sig_pri_span::fds, LOG_NOTICE, dahdi_pvt::pri, pri_event_alarm(), pri_event_noalarm(), and sig_pri_span::span.
02997 { 02998 int x, res; 02999 03000 res = ioctl(pri->fds[index], DAHDI_GETEVENT, &x); 03001 if (x) { 03002 ast_log(LOG_NOTICE, "PRI got event: %s (%d) on D-channel of span %d\n", event2str(x), x, pri->span); 03003 } 03004 /* Keep track of alarm state */ 03005 switch (x) { 03006 case DAHDI_EVENT_ALARM: 03007 pri_event_alarm(pri, index, 0); 03008 break; 03009 case DAHDI_EVENT_NOALARM: 03010 pri_event_noalarm(pri, index, 0); 03011 break; 03012 default: 03013 break; 03014 } 03015 }
static void my_handle_dtmf | ( | void * | pvt, | |
struct ast_channel * | ast, | |||
enum analog_sub | analog_index, | |||
struct ast_frame ** | dest | |||
) | [static] |
Definition at line 2018 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_debug, ast_dsp_set_features(), ast_exists_extension(), AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verb, dahdi_pvt::bufferoverrideinuse, dahdi_pvt::bufsize, ast_channel::caller, dahdi_pvt::callprogress, CALLPROGRESS_FAX, ast_channel::context, dahdi_confmute(), dahdi_subchannel::dfd, dahdi_pvt::dsp, DSP_FEATURE_FAX_DETECT, dahdi_pvt::dsp_features, errno, ast_channel::exten, dahdi_subchannel::f, f, dahdi_pvt::faxbuf_no, dahdi_pvt::faxbuf_policy, dahdi_pvt::faxhandled, ast_frame::frametype, ast_party_caller::id, ast_frame_subclass::integer, dahdi_pvt::lock, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, ast_channel::name, ast_party_id::number, pbx_builtin_setvar_helper(), S_COR, S_OR, ast_party_number::str, ast_frame::subclass, dahdi_pvt::subs, dahdi_pvt::usefaxbuffers, and ast_party_number::valid.
02019 { 02020 struct ast_frame *f = *dest; 02021 struct dahdi_pvt *p = pvt; 02022 int idx = analogsub_to_dahdisub(analog_index); 02023 02024 ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n", 02025 f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End", 02026 f->subclass.integer, f->subclass.integer, ast->name); 02027 02028 if (f->subclass.integer == 'f') { 02029 if (f->frametype == AST_FRAME_DTMF_END) { 02030 /* Fax tone -- Handle and return NULL */ 02031 if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) { 02032 /* If faxbuffers are configured, use them for the fax transmission */ 02033 if (p->usefaxbuffers && !p->bufferoverrideinuse) { 02034 struct dahdi_bufferinfo bi = { 02035 .txbufpolicy = p->faxbuf_policy, 02036 .bufsize = p->bufsize, 02037 .numbufs = p->faxbuf_no 02038 }; 02039 int res; 02040 02041 if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 02042 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast->name, strerror(errno)); 02043 } else { 02044 p->bufferoverrideinuse = 1; 02045 } 02046 } 02047 p->faxhandled = 1; 02048 if (p->dsp) { 02049 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 02050 ast_dsp_set_features(p->dsp, p->dsp_features); 02051 ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast->name); 02052 } 02053 if (strcmp(ast->exten, "fax")) { 02054 const char *target_context = S_OR(ast->macrocontext, ast->context); 02055 02056 /* We need to unlock 'ast' here because ast_exists_extension has the 02057 * potential to start autoservice on the channel. Such action is prone 02058 * to deadlock. 02059 */ 02060 ast_mutex_unlock(&p->lock); 02061 ast_channel_unlock(ast); 02062 if (ast_exists_extension(ast, target_context, "fax", 1, 02063 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 02064 ast_channel_lock(ast); 02065 ast_mutex_lock(&p->lock); 02066 ast_verb(3, "Redirecting %s to fax extension\n", ast->name); 02067 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 02068 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 02069 if (ast_async_goto(ast, target_context, "fax", 1)) 02070 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 02071 } else { 02072 ast_channel_lock(ast); 02073 ast_mutex_lock(&p->lock); 02074 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 02075 } 02076 } else { 02077 ast_debug(1, "Already in a fax extension, not redirecting\n"); 02078 } 02079 } else { 02080 ast_debug(1, "Fax already handled\n"); 02081 } 02082 dahdi_confmute(p, 0); 02083 } 02084 p->subs[idx].f.frametype = AST_FRAME_NULL; 02085 p->subs[idx].f.subclass.integer = 0; 02086 *dest = &p->subs[idx].f; 02087 } 02088 }
static void my_handle_link_exception | ( | struct sig_ss7_linkset * | linkset, | |
int | which | |||
) | [static] |
Definition at line 3308 of file chan_dahdi.c.
References ast_log(), event2str(), sig_ss7_linkset::fds, LOG_ERROR, LOG_NOTICE, sig_ss7_link_alarm(), sig_ss7_link_noalarm(), and sig_ss7_linkset::span.
03309 { 03310 int event; 03311 03312 if (ioctl(linkset->fds[which], DAHDI_GETEVENT, &event)) { 03313 ast_log(LOG_ERROR, "SS7: Error in exception retrieval on span %d/%d!\n", 03314 linkset->span, which); 03315 return; 03316 } 03317 switch (event) { 03318 case DAHDI_EVENT_NONE: 03319 break; 03320 case DAHDI_EVENT_ALARM: 03321 ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n", 03322 event2str(event), event, linkset->span, which); 03323 sig_ss7_link_alarm(linkset, which); 03324 break; 03325 case DAHDI_EVENT_NOALARM: 03326 ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n", 03327 event2str(event), event, linkset->span, which); 03328 sig_ss7_link_noalarm(linkset, which); 03329 break; 03330 default: 03331 ast_log(LOG_NOTICE, "SS7 got event: %s(%d) on span %d/%d\n", 03332 event2str(event), event, linkset->span, which); 03333 break; 03334 } 03335 }
static void my_handle_notify_message | ( | struct ast_channel * | chan, | |
void * | pvt, | |||
int | cid_flags, | |||
int | neon_mwievent | |||
) | [static] |
Definition at line 3504 of file chan_dahdi.c.
References ANALOG_EVENT_NEONMWI_ACTIVE, ANALOG_EVENT_NEONMWI_INACTIVE, ast_hangup(), ast_log(), dahdi_pvt::channel, CID_MSGWAITING, CID_NOMSGWAITING, LOG_NOTICE, dahdi_pvt::mailbox, dahdi_pvt::mwimonitor_neon, dahdi_pvt::mwimonitor_rpas, and notify_message().
03505 { 03506 struct dahdi_pvt *p = pvt; 03507 03508 if (neon_mwievent > -1 && !p->mwimonitor_neon) 03509 return; 03510 03511 if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) { 03512 ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox); 03513 notify_message(p->mailbox, 1); 03514 } else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) { 03515 ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox); 03516 notify_message(p->mailbox, 0); 03517 } 03518 /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */ 03519 /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */ 03520 if (neon_mwievent == -1 && p->mwimonitor_rpas) { 03521 ast_hangup(chan); 03522 return; 03523 } 03524 }
static void my_hangup_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2853 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, dahdi_pvt::hanguponpolarityswitch, and my_set_polarity().
02854 { 02855 struct dahdi_pvt *p = pvt; 02856 02857 if (!p->hanguponpolarityswitch) { 02858 return; 02859 } 02860 02861 if (p->answeronpolarityswitch) { 02862 my_set_polarity(pvt, 0); 02863 } else { 02864 my_set_polarity(pvt, 1); 02865 } 02866 }
static int my_has_voicemail | ( | void * | pvt | ) | [static] |
Definition at line 2613 of file chan_dahdi.c.
References has_voicemail().
02614 { 02615 struct dahdi_pvt *p = pvt; 02616 02617 return has_voicemail(p); 02618 }
static void my_increase_ss_count | ( | void | ) | [static] |
Definition at line 2311 of file chan_dahdi.c.
References ast_mutex_lock, ast_mutex_unlock, ss_thread_count, and ss_thread_lock.
02312 { 02313 ast_mutex_lock(&ss_thread_lock); 02314 ss_thread_count++; 02315 ast_mutex_unlock(&ss_thread_lock); 02316 }
static int my_is_dialing | ( | void * | pvt, | |
enum analog_sub | sub | |||
) | [static] |
Definition at line 2915 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_log(), dahdi_subchannel::dfd, LOG_DEBUG, and dahdi_pvt::subs.
02916 { 02917 struct dahdi_pvt *p = pvt; 02918 int index; 02919 int x; 02920 02921 index = analogsub_to_dahdisub(sub); 02922 02923 if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) { 02924 ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed!\n"); 02925 return -1; 02926 } 02927 02928 return x; 02929 }
static int my_is_off_hook | ( | void * | pvt | ) | [static] |
Definition at line 2748 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, errno, LOG_WARNING, dahdi_pvt::sig, SIG_FXSGS, SIG_FXSKS, SUB_REAL, and dahdi_pvt::subs.
02749 { 02750 struct dahdi_pvt *p = pvt; 02751 int res; 02752 struct dahdi_params par; 02753 02754 memset(&par, 0, sizeof(par)); 02755 02756 if (p->subs[SUB_REAL].dfd > -1) 02757 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par); 02758 else { 02759 /* Assume not off hook on CVRS */ 02760 res = 0; 02761 par.rxisoffhook = 0; 02762 } 02763 if (res) { 02764 ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno)); 02765 } 02766 02767 if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 02768 /* When "onhook" that means no battery on the line, and thus 02769 it is out of service..., if it's on a TDM card... If it's a channel 02770 bank, there is no telling... */ 02771 return (par.rxbits > -1) || par.rxisoffhook; 02772 } 02773 02774 return par.rxisoffhook; 02775 }
static void my_lock_private | ( | void * | pvt | ) | [static] |
Definition at line 2090 of file chan_dahdi.c.
References ast_mutex_lock, and dahdi_pvt::lock.
02091 { 02092 struct dahdi_pvt *p = pvt; 02093 ast_mutex_lock(&p->lock); 02094 }
static void my_module_ref | ( | void | ) | [static] |
Definition at line 3242 of file chan_dahdi.c.
References ast_module_ref().
03243 { 03244 ast_module_ref(ast_module_info->self); 03245 }
static void my_module_unref | ( | void | ) | [static] |
Definition at line 3256 of file chan_dahdi.c.
References ast_module_unref().
03257 { 03258 ast_module_unref(ast_module_info->self); 03259 }
static struct ast_channel* my_new_analog_ast_channel | ( | void * | pvt, | |
int | state, | |||
int | startpbx, | |||
enum analog_sub | sub, | |||
const struct ast_channel * | requestor | |||
) | [static] |
Definition at line 2476 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_new(), and ast_channel::linkedid.
02477 { 02478 struct dahdi_pvt *p = pvt; 02479 int dsub = analogsub_to_dahdisub(sub); 02480 02481 return dahdi_new(p, state, startpbx, dsub, 0, requestor ? requestor->linkedid : ""); 02482 }
static struct ast_channel* my_new_pri_ast_channel | ( | void * | pvt, | |
int | state, | |||
enum sig_pri_law | law, | |||
char * | exten, | |||
const struct ast_channel * | requestor | |||
) | [static] |
Definition at line 2496 of file chan_dahdi.c.
References ast_copy_string(), ast_log(), dahdi_pvt::channel, dahdi_new(), dahdi_setlaw(), errno, dahdi_pvt::exten, ast_channel::linkedid, LOG_WARNING, dahdi_pvt::sig, SIG_PRI_ALAW, SIG_PRI_DEFLAW, SIG_PRI_LIB_HANDLE_CASES, SIG_PRI_ULAW, dahdi_pvt::sig_pvt, SUB_REAL, and dahdi_pvt::subs.
02497 { 02498 struct dahdi_pvt *p = pvt; 02499 int audio; 02500 int newlaw = -1; 02501 02502 switch (p->sig) { 02503 case SIG_PRI_LIB_HANDLE_CASES: 02504 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 02505 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */ 02506 break; 02507 } 02508 /* Fall through */ 02509 default: 02510 /* Set to audio mode at this point */ 02511 audio = 1; 02512 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1) { 02513 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", 02514 p->channel, audio, strerror(errno)); 02515 } 02516 break; 02517 } 02518 02519 if (law != SIG_PRI_DEFLAW) { 02520 dahdi_setlaw(p->subs[SUB_REAL].dfd, (law == SIG_PRI_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW); 02521 } 02522 02523 ast_copy_string(p->exten, exten, sizeof(p->exten)); 02524 02525 switch (law) { 02526 case SIG_PRI_DEFLAW: 02527 newlaw = 0; 02528 break; 02529 case SIG_PRI_ALAW: 02530 newlaw = DAHDI_LAW_ALAW; 02531 break; 02532 case SIG_PRI_ULAW: 02533 newlaw = DAHDI_LAW_MULAW; 02534 break; 02535 } 02536 return dahdi_new(p, state, 0, SUB_REAL, newlaw, requestor ? requestor->linkedid : ""); 02537 }
static struct ast_channel* my_new_ss7_ast_channel | ( | void * | pvt, | |
int | state, | |||
enum sig_ss7_law | law, | |||
char * | exten, | |||
const struct ast_channel * | requestor | |||
) | [static] |
Definition at line 3365 of file chan_dahdi.c.
References ast_copy_string(), ast_log(), dahdi_pvt::channel, dahdi_new(), dahdi_setlaw(), errno, dahdi_pvt::exten, ast_channel::linkedid, LOG_WARNING, SIG_SS7_ALAW, SIG_SS7_DEFLAW, SIG_SS7_ULAW, SUB_REAL, and dahdi_pvt::subs.
03366 { 03367 struct dahdi_pvt *p = pvt; 03368 int audio; 03369 int newlaw; 03370 03371 /* Set to audio mode at this point */ 03372 audio = 1; 03373 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1) 03374 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", 03375 p->channel, audio, strerror(errno)); 03376 03377 if (law != SIG_SS7_DEFLAW) { 03378 dahdi_setlaw(p->subs[SUB_REAL].dfd, 03379 (law == SIG_SS7_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW); 03380 } 03381 03382 ast_copy_string(p->exten, exten, sizeof(p->exten)); 03383 03384 newlaw = -1; 03385 switch (law) { 03386 case SIG_SS7_DEFLAW: 03387 newlaw = 0; 03388 break; 03389 case SIG_SS7_ALAW: 03390 newlaw = DAHDI_LAW_ALAW; 03391 break; 03392 case SIG_SS7_ULAW: 03393 newlaw = DAHDI_LAW_MULAW; 03394 break; 03395 } 03396 return dahdi_new(p, state, 0, SUB_REAL, newlaw, requestor ? requestor->linkedid : ""); 03397 }
static int my_off_hook | ( | void * | pvt | ) | [static] |
Definition at line 2810 of file chan_dahdi.c.
References dahdi_set_hook(), SUB_REAL, and dahdi_pvt::subs.
02811 { 02812 struct dahdi_pvt *p = pvt; 02813 return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 02814 }
static int my_on_hook | ( | void * | pvt | ) | [static] |
Definition at line 2931 of file chan_dahdi.c.
References ANALOG_SUB_REAL, dahdi_set_hook(), and dahdi_pvt::subs.
02932 { 02933 struct dahdi_pvt *p = pvt; 02934 return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK); 02935 }
static int my_play_tone | ( | void * | pvt, | |
enum analog_sub | sub, | |||
enum analog_tone | tone | |||
) | [static] |
Definition at line 2620 of file chan_dahdi.c.
References analog_tone_to_dahditone(), analogsub_to_dahdisub(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
02621 { 02622 struct dahdi_pvt *p = pvt; 02623 int index; 02624 02625 index = analogsub_to_dahdisub(sub); 02626 02627 return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone)); 02628 }
static void my_pri_fixup_chans | ( | void * | chan_old, | |
void * | chan_new | |||
) | [static] |
Definition at line 2938 of file chan_dahdi.c.
References dahdi_subchannel::dfd, dahdi_pvt::dialing, dahdi_pvt::dialstring, dahdi_pvt::digital, dahdi_pvt::dsp, dahdi_pvt::dsp_features, ast_channel::fds, dahdi_pvt::law, dahdi_pvt::outgoing, dahdi_subchannel::owner, dahdi_pvt::owner, SUB_REAL, dahdi_pvt::subs, and ast_channel::tech_pvt.
02939 { 02940 struct dahdi_pvt *old_chan = chan_old; 02941 struct dahdi_pvt *new_chan = chan_new; 02942 02943 new_chan->owner = old_chan->owner; 02944 old_chan->owner = NULL; 02945 if (new_chan->owner) { 02946 new_chan->owner->tech_pvt = new_chan; 02947 new_chan->owner->fds[0] = new_chan->subs[SUB_REAL].dfd; 02948 new_chan->subs[SUB_REAL].owner = old_chan->subs[SUB_REAL].owner; 02949 old_chan->subs[SUB_REAL].owner = NULL; 02950 } 02951 /* Copy any DSP that may be present */ 02952 new_chan->dsp = old_chan->dsp; 02953 new_chan->dsp_features = old_chan->dsp_features; 02954 old_chan->dsp = NULL; 02955 old_chan->dsp_features = 0; 02956 02957 /* Transfer flags from the old channel. */ 02958 new_chan->dialing = old_chan->dialing; 02959 new_chan->digital = old_chan->digital; 02960 new_chan->outgoing = old_chan->outgoing; 02961 old_chan->dialing = 0; 02962 old_chan->digital = 0; 02963 old_chan->outgoing = 0; 02964 02965 /* More stuff to transfer to the new channel. */ 02966 new_chan->law = old_chan->law; 02967 strcpy(new_chan->dialstring, old_chan->dialstring); 02968 }
static void my_pri_make_cc_dialstring | ( | void * | priv, | |
char * | buf, | |||
size_t | buf_size | |||
) | [static] |
Definition at line 3126 of file chan_dahdi.c.
References args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_NONSTANDARD_APP_ARGS, and ast_strdupa.
03127 { 03128 char *dial; 03129 struct dahdi_pvt *pvt; 03130 AST_DECLARE_APP_ARGS(args, 03131 AST_APP_ARG(tech); /* channel technology token */ 03132 AST_APP_ARG(group); /* channel/group token */ 03133 //AST_APP_ARG(ext); /* extension token */ 03134 //AST_APP_ARG(opts); /* options token */ 03135 //AST_APP_ARG(other); /* Any remining unused arguments */ 03136 ); 03137 03138 pvt = priv; 03139 dial = ast_strdupa(pvt->dialstring); 03140 AST_NONSTANDARD_APP_ARGS(args, dial, '/'); 03141 if (!args.tech) { 03142 ast_copy_string(buf, pvt->dialstring, buf_size); 03143 return; 03144 } 03145 if (!args.group) { 03146 /* Append the ISDN span channel restriction to the dialstring. */ 03147 snprintf(buf, buf_size, "%s/i%d-", args.tech, pvt->pri->span); 03148 return; 03149 } 03150 if (isdigit(args.group[0]) || args.group[0] == 'i' || strchr(args.group, '!')) { 03151 /* The ISDN span channel restriction is not needed or already 03152 * in the dialstring. */ 03153 ast_copy_string(buf, pvt->dialstring, buf_size); 03154 return; 03155 } 03156 /* Insert the ISDN span channel restriction into the dialstring. */ 03157 snprintf(buf, buf_size, "%s/i%d-%s", args.tech, pvt->pri->span, args.group); 03158 }
static void my_pri_open_media | ( | void * | p | ) | [static] |
Definition at line 2552 of file chan_dahdi.c.
References ast_dsp_set_features(), ast_log(), dahdi_pvt::channel, dahdi_setlaw(), dahdi_subchannel::dfd, dahdi_pvt::digital, dahdi_pvt::dsp, dahdi_pvt::dsp_features, errno, dahdi_pvt::law, LOG_WARNING, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, set_actual_gain(), SUB_REAL, dahdi_pvt::subs, dahdi_pvt::txdrc, and dahdi_pvt::txgain.
02553 { 02554 struct dahdi_pvt *pvt = p; 02555 int res; 02556 int dfd; 02557 int set_val; 02558 02559 dfd = pvt->subs[SUB_REAL].dfd; 02560 02561 /* Open the media path. */ 02562 set_val = 1; 02563 res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val); 02564 if (res < 0) { 02565 ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", 02566 pvt->channel, strerror(errno)); 02567 } 02568 02569 /* Set correct companding law for this call. */ 02570 res = dahdi_setlaw(dfd, pvt->law); 02571 if (res < 0) { 02572 ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pvt->channel); 02573 } 02574 02575 /* Set correct gain for this call. */ 02576 if (pvt->digital) { 02577 res = set_actual_gain(dfd, 0, 0, pvt->rxdrc, pvt->txdrc, pvt->law); 02578 } else { 02579 res = set_actual_gain(dfd, pvt->rxgain, pvt->txgain, pvt->rxdrc, pvt->txdrc, 02580 pvt->law); 02581 } 02582 if (res < 0) { 02583 ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pvt->channel); 02584 } 02585 02586 if (pvt->dsp_features && pvt->dsp) { 02587 ast_dsp_set_features(pvt->dsp, pvt->dsp_features); 02588 pvt->dsp_features = 0; 02589 } 02590 }
static int my_pri_play_tone | ( | void * | pvt, | |
enum sig_pri_tone | tone | |||
) | [static] |
Definition at line 3019 of file chan_dahdi.c.
References sig_pri_tone_to_dahditone(), SUB_REAL, and dahdi_pvt::subs.
03020 { 03021 struct dahdi_pvt *p = pvt; 03022 03023 return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_pri_tone_to_dahditone(tone)); 03024 }
static int my_ring | ( | void * | pvt | ) | [static] |
Definition at line 2794 of file chan_dahdi.c.
References dahdi_ring_phone().
02795 { 02796 struct dahdi_pvt *p = pvt; 02797 02798 return dahdi_ring_phone(p); 02799 }
static int my_send_callerid | ( | void * | pvt, | |
int | cwcid, | |||
struct ast_party_caller * | caller | |||
) | [static] |
Definition at line 1917 of file chan_dahdi.c.
References ast_callerid_callwaiting_generate(), ast_callerid_generate(), ast_debug, ast_free, AST_LAW, ast_log(), ast_malloc, ast_verb, dahdi_pvt::callwaitcas, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cidcwexpire, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, ast_party_caller::id, LOG_WARNING, MAX_CALLERID_SIZE, ast_party_id::name, ast_party_id::number, READ_SIZE, send_callerid(), ast_party_number::str, and ast_party_name::str.
01918 { 01919 struct dahdi_pvt *p = pvt; 01920 01921 ast_debug(2, "Starting cid spill\n"); 01922 01923 if (p->cidspill) { 01924 ast_log(LOG_WARNING, "cidspill already exists??\n"); 01925 ast_free(p->cidspill); 01926 } 01927 01928 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) { 01929 if (cwcid == 0) { 01930 p->cidlen = ast_callerid_generate(p->cidspill, 01931 caller->id.name.str, 01932 caller->id.number.str, 01933 AST_LAW(p)); 01934 } else { 01935 ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", 01936 caller->id.name.str, caller->id.number.str); 01937 p->callwaitcas = 0; 01938 p->cidcwexpire = 0; 01939 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, 01940 caller->id.name.str, 01941 caller->id.number.str, 01942 AST_LAW(p)); 01943 p->cidlen += READ_SIZE * 4; 01944 } 01945 p->cidpos = 0; 01946 p->cid_suppress_expire = 0; 01947 send_callerid(p); 01948 } 01949 return 0; 01950 }
static void my_set_alarm | ( | void * | pvt, | |
int | in_alarm | |||
) | [static] |
static void my_set_cadence | ( | void * | pvt, | |
int * | cidrings, | |||
struct ast_channel * | ast | |||
) | [static] |
Definition at line 2159 of file chan_dahdi.c.
References ast_log(), cadences, dahdi_pvt::distinctivering, errno, LOG_WARNING, ast_channel::name, num_cadence, dahdi_pvt::sendcalleridafter, SUB_REAL, and dahdi_pvt::subs.
02160 { 02161 struct dahdi_pvt *p = pvt; 02162 02163 /* Choose proper cadence */ 02164 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) { 02165 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1])) 02166 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno)); 02167 *cidrings = cidrings[p->distinctivering - 1]; 02168 } else { 02169 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL)) 02170 ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno)); 02171 *cidrings = p->sendcalleridafter; 02172 } 02173 }
static void my_set_callerid | ( | void * | pvt, | |
const struct ast_party_caller * | caller | |||
) | [static] |
Definition at line 3038 of file chan_dahdi.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_copy_string(), ast_party_id_presentation(), dahdi_pvt::callingpres, dahdi_pvt::cid_ani, dahdi_pvt::cid_ani2, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_subaddr, dahdi_pvt::cid_tag, dahdi_pvt::cid_ton, ast_party_caller::id, ast_party_id::name, ast_party_id::number, ast_party_number::plan, S_COR, ast_party_subaddress::str, ast_party_name::str, ast_party_number::str, ast_party_id::subaddress, ast_party_id::tag, ast_party_subaddress::valid, ast_party_name::valid, and ast_party_number::valid.
03039 { 03040 struct dahdi_pvt *p = pvt; 03041 03042 ast_copy_string(p->cid_num, 03043 S_COR(caller->id.number.valid, caller->id.number.str, ""), 03044 sizeof(p->cid_num)); 03045 ast_copy_string(p->cid_name, 03046 S_COR(caller->id.name.valid, caller->id.name.str, ""), 03047 sizeof(p->cid_name)); 03048 ast_copy_string(p->cid_subaddr, 03049 S_COR(caller->id.subaddress.valid, caller->id.subaddress.str, ""), 03050 sizeof(p->cid_subaddr)); 03051 p->cid_ton = caller->id.number.plan; 03052 p->callingpres = ast_party_id_presentation(&caller->id); 03053 if (caller->id.tag) { 03054 ast_copy_string(p->cid_tag, caller->id.tag, sizeof(p->cid_tag)); 03055 } 03056 ast_copy_string(p->cid_ani, 03057 S_COR(caller->ani.number.valid, caller->ani.number.str, ""), 03058 sizeof(p->cid_ani)); 03059 p->cid_ani2 = caller->ani2; 03060 }
static void my_set_callwaiting | ( | void * | pvt, | |
int | callwaiting_enable | |||
) | [static] |
Definition at line 2269 of file chan_dahdi.c.
References dahdi_pvt::callwaiting.
02270 { 02271 struct dahdi_pvt *p = pvt; 02272 02273 p->callwaiting = callwaiting_enable; 02274 }
static void my_set_confirmanswer | ( | void * | pvt, | |
int | flag | |||
) | [static] |
Definition at line 2253 of file chan_dahdi.c.
References dahdi_pvt::confirmanswer.
02254 { 02255 struct dahdi_pvt *p = pvt; 02256 p->confirmanswer = flag; 02257 }
static void my_set_dialing | ( | void * | pvt, | |
int | is_dialing | |||
) | [static] |
static void my_set_digital | ( | void * | pvt, | |
int | is_digital | |||
) | [static] |
static void my_set_dnid | ( | void * | pvt, | |
const char * | dnid | |||
) | [static] |
Definition at line 3074 of file chan_dahdi.c.
References ast_copy_string(), and dahdi_pvt::dnid.
03075 { 03076 struct dahdi_pvt *p = pvt; 03077 03078 ast_copy_string(p->dnid, dnid, sizeof(p->dnid)); 03079 }
static int my_set_echocanceller | ( | void * | pvt, | |
int | enable | |||
) | [static] |
Definition at line 2780 of file chan_dahdi.c.
References dahdi_disable_ec(), and dahdi_enable_ec().
02781 { 02782 struct dahdi_pvt *p = pvt; 02783 02784 if (enable) 02785 dahdi_enable_ec(p); 02786 else 02787 dahdi_disable_ec(p); 02788 02789 return 0; 02790 }
static void my_set_inservice | ( | void * | pvt, | |
int | is_inservice | |||
) | [static] |
static void my_set_inthreeway | ( | void * | pvt, | |
enum analog_sub | sub, | |||
int | inthreeway | |||
) | [static] |
Definition at line 2124 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_subchannel::inthreeway, and dahdi_pvt::subs.
02125 { 02126 struct dahdi_pvt *p = pvt; 02127 int idx = analogsub_to_dahdisub(sub); 02128 02129 p->subs[idx].inthreeway = inthreeway; 02130 }
static int my_set_linear_mode | ( | void * | pvt, | |
enum analog_sub | sub, | |||
int | linear_mode | |||
) | [static] |
Definition at line 2112 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_setlinear(), dahdi_subchannel::dfd, dahdi_subchannel::linear, and dahdi_pvt::subs.
02113 { 02114 struct dahdi_pvt *p = pvt; 02115 int oldval; 02116 int idx = analogsub_to_dahdisub(sub); 02117 02118 dahdi_setlinear(p->subs[idx].dfd, linear_mode); 02119 oldval = p->subs[idx].linear; 02120 p->subs[idx].linear = linear_mode ? 1 : 0; 02121 return oldval; 02122 }
static void my_set_locallyblocked | ( | void * | pvt, | |
int | is_blocked | |||
) | [static] |
Definition at line 2208 of file chan_dahdi.c.
References dahdi_pvt::locallyblocked.
02209 { 02210 struct dahdi_pvt *p = pvt; 02211 02212 p->locallyblocked = is_blocked; 02213 }
static void my_set_needringing | ( | void * | pvt, | |
int | value | |||
) | [static] |
Definition at line 2816 of file chan_dahdi.c.
References dahdi_subchannel::needringing, SUB_REAL, and dahdi_pvt::subs.
02817 { 02818 struct dahdi_pvt *p = pvt; 02819 p->subs[SUB_REAL].needringing = value; 02820 }
static void my_set_new_owner | ( | void * | pvt, | |
struct ast_channel * | new_owner | |||
) | [static] |
static void my_set_polarity | ( | void * | pvt, | |
int | value | |||
) | [static] |
Definition at line 2822 of file chan_dahdi.c.
References CHAN_PSEUDO, dahdi_pvt::channel, dahdi_pvt::polarity, SUB_REAL, and dahdi_pvt::subs.
Referenced by my_answer_polarityswitch(), my_hangup_polarityswitch(), and my_start_polarityswitch().
02823 { 02824 struct dahdi_pvt *p = pvt; 02825 02826 if (p->channel == CHAN_PSEUDO) { 02827 return; 02828 } 02829 p->polarity = value; 02830 ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETPOLARITY, &value); 02831 }
static void my_set_pulsedial | ( | void * | pvt, | |
int | flag | |||
) | [static] |
static void my_set_rdnis | ( | void * | pvt, | |
const char * | rdnis | |||
) | [static] |
Definition at line 3093 of file chan_dahdi.c.
References ast_copy_string(), and dahdi_pvt::rdnis.
03094 { 03095 struct dahdi_pvt *p = pvt; 03096 03097 ast_copy_string(p->rdnis, rdnis, sizeof(p->rdnis)); 03098 }
static void my_set_remotelyblocked | ( | void * | pvt, | |
int | is_blocked | |||
) | [static] |
Definition at line 2217 of file chan_dahdi.c.
References dahdi_pvt::remotelyblocked.
02218 { 02219 struct dahdi_pvt *p = pvt; 02220 02221 p->remotelyblocked = is_blocked; 02222 }
static void my_set_ringtimeout | ( | void * | pvt, | |
int | ringt | |||
) | [static] |
static void my_set_waitingfordt | ( | void * | pvt, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 2231 of file chan_dahdi.c.
References ast_log(), ast_setstate(), AST_STATE_OFFHOOK, CANPROGRESSDETECT, dahdi_pvt::dsp, LOG_DEBUG, dahdi_pvt::waitfordialtone, and dahdi_pvt::waitingfordt.
02232 { 02233 struct dahdi_pvt *p = pvt; 02234 02235 if (p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp) { 02236 ast_log(LOG_DEBUG, "Defer dialing for %dms or dialtone\n", p->waitfordialtone); 02237 gettimeofday(&p->waitingfordt, NULL); 02238 ast_setstate(ast, AST_STATE_OFFHOOK); 02239 } 02240 }
static int my_ss7_play_tone | ( | void * | pvt, | |
enum sig_ss7_tone | tone | |||
) | [static] |
Definition at line 3425 of file chan_dahdi.c.
References sig_ss7_tone_to_dahditone(), SUB_REAL, and dahdi_pvt::subs.
03426 { 03427 struct dahdi_pvt *p = pvt; 03428 03429 return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_ss7_tone_to_dahditone(tone)); 03430 }
static void my_ss7_set_loopback | ( | void * | pvt, | |
int | enable | |||
) | [static] |
Definition at line 3339 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.
03340 { 03341 struct dahdi_pvt *p = pvt; 03342 03343 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_LOOPBACK, &enable)) { 03344 ast_log(LOG_WARNING, "Unable to set loopback on channel %d: %s\n", p->channel, 03345 strerror(errno)); 03346 } 03347 }
static int my_start | ( | void * | pvt | ) | [static] |
Definition at line 2868 of file chan_dahdi.c.
References SUB_REAL, and dahdi_pvt::subs.
02869 { 02870 struct dahdi_pvt *p = pvt; 02871 int x = DAHDI_START; 02872 02873 return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 02874 }
static int my_start_cid_detect | ( | void * | pvt, | |
int | cid_signalling | |||
) | [static] |
Definition at line 1646 of file chan_dahdi.c.
References ast_log(), bump_gains(), callerid_new(), dahdi_pvt::cs, dahdi_setlinear(), dahdi_subchannel::dfd, LOG_ERROR, SUB_REAL, and dahdi_pvt::subs.
01647 { 01648 struct dahdi_pvt *p = pvt; 01649 int index = SUB_REAL; 01650 p->cs = callerid_new(cid_signalling); 01651 if (!p->cs) { 01652 ast_log(LOG_ERROR, "Unable to alloc callerid\n"); 01653 return -1; 01654 } 01655 bump_gains(p); 01656 dahdi_setlinear(p->subs[index].dfd, 0); 01657 01658 return 0; 01659 }
static void my_start_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2833 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, dahdi_pvt::hanguponpolarityswitch, and my_set_polarity().
02834 { 02835 struct dahdi_pvt *p = pvt; 02836 02837 if (p->answeronpolarityswitch || p->hanguponpolarityswitch) { 02838 my_set_polarity(pvt, 0); 02839 } 02840 }
static int my_stop_callwait | ( | void * | pvt | ) | [static] |
Definition at line 1870 of file chan_dahdi.c.
References dahdi_pvt::callwaitingrepeat, dahdi_pvt::cid_suppress_expire, and dahdi_pvt::cidcwexpire.
01871 { 01872 struct dahdi_pvt *p = pvt; 01873 p->callwaitingrepeat = 0; 01874 p->cidcwexpire = 0; 01875 p->cid_suppress_expire = 0; 01876 01877 return 0; 01878 }
static int my_stop_cid_detect | ( | void * | pvt | ) | [static] |
Definition at line 1661 of file chan_dahdi.c.
References callerid_free(), dahdi_pvt::cs, dahdi_setlinear(), dahdi_subchannel::dfd, dahdi_subchannel::linear, SUB_REAL, and dahdi_pvt::subs.
01662 { 01663 struct dahdi_pvt *p = pvt; 01664 int index = SUB_REAL; 01665 if (p->cs) 01666 callerid_free(p->cs); 01667 dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear); 01668 return 0; 01669 }
static void my_swap_subchannels | ( | void * | pvt, | |
enum analog_sub | a, | |||
struct ast_channel * | ast_a, | |||
enum analog_sub | b, | |||
struct ast_channel * | ast_b | |||
) | [static] |
Definition at line 2442 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_channel_set_fd(), dahdi_subchannel::chan, db, dahdi_subchannel::dfd, dahdi_subchannel::inthreeway, dahdi_subchannel::owner, dahdi_pvt::subs, and wakeup_sub().
02443 { 02444 struct dahdi_pvt *p = pvt; 02445 int da, db; 02446 int tchan; 02447 int tinthreeway; 02448 02449 da = analogsub_to_dahdisub(a); 02450 db = analogsub_to_dahdisub(b); 02451 02452 tchan = p->subs[da].chan; 02453 p->subs[da].chan = p->subs[db].chan; 02454 p->subs[db].chan = tchan; 02455 02456 tinthreeway = p->subs[da].inthreeway; 02457 p->subs[da].inthreeway = p->subs[db].inthreeway; 02458 p->subs[db].inthreeway = tinthreeway; 02459 02460 p->subs[da].owner = ast_a; 02461 p->subs[db].owner = ast_b; 02462 02463 if (ast_a) 02464 ast_channel_set_fd(ast_a, 0, p->subs[da].dfd); 02465 if (ast_b) 02466 ast_channel_set_fd(ast_b, 0, p->subs[db].dfd); 02467 02468 wakeup_sub(p, a); 02469 wakeup_sub(p, b); 02470 02471 return; 02472 }
static int my_train_echocanceller | ( | void * | pvt | ) | [static] |
Definition at line 2906 of file chan_dahdi.c.
References dahdi_train_ec().
02907 { 02908 struct dahdi_pvt *p = pvt; 02909 02910 dahdi_train_ec(p); 02911 02912 return 0; 02913 }
static int my_unallocate_sub | ( | void * | pvt, | |
enum analog_sub | analogsub | |||
) | [static] |
Definition at line 2595 of file chan_dahdi.c.
References analogsub_to_dahdisub(), and unalloc_sub().
02596 { 02597 struct dahdi_pvt *p = pvt; 02598 02599 return unalloc_sub(p, analogsub_to_dahdisub(analogsub)); 02600 }
static void my_unlock_private | ( | void * | pvt | ) | [static] |
Definition at line 2096 of file chan_dahdi.c.
References ast_mutex_unlock, and dahdi_pvt::lock.
02097 { 02098 struct dahdi_pvt *p = pvt; 02099 ast_mutex_unlock(&p->lock); 02100 }
static int my_wait_event | ( | void * | pvt | ) | [static] |
Definition at line 2727 of file chan_dahdi.c.
References dahdi_wait_event(), SUB_REAL, and dahdi_pvt::subs.
02728 { 02729 struct dahdi_pvt *p = pvt; 02730 02731 return dahdi_wait_event(p->subs[SUB_REAL].dfd); 02732 }
static int my_wink | ( | void * | pvt, | |
enum analog_sub | sub | |||
) | [static] |
Definition at line 2002 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_log(), dahdi_wink(), LOG_ERROR, and SUB_REAL.
02003 { 02004 struct dahdi_pvt *p = pvt; 02005 int index = analogsub_to_dahdisub(sub); 02006 if (index != SUB_REAL) { 02007 ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n"); 02008 } 02009 return dahdi_wink(p, index); 02010 }
static void notify_message | ( | char * | mailbox_full, | |
int | thereornot | |||
) | [static] |
Send MWI state change.
1) It generates an internal Asterisk event notifying any other module that cares about MWI that the state of a mailbox has changed.
2) It runs the script specified by the mwimonitornotify option to allow some custom handling of the state change.
Definition at line 3475 of file chan_dahdi.c.
References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_safe_system(), ast_strdupa, ast_strlen_zero(), context, mailbox, mwimonitornotify, and strsep().
Referenced by handle_init_event(), and my_handle_notify_message().
03476 { 03477 char s[sizeof(mwimonitornotify) + 80]; 03478 struct ast_event *event; 03479 char *mailbox, *context; 03480 03481 /* Strip off @default */ 03482 context = mailbox = ast_strdupa(mailbox_full); 03483 strsep(&context, "@"); 03484 if (ast_strlen_zero(context)) 03485 context = "default"; 03486 03487 if (!(event = ast_event_new(AST_EVENT_MWI, 03488 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 03489 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 03490 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot, 03491 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot, 03492 AST_EVENT_IE_END))) { 03493 return; 03494 } 03495 03496 ast_event_queue_and_cache(event); 03497 03498 if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) { 03499 snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot); 03500 ast_safe_system(s); 03501 } 03502 }
static int parse_buffers_policy | ( | const char * | parse, | |
int * | num_buffers, | |||
int * | policy | |||
) | [static] |
Definition at line 6820 of file chan_dahdi.c.
References ast_log(), and LOG_WARNING.
Referenced by dahdi_func_write().
06821 { 06822 int res; 06823 char policy_str[21] = ""; 06824 06825 if ((res = sscanf(parse, "%30d,%20s", num_buffers, policy_str)) != 2) { 06826 ast_log(LOG_WARNING, "Parsing buffer string '%s' failed.\n", parse); 06827 return 1; 06828 } 06829 if (*num_buffers < 0) { 06830 ast_log(LOG_WARNING, "Invalid buffer count given '%d'.\n", *num_buffers); 06831 return -1; 06832 } 06833 if (!strcasecmp(policy_str, "full")) { 06834 *policy = DAHDI_POLICY_WHEN_FULL; 06835 } else if (!strcasecmp(policy_str, "immediate")) { 06836 *policy = DAHDI_POLICY_IMMEDIATE; 06837 #if defined(HAVE_DAHDI_HALF_FULL) 06838 } else if (!strcasecmp(policy_str, "half")) { 06839 *policy = DAHDI_POLICY_HALF_FULL; 06840 #endif 06841 } else { 06842 ast_log(LOG_WARNING, "Invalid policy name given '%s'.\n", policy_str); 06843 return -1; 06844 } 06845 06846 return 0; 06847 }
static unsigned int parse_pointcode | ( | const char * | pcstring | ) | [static] |
Definition at line 11739 of file chan_dahdi.c.
11740 { 11741 unsigned int code1, code2, code3; 11742 int numvals; 11743 11744 numvals = sscanf(pcstring, "%30d-%30d-%30d", &code1, &code2, &code3); 11745 if (numvals == 1) 11746 return code1; 11747 if (numvals == 3) 11748 return (code1 << 16) | (code2 << 8) | code3; 11749 11750 return 0; 11751 }
static char* parse_spanchan | ( | char * | chanstr, | |
char ** | subdir | |||
) | [static] |
Definition at line 16294 of file chan_dahdi.c.
References string_replace().
Referenced by build_channels().
16295 { 16296 char *p; 16297 16298 if ((p = strrchr(chanstr, '!')) == NULL) { 16299 *subdir = NULL; 16300 return chanstr; 16301 } 16302 *p++ = '\0'; 16303 string_replace(chanstr, '!', '/'); 16304 *subdir = chanstr; 16305 return p; 16306 }
static int prepare_pri | ( | struct dahdi_pri * | pri | ) | [static] |
Definition at line 13766 of file chan_dahdi.c.
References ast_log(), sig_pri_span::calls, dahdi_close_pri_fd(), dahdi_pri_callbacks, sig_pri_span::dchan_logical_span, dahdi_pri::dchannels, errno, sig_pri_span::fds, dahdi_pri::pri, pri_event_alarm(), pri_event_noalarm(), dahdi_pri::prilogicalspan, and pris.
Referenced by setup_dahdi_int().
13767 { 13768 int i, res, x; 13769 struct dahdi_params p; 13770 struct dahdi_bufferinfo bi; 13771 struct dahdi_spaninfo si; 13772 13773 pri->pri.calls = &dahdi_pri_callbacks; 13774 13775 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 13776 if (!pri->dchannels[i]) 13777 break; 13778 pri->pri.fds[i] = open("/dev/dahdi/channel", O_RDWR); 13779 x = pri->dchannels[i]; 13780 if ((pri->pri.fds[i] < 0) || (ioctl(pri->pri.fds[i],DAHDI_SPECIFY,&x) == -1)) { 13781 ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno)); 13782 return -1; 13783 } 13784 memset(&p, 0, sizeof(p)); 13785 res = ioctl(pri->pri.fds[i], DAHDI_GET_PARAMS, &p); 13786 if (res) { 13787 dahdi_close_pri_fd(pri, i); 13788 ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno)); 13789 return -1; 13790 } 13791 if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC)) { 13792 dahdi_close_pri_fd(pri, i); 13793 ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.\n", x); 13794 return -1; 13795 } 13796 memset(&si, 0, sizeof(si)); 13797 res = ioctl(pri->pri.fds[i], DAHDI_SPANSTAT, &si); 13798 if (res) { 13799 dahdi_close_pri_fd(pri, i); 13800 ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno)); 13801 } 13802 if (!si.alarms) { 13803 pri_event_noalarm(&pri->pri, i, 1); 13804 } else { 13805 pri_event_alarm(&pri->pri, i, 1); 13806 } 13807 memset(&bi, 0, sizeof(bi)); 13808 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; 13809 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; 13810 bi.numbufs = 32; 13811 bi.bufsize = 1024; 13812 if (ioctl(pri->pri.fds[i], DAHDI_SET_BUFINFO, &bi)) { 13813 ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d: %s\n", x, strerror(errno)); 13814 dahdi_close_pri_fd(pri, i); 13815 return -1; 13816 } 13817 pri->pri.dchan_logical_span[i] = pris[p.spanno - 1].prilogicalspan; 13818 } 13819 return 0; 13820 }
static int pri_create_spanmap | ( | int | span, | |
int | trunkgroup, | |||
int | logicalspan | |||
) | [static] |
Definition at line 11726 of file chan_dahdi.c.
References ast_log(), dahdi_pri::mastertrunkgroup, dahdi_pri::prilogicalspan, and pris.
Referenced by setup_dahdi_int().
11727 { 11728 if (pris[span].mastertrunkgroup) { 11729 ast_log(LOG_WARNING, "Span %d is already part of trunk group %d, cannot add to trunk group %d\n", span + 1, pris[span].mastertrunkgroup, trunkgroup); 11730 return -1; 11731 } 11732 pris[span].mastertrunkgroup = trunkgroup; 11733 pris[span].prilogicalspan = logicalspan; 11734 return 0; 11735 }
static int pri_create_trunkgroup | ( | int | trunkgroup, | |
int * | channels | |||
) | [static] |
Definition at line 11663 of file chan_dahdi.c.
References ast_log(), NUM_SPANS, and pris.
Referenced by setup_dahdi_int().
11664 { 11665 struct dahdi_spaninfo si; 11666 struct dahdi_params p; 11667 int fd; 11668 int span; 11669 int ospan=0; 11670 int x,y; 11671 for (x = 0; x < NUM_SPANS; x++) { 11672 if (pris[x].pri.trunkgroup == trunkgroup) { 11673 ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]); 11674 return -1; 11675 } 11676 } 11677 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 11678 if (!channels[y]) 11679 break; 11680 memset(&si, 0, sizeof(si)); 11681 memset(&p, 0, sizeof(p)); 11682 fd = open("/dev/dahdi/channel", O_RDWR); 11683 if (fd < 0) { 11684 ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno)); 11685 return -1; 11686 } 11687 x = channels[y]; 11688 if (ioctl(fd, DAHDI_SPECIFY, &x)) { 11689 ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno)); 11690 close(fd); 11691 return -1; 11692 } 11693 if (ioctl(fd, DAHDI_GET_PARAMS, &p)) { 11694 ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno)); 11695 return -1; 11696 } 11697 if (ioctl(fd, DAHDI_SPANSTAT, &si)) { 11698 ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d): %s\n", channels[y], p.spanno, strerror(errno)); 11699 close(fd); 11700 return -1; 11701 } 11702 span = p.spanno - 1; 11703 if (pris[span].pri.trunkgroup) { 11704 ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].pri.trunkgroup); 11705 close(fd); 11706 return -1; 11707 } 11708 if (pris[span].pri.pvts[0]) { 11709 ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1); 11710 close(fd); 11711 return -1; 11712 } 11713 if (!y) { 11714 pris[span].pri.trunkgroup = trunkgroup; 11715 ospan = span; 11716 } 11717 pris[ospan].dchannels[y] = channels[y]; 11718 pris[span].pri.span = span + 1; 11719 close(fd); 11720 } 11721 return 0; 11722 }
static int pri_resolve_span | ( | int * | span, | |
int | channel, | |||
int | offset, | |||
struct dahdi_spaninfo * | si | |||
) | [static] |
Definition at line 11617 of file chan_dahdi.c.
References ast_log(), dahdi_pri::mastertrunkgroup, NUM_SPANS, dahdi_pvt::pri, pris, and sig_pri_span::trunkgroup.
11618 { 11619 int x; 11620 int trunkgroup; 11621 /* Get appropriate trunk group if there is one */ 11622 trunkgroup = pris[*span].mastertrunkgroup; 11623 if (trunkgroup) { 11624 /* Select a specific trunk group */ 11625 for (x = 0; x < NUM_SPANS; x++) { 11626 if (pris[x].pri.trunkgroup == trunkgroup) { 11627 *span = x; 11628 return 0; 11629 } 11630 } 11631 ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup); 11632 *span = -1; 11633 } else { 11634 if (pris[*span].pri.trunkgroup) { 11635 ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].pri.trunkgroup); 11636 *span = -1; 11637 } else if (pris[*span].mastertrunkgroup) { 11638 ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup); 11639 *span = -1; 11640 } else { 11641 if (si->totalchans == 31) { 11642 /* E1 */ 11643 pris[*span].dchannels[0] = 16 + offset; 11644 } else if (si->totalchans == 24) { 11645 /* T1 or J1 */ 11646 pris[*span].dchannels[0] = 24 + offset; 11647 } else if (si->totalchans == 3) { 11648 /* BRI */ 11649 pris[*span].dchannels[0] = 3 + offset; 11650 } else { 11651 ast_log(LOG_WARNING, "Unable to use span %d, since the D-channel cannot be located (unexpected span size of %d channels)\n", *span, si->totalchans); 11652 *span = -1; 11653 return 0; 11654 } 11655 pris[*span].pri.span = *span + 1; 11656 } 11657 } 11658 return 0; 11659 }
static int process_dahdi | ( | struct dahdi_chan_conf * | confp, | |
const char * | cat, | |||
struct ast_variable * | v, | |||
int | reload, | |||
int | options | |||
) | [static] |
Definition at line 16437 of file chan_dahdi.c.
References ast_copy_string(), ast_jb_read_conf(), ast_log(), build_channels(), dahdi_chan_conf::chan, global_jbconf, ast_variable::lineno, MAX_CHANLIST_LEN, ast_variable::name, ast_variable::next, dahdi_pvt::parkinglot, PROC_DAHDI_OPT_NOCHAN, and ast_variable::value.
Referenced by setup_dahdi_int().
16438 { 16439 struct dahdi_pvt *tmp; 16440 int y; 16441 int found_pseudo = 0; 16442 char dahdichan[MAX_CHANLIST_LEN] = {}; 16443 16444 for (; v; v = v->next) { 16445 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 16446 continue; 16447 16448 /* must have parkinglot in confp before build_channels is called */ 16449 if (!strcasecmp(v->name, "parkinglot")) { 16450 ast_copy_string(confp->chan.parkinglot, v->value, sizeof(confp->chan.parkinglot)); 16451 } 16452 16453 /* Create the interface list */ 16454 if (!strcasecmp(v->name, "channel") || !strcasecmp(v->name, "channels")) { 16455 if (options & PROC_DAHDI_OPT_NOCHAN) { 16456 ast_log(LOG_WARNING, "Channel '%s' ignored.\n", v->value); 16457 continue; 16458 } 16459 if (build_channels(confp, v->value, reload, v->lineno, &found_pseudo)) { 16460 if (confp->ignore_failed_channels) { 16461 ast_log(LOG_WARNING, "Channel '%s' failure ignored: ignore_failed_channels.\n", v->value); 16462 continue; 16463 } else { 16464 return -1; 16465 } 16466 } 16467 ast_log(LOG_DEBUG, "Channel '%s' configured.\n", v->value); 16468 } else if (!strcasecmp(v->name, "ignore_failed_channels")) { 16469 confp->ignore_failed_channels = ast_true(v->value); 16470 } else if (!strcasecmp(v->name, "buffers")) { 16471 if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) { 16472 ast_log(LOG_WARNING, "Using default buffer policy.\n"); 16473 confp->chan.buf_no = numbufs; 16474 confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE; 16475 } 16476 } else if (!strcasecmp(v->name, "faxbuffers")) { 16477 if (!parse_buffers_policy(v->value, &confp->chan.faxbuf_no, &confp->chan.faxbuf_policy)) { 16478 confp->chan.usefaxbuffers = 1; 16479 } 16480 } else if (!strcasecmp(v->name, "dahdichan")) { 16481 ast_copy_string(dahdichan, v->value, sizeof(dahdichan)); 16482 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 16483 usedistinctiveringdetection = ast_true(v->value); 16484 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) { 16485 distinctiveringaftercid = ast_true(v->value); 16486 } else if (!strcasecmp(v->name, "dring1context")) { 16487 ast_copy_string(confp->chan.drings.ringContext[0].contextData,v->value,sizeof(confp->chan.drings.ringContext[0].contextData)); 16488 } else if (!strcasecmp(v->name, "dring2context")) { 16489 ast_copy_string(confp->chan.drings.ringContext[1].contextData,v->value,sizeof(confp->chan.drings.ringContext[1].contextData)); 16490 } else if (!strcasecmp(v->name, "dring3context")) { 16491 ast_copy_string(confp->chan.drings.ringContext[2].contextData,v->value,sizeof(confp->chan.drings.ringContext[2].contextData)); 16492 } else if (!strcasecmp(v->name, "dring1range")) { 16493 confp->chan.drings.ringnum[0].range = atoi(v->value); 16494 } else if (!strcasecmp(v->name, "dring2range")) { 16495 confp->chan.drings.ringnum[1].range = atoi(v->value); 16496 } else if (!strcasecmp(v->name, "dring3range")) { 16497 confp->chan.drings.ringnum[2].range = atoi(v->value); 16498 } else if (!strcasecmp(v->name, "dring1")) { 16499 sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[0].ring[0], &confp->chan.drings.ringnum[0].ring[1], &confp->chan.drings.ringnum[0].ring[2]); 16500 } else if (!strcasecmp(v->name, "dring2")) { 16501 sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[1].ring[0], &confp->chan.drings.ringnum[1].ring[1], &confp->chan.drings.ringnum[1].ring[2]); 16502 } else if (!strcasecmp(v->name, "dring3")) { 16503 sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[2].ring[0], &confp->chan.drings.ringnum[2].ring[1], &confp->chan.drings.ringnum[2].ring[2]); 16504 } else if (!strcasecmp(v->name, "usecallerid")) { 16505 confp->chan.use_callerid = ast_true(v->value); 16506 } else if (!strcasecmp(v->name, "cidsignalling")) { 16507 if (!strcasecmp(v->value, "bell")) 16508 confp->chan.cid_signalling = CID_SIG_BELL; 16509 else if (!strcasecmp(v->value, "v23")) 16510 confp->chan.cid_signalling = CID_SIG_V23; 16511 else if (!strcasecmp(v->value, "dtmf")) 16512 confp->chan.cid_signalling = CID_SIG_DTMF; 16513 else if (!strcasecmp(v->value, "smdi")) 16514 confp->chan.cid_signalling = CID_SIG_SMDI; 16515 else if (!strcasecmp(v->value, "v23_jp")) 16516 confp->chan.cid_signalling = CID_SIG_V23_JP; 16517 else if (ast_true(v->value)) 16518 confp->chan.cid_signalling = CID_SIG_BELL; 16519 } else if (!strcasecmp(v->name, "cidstart")) { 16520 if (!strcasecmp(v->value, "ring")) 16521 confp->chan.cid_start = CID_START_RING; 16522 else if (!strcasecmp(v->value, "polarity_in")) 16523 confp->chan.cid_start = CID_START_POLARITY_IN; 16524 else if (!strcasecmp(v->value, "polarity")) 16525 confp->chan.cid_start = CID_START_POLARITY; 16526 else if (!strcasecmp(v->value, "dtmf")) 16527 confp->chan.cid_start = CID_START_DTMF_NOALERT; 16528 else if (ast_true(v->value)) 16529 confp->chan.cid_start = CID_START_RING; 16530 } else if (!strcasecmp(v->name, "threewaycalling")) { 16531 confp->chan.threewaycalling = ast_true(v->value); 16532 } else if (!strcasecmp(v->name, "cancallforward")) { 16533 confp->chan.cancallforward = ast_true(v->value); 16534 } else if (!strcasecmp(v->name, "relaxdtmf")) { 16535 if (ast_true(v->value)) 16536 confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 16537 else 16538 confp->chan.dtmfrelax = 0; 16539 } else if (!strcasecmp(v->name, "mailbox")) { 16540 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox)); 16541 } else if (!strcasecmp(v->name, "hasvoicemail")) { 16542 if (ast_true(v->value) && ast_strlen_zero(confp->chan.mailbox)) { 16543 ast_copy_string(confp->chan.mailbox, cat, sizeof(confp->chan.mailbox)); 16544 } 16545 } else if (!strcasecmp(v->name, "adsi")) { 16546 confp->chan.adsi = ast_true(v->value); 16547 } else if (!strcasecmp(v->name, "usesmdi")) { 16548 confp->chan.use_smdi = ast_true(v->value); 16549 } else if (!strcasecmp(v->name, "smdiport")) { 16550 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port)); 16551 } else if (!strcasecmp(v->name, "transfer")) { 16552 confp->chan.transfer = ast_true(v->value); 16553 } else if (!strcasecmp(v->name, "canpark")) { 16554 confp->chan.canpark = ast_true(v->value); 16555 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 16556 confp->chan.echocanbridged = ast_true(v->value); 16557 } else if (!strcasecmp(v->name, "busydetect")) { 16558 confp->chan.busydetect = ast_true(v->value); 16559 } else if (!strcasecmp(v->name, "busycount")) { 16560 confp->chan.busycount = atoi(v->value); 16561 } else if (!strcasecmp(v->name, "silencethreshold")) { 16562 confp->chan.silencethreshold = atoi(v->value); 16563 } else if (!strcasecmp(v->name, "busycompare")) { 16564 confp->chan.busycompare = ast_true(v->value); 16565 } else if (!strcasecmp(v->name, "busypattern")) { 16566 if (sscanf(v->value, "%30d,%30d", &confp->chan.busytonelength, &confp->chan.busyquietlength) != 2) { 16567 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength at line %d.\n", v->lineno); 16568 } 16569 int count = sscanf(v->value, "%d,%d", &confp->chan.busytonelength, &confp->chan.busyquietlength); 16570 if (count == 1) 16571 confp->chan.busyquietlength = 0; 16572 else if (count < 1) 16573 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength[,quietlength] at line %d.\n", v->lineno); 16574 } else if (!strcasecmp(v->name, "busyfuzziness")) { 16575 confp->chan.busyfuzziness = atoi(v->value); 16576 } else if (!strcasecmp(v->name, "callprogress")) { 16577 confp->chan.callprogress &= ~CALLPROGRESS_PROGRESS; 16578 if (ast_true(v->value)) 16579 confp->chan.callprogress |= CALLPROGRESS_PROGRESS; 16580 } else if (!strcasecmp(v->name, "waitfordialtone")) { 16581 confp->chan.waitfordialtone = atoi(v->value); 16582 } else if (!strcasecmp(v->name, "faxdetect")) { 16583 confp->chan.callprogress &= ~CALLPROGRESS_FAX; 16584 if (!strcasecmp(v->value, "incoming")) { 16585 confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING; 16586 } else if (!strcasecmp(v->value, "outgoing")) { 16587 confp->chan.callprogress |= CALLPROGRESS_FAX_OUTGOING; 16588 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 16589 confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING; 16590 } else if (!strcasecmp(v->name, "echocancel")) { 16591 process_echocancel(confp, v->value, v->lineno); 16592 } else if (!strcasecmp(v->name, "echotraining")) { 16593 if (sscanf(v->value, "%30d", &y) == 1) { 16594 if ((y < 10) || (y > 4000)) { 16595 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d.\n", v->lineno); 16596 } else { 16597 confp->chan.echotraining = y; 16598 } 16599 } else if (ast_true(v->value)) { 16600 confp->chan.echotraining = 400; 16601 } else 16602 confp->chan.echotraining = 0; 16603 } else if (!strcasecmp(v->name, "hidecallerid")) { 16604 confp->chan.hidecallerid = ast_true(v->value); 16605 } else if (!strcasecmp(v->name, "hidecalleridname")) { 16606 confp->chan.hidecalleridname = ast_true(v->value); 16607 } else if (!strcasecmp(v->name, "pulsedial")) { 16608 confp->chan.pulse = ast_true(v->value); 16609 } else if (!strcasecmp(v->name, "callreturn")) { 16610 confp->chan.callreturn = ast_true(v->value); 16611 } else if (!strcasecmp(v->name, "callwaiting")) { 16612 confp->chan.callwaiting = ast_true(v->value); 16613 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 16614 confp->chan.callwaitingcallerid = ast_true(v->value); 16615 } else if (!strcasecmp(v->name, "context")) { 16616 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context)); 16617 } else if (!strcasecmp(v->name, "language")) { 16618 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language)); 16619 } else if (!strcasecmp(v->name, "progzone")) { 16620 ast_copy_string(progzone, v->value, sizeof(progzone)); 16621 } else if (!strcasecmp(v->name, "mohinterpret") 16622 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) { 16623 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret)); 16624 } else if (!strcasecmp(v->name, "mohsuggest")) { 16625 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest)); 16626 } else if (!strcasecmp(v->name, "parkinglot")) { 16627 ast_copy_string(parkinglot, v->value, sizeof(parkinglot)); 16628 } else if (!strcasecmp(v->name, "stripmsd")) { 16629 ast_log(LOG_NOTICE, "Configuration option \"%s\" has been deprecated. Please use dialplan instead\n", v->name); 16630 confp->chan.stripmsd = atoi(v->value); 16631 } else if (!strcasecmp(v->name, "jitterbuffers")) { 16632 numbufs = atoi(v->value); 16633 } else if (!strcasecmp(v->name, "group")) { 16634 confp->chan.group = ast_get_group(v->value); 16635 } else if (!strcasecmp(v->name, "callgroup")) { 16636 if (!strcasecmp(v->value, "none")) 16637 confp->chan.callgroup = 0; 16638 else 16639 confp->chan.callgroup = ast_get_group(v->value); 16640 } else if (!strcasecmp(v->name, "pickupgroup")) { 16641 if (!strcasecmp(v->value, "none")) 16642 confp->chan.pickupgroup = 0; 16643 else 16644 confp->chan.pickupgroup = ast_get_group(v->value); 16645 } else if (!strcasecmp(v->name, "setvar")) { 16646 char *varname = ast_strdupa(v->value), *varval = NULL; 16647 struct ast_variable *tmpvar; 16648 if (varname && (varval = strchr(varname, '='))) { 16649 *varval++ = '\0'; 16650 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 16651 tmpvar->next = confp->chan.vars; 16652 confp->chan.vars = tmpvar; 16653 } 16654 } 16655 } else if (!strcasecmp(v->name, "immediate")) { 16656 confp->chan.immediate = ast_true(v->value); 16657 } else if (!strcasecmp(v->name, "transfertobusy")) { 16658 confp->chan.transfertobusy = ast_true(v->value); 16659 } else if (!strcasecmp(v->name, "mwimonitor")) { 16660 confp->chan.mwimonitor_neon = 0; 16661 confp->chan.mwimonitor_fsk = 0; 16662 confp->chan.mwimonitor_rpas = 0; 16663 if (strcasestr(v->value, "fsk")) { 16664 confp->chan.mwimonitor_fsk = 1; 16665 } 16666 if (strcasestr(v->value, "rpas")) { 16667 confp->chan.mwimonitor_rpas = 1; 16668 } 16669 if (strcasestr(v->value, "neon")) { 16670 confp->chan.mwimonitor_neon = 1; 16671 } 16672 /* If set to true or yes, assume that simple fsk is desired */ 16673 if (ast_true(v->value)) { 16674 confp->chan.mwimonitor_fsk = 1; 16675 } 16676 } else if (!strcasecmp(v->name, "cid_rxgain")) { 16677 if (sscanf(v->value, "%30f", &confp->chan.cid_rxgain) != 1) { 16678 ast_log(LOG_WARNING, "Invalid cid_rxgain: %s at line %d.\n", v->value, v->lineno); 16679 } 16680 } else if (!strcasecmp(v->name, "rxgain")) { 16681 if (sscanf(v->value, "%30f", &confp->chan.rxgain) != 1) { 16682 ast_log(LOG_WARNING, "Invalid rxgain: %s at line %d.\n", v->value, v->lineno); 16683 } 16684 } else if (!strcasecmp(v->name, "txgain")) { 16685 if (sscanf(v->value, "%30f", &confp->chan.txgain) != 1) { 16686 ast_log(LOG_WARNING, "Invalid txgain: %s at line %d.\n", v->value, v->lineno); 16687 } 16688 } else if (!strcasecmp(v->name, "txdrc")) { 16689 if (sscanf(v->value, "%f", &confp->chan.txdrc) != 1) { 16690 ast_log(LOG_WARNING, "Invalid txdrc: %s\n", v->value); 16691 } 16692 } else if (!strcasecmp(v->name, "rxdrc")) { 16693 if (sscanf(v->value, "%f", &confp->chan.rxdrc) != 1) { 16694 ast_log(LOG_WARNING, "Invalid rxdrc: %s\n", v->value); 16695 } 16696 } else if (!strcasecmp(v->name, "tonezone")) { 16697 if (sscanf(v->value, "%30d", &confp->chan.tonezone) != 1) { 16698 ast_log(LOG_WARNING, "Invalid tonezone: %s at line %d.\n", v->value, v->lineno); 16699 } 16700 } else if (!strcasecmp(v->name, "callerid")) { 16701 if (!strcasecmp(v->value, "asreceived")) { 16702 confp->chan.cid_num[0] = '\0'; 16703 confp->chan.cid_name[0] = '\0'; 16704 } else { 16705 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num)); 16706 } 16707 } else if (!strcasecmp(v->name, "fullname")) { 16708 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name)); 16709 } else if (!strcasecmp(v->name, "cid_number")) { 16710 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num)); 16711 } else if (!strcasecmp(v->name, "cid_tag")) { 16712 ast_copy_string(confp->chan.cid_tag, v->value, sizeof(confp->chan.cid_tag)); 16713 } else if (!strcasecmp(v->name, "useincomingcalleridondahditransfer")) { 16714 confp->chan.dahditrcallerid = ast_true(v->value); 16715 } else if (!strcasecmp(v->name, "restrictcid")) { 16716 confp->chan.restrictcid = ast_true(v->value); 16717 } else if (!strcasecmp(v->name, "usecallingpres")) { 16718 confp->chan.use_callingpres = ast_true(v->value); 16719 } else if (!strcasecmp(v->name, "accountcode")) { 16720 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode)); 16721 } else if (!strcasecmp(v->name, "amaflags")) { 16722 y = ast_cdr_amaflags2int(v->value); 16723 if (y < 0) 16724 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d.\n", v->value, v->lineno); 16725 else 16726 confp->chan.amaflags = y; 16727 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 16728 confp->chan.polarityonanswerdelay = atoi(v->value); 16729 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 16730 confp->chan.answeronpolarityswitch = ast_true(v->value); 16731 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 16732 confp->chan.hanguponpolarityswitch = ast_true(v->value); 16733 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 16734 confp->chan.sendcalleridafter = atoi(v->value); 16735 } else if (!strcasecmp(v->name, "mwimonitornotify")) { 16736 ast_copy_string(mwimonitornotify, v->value, sizeof(mwimonitornotify)); 16737 } else if (ast_cc_is_config_param(v->name)) { 16738 ast_cc_set_param(confp->chan.cc_params, v->name, v->value); 16739 } else if (!strcasecmp(v->name, "mwisendtype")) { 16740 #ifndef HAVE_DAHDI_LINEREVERSE_VMWI /* backward compatibility for older dahdi VMWI implementation */ 16741 if (!strcasecmp(v->value, "rpas")) { /* Ring Pulse Alert Signal */ 16742 mwisend_rpas = 1; 16743 } else { 16744 mwisend_rpas = 0; 16745 } 16746 #else 16747 /* Default is fsk, to turn it off you must specify nofsk */ 16748 memset(&confp->chan.mwisend_setting, 0, sizeof(confp->chan.mwisend_setting)); 16749 if (strcasestr(v->value, "nofsk")) { /* NoFSK */ 16750 confp->chan.mwisend_fsk = 0; 16751 } else { /* Default FSK */ 16752 confp->chan.mwisend_fsk = 1; 16753 } 16754 if (strcasestr(v->value, "rpas")) { /* Ring Pulse Alert Signal, normally followed by FSK */ 16755 confp->chan.mwisend_rpas = 1; 16756 } else { 16757 confp->chan.mwisend_rpas = 0; 16758 } 16759 if (strcasestr(v->value, "lrev")) { /* Line Reversal */ 16760 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV; 16761 } 16762 if (strcasestr(v->value, "hvdc")) { /* HV 90VDC */ 16763 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC; 16764 } 16765 if ( (strcasestr(v->value, "neon")) || (strcasestr(v->value, "hvac")) ){ /* 90V DC pulses */ 16766 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC; 16767 } 16768 #endif 16769 } else if (reload != 1) { 16770 if (!strcasecmp(v->name, "signalling") || !strcasecmp(v->name, "signaling")) { 16771 int orig_radio = confp->chan.radio; 16772 int orig_outsigmod = confp->chan.outsigmod; 16773 int orig_auto = confp->is_sig_auto; 16774 16775 confp->chan.radio = 0; 16776 confp->chan.outsigmod = -1; 16777 confp->is_sig_auto = 0; 16778 if (!strcasecmp(v->value, "em")) { 16779 confp->chan.sig = SIG_EM; 16780 } else if (!strcasecmp(v->value, "em_e1")) { 16781 confp->chan.sig = SIG_EM_E1; 16782 } else if (!strcasecmp(v->value, "em_w")) { 16783 confp->chan.sig = SIG_EMWINK; 16784 } else if (!strcasecmp(v->value, "fxs_ls")) { 16785 confp->chan.sig = SIG_FXSLS; 16786 } else if (!strcasecmp(v->value, "fxs_gs")) { 16787 confp->chan.sig = SIG_FXSGS; 16788 } else if (!strcasecmp(v->value, "fxs_ks")) { 16789 confp->chan.sig = SIG_FXSKS; 16790 } else if (!strcasecmp(v->value, "fxo_ls")) { 16791 confp->chan.sig = SIG_FXOLS; 16792 } else if (!strcasecmp(v->value, "fxo_gs")) { 16793 confp->chan.sig = SIG_FXOGS; 16794 } else if (!strcasecmp(v->value, "fxo_ks")) { 16795 confp->chan.sig = SIG_FXOKS; 16796 } else if (!strcasecmp(v->value, "fxs_rx")) { 16797 confp->chan.sig = SIG_FXSKS; 16798 confp->chan.radio = 1; 16799 } else if (!strcasecmp(v->value, "fxo_rx")) { 16800 confp->chan.sig = SIG_FXOLS; 16801 confp->chan.radio = 1; 16802 } else if (!strcasecmp(v->value, "fxs_tx")) { 16803 confp->chan.sig = SIG_FXSLS; 16804 confp->chan.radio = 1; 16805 } else if (!strcasecmp(v->value, "fxo_tx")) { 16806 confp->chan.sig = SIG_FXOGS; 16807 confp->chan.radio = 1; 16808 } else if (!strcasecmp(v->value, "em_rx")) { 16809 confp->chan.sig = SIG_EM; 16810 confp->chan.radio = 1; 16811 } else if (!strcasecmp(v->value, "em_tx")) { 16812 confp->chan.sig = SIG_EM; 16813 confp->chan.radio = 1; 16814 } else if (!strcasecmp(v->value, "em_rxtx")) { 16815 confp->chan.sig = SIG_EM; 16816 confp->chan.radio = 2; 16817 } else if (!strcasecmp(v->value, "em_txrx")) { 16818 confp->chan.sig = SIG_EM; 16819 confp->chan.radio = 2; 16820 } else if (!strcasecmp(v->value, "sf")) { 16821 confp->chan.sig = SIG_SF; 16822 } else if (!strcasecmp(v->value, "sf_w")) { 16823 confp->chan.sig = SIG_SFWINK; 16824 } else if (!strcasecmp(v->value, "sf_featd")) { 16825 confp->chan.sig = SIG_FEATD; 16826 } else if (!strcasecmp(v->value, "sf_featdmf")) { 16827 confp->chan.sig = SIG_FEATDMF; 16828 } else if (!strcasecmp(v->value, "sf_featb")) { 16829 confp->chan.sig = SIG_SF_FEATB; 16830 } else if (!strcasecmp(v->value, "sf")) { 16831 confp->chan.sig = SIG_SF; 16832 } else if (!strcasecmp(v->value, "sf_rx")) { 16833 confp->chan.sig = SIG_SF; 16834 confp->chan.radio = 1; 16835 } else if (!strcasecmp(v->value, "sf_tx")) { 16836 confp->chan.sig = SIG_SF; 16837 confp->chan.radio = 1; 16838 } else if (!strcasecmp(v->value, "sf_rxtx")) { 16839 confp->chan.sig = SIG_SF; 16840 confp->chan.radio = 2; 16841 } else if (!strcasecmp(v->value, "sf_txrx")) { 16842 confp->chan.sig = SIG_SF; 16843 confp->chan.radio = 2; 16844 } else if (!strcasecmp(v->value, "featd")) { 16845 confp->chan.sig = SIG_FEATD; 16846 } else if (!strcasecmp(v->value, "featdmf")) { 16847 confp->chan.sig = SIG_FEATDMF; 16848 } else if (!strcasecmp(v->value, "featdmf_ta")) { 16849 confp->chan.sig = SIG_FEATDMF_TA; 16850 } else if (!strcasecmp(v->value, "e911")) { 16851 confp->chan.sig = SIG_E911; 16852 } else if (!strcasecmp(v->value, "fgccama")) { 16853 confp->chan.sig = SIG_FGC_CAMA; 16854 } else if (!strcasecmp(v->value, "fgccamamf")) { 16855 confp->chan.sig = SIG_FGC_CAMAMF; 16856 } else if (!strcasecmp(v->value, "featb")) { 16857 confp->chan.sig = SIG_FEATB; 16858 #ifdef HAVE_PRI 16859 } else if (!strcasecmp(v->value, "pri_net")) { 16860 confp->chan.sig = SIG_PRI; 16861 confp->pri.pri.nodetype = PRI_NETWORK; 16862 } else if (!strcasecmp(v->value, "pri_cpe")) { 16863 confp->chan.sig = SIG_PRI; 16864 confp->pri.pri.nodetype = PRI_CPE; 16865 } else if (!strcasecmp(v->value, "bri_cpe")) { 16866 confp->chan.sig = SIG_BRI; 16867 confp->pri.pri.nodetype = PRI_CPE; 16868 } else if (!strcasecmp(v->value, "bri_net")) { 16869 confp->chan.sig = SIG_BRI; 16870 confp->pri.pri.nodetype = PRI_NETWORK; 16871 } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) { 16872 confp->chan.sig = SIG_BRI_PTMP; 16873 confp->pri.pri.nodetype = PRI_CPE; 16874 } else if (!strcasecmp(v->value, "bri_net_ptmp")) { 16875 #if defined(HAVE_PRI_CALL_HOLD) 16876 confp->chan.sig = SIG_BRI_PTMP; 16877 confp->pri.pri.nodetype = PRI_NETWORK; 16878 #else 16879 ast_log(LOG_WARNING, "How cool would it be if someone implemented this mode! For now, sucks for you. (line %d)\n", v->lineno); 16880 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 16881 #endif 16882 #if defined(HAVE_SS7) 16883 } else if (!strcasecmp(v->value, "ss7")) { 16884 confp->chan.sig = SIG_SS7; 16885 #endif /* defined(HAVE_SS7) */ 16886 #ifdef HAVE_OPENR2 16887 } else if (!strcasecmp(v->value, "mfcr2")) { 16888 confp->chan.sig = SIG_MFCR2; 16889 #endif 16890 } else if (!strcasecmp(v->value, "auto")) { 16891 confp->is_sig_auto = 1; 16892 } else { 16893 confp->chan.outsigmod = orig_outsigmod; 16894 confp->chan.radio = orig_radio; 16895 confp->is_sig_auto = orig_auto; 16896 ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno); 16897 } 16898 } else if (!strcasecmp(v->name, "outsignalling") || !strcasecmp(v->name, "outsignaling")) { 16899 if (!strcasecmp(v->value, "em")) { 16900 confp->chan.outsigmod = SIG_EM; 16901 } else if (!strcasecmp(v->value, "em_e1")) { 16902 confp->chan.outsigmod = SIG_EM_E1; 16903 } else if (!strcasecmp(v->value, "em_w")) { 16904 confp->chan.outsigmod = SIG_EMWINK; 16905 } else if (!strcasecmp(v->value, "sf")) { 16906 confp->chan.outsigmod = SIG_SF; 16907 } else if (!strcasecmp(v->value, "sf_w")) { 16908 confp->chan.outsigmod = SIG_SFWINK; 16909 } else if (!strcasecmp(v->value, "sf_featd")) { 16910 confp->chan.outsigmod = SIG_FEATD; 16911 } else if (!strcasecmp(v->value, "sf_featdmf")) { 16912 confp->chan.outsigmod = SIG_FEATDMF; 16913 } else if (!strcasecmp(v->value, "sf_featb")) { 16914 confp->chan.outsigmod = SIG_SF_FEATB; 16915 } else if (!strcasecmp(v->value, "sf")) { 16916 confp->chan.outsigmod = SIG_SF; 16917 } else if (!strcasecmp(v->value, "featd")) { 16918 confp->chan.outsigmod = SIG_FEATD; 16919 } else if (!strcasecmp(v->value, "featdmf")) { 16920 confp->chan.outsigmod = SIG_FEATDMF; 16921 } else if (!strcasecmp(v->value, "featdmf_ta")) { 16922 confp->chan.outsigmod = SIG_FEATDMF_TA; 16923 } else if (!strcasecmp(v->value, "e911")) { 16924 confp->chan.outsigmod = SIG_E911; 16925 } else if (!strcasecmp(v->value, "fgccama")) { 16926 confp->chan.outsigmod = SIG_FGC_CAMA; 16927 } else if (!strcasecmp(v->value, "fgccamamf")) { 16928 confp->chan.outsigmod = SIG_FGC_CAMAMF; 16929 } else if (!strcasecmp(v->value, "featb")) { 16930 confp->chan.outsigmod = SIG_FEATB; 16931 } else { 16932 ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno); 16933 } 16934 #ifdef HAVE_PRI 16935 } else if (!strcasecmp(v->name, "pridialplan")) { 16936 if (!strcasecmp(v->value, "national")) { 16937 confp->pri.pri.dialplan = PRI_NATIONAL_ISDN + 1; 16938 } else if (!strcasecmp(v->value, "unknown")) { 16939 confp->pri.pri.dialplan = PRI_UNKNOWN + 1; 16940 } else if (!strcasecmp(v->value, "private")) { 16941 confp->pri.pri.dialplan = PRI_PRIVATE + 1; 16942 } else if (!strcasecmp(v->value, "international")) { 16943 confp->pri.pri.dialplan = PRI_INTERNATIONAL_ISDN + 1; 16944 } else if (!strcasecmp(v->value, "local")) { 16945 confp->pri.pri.dialplan = PRI_LOCAL_ISDN + 1; 16946 } else if (!strcasecmp(v->value, "dynamic")) { 16947 confp->pri.pri.dialplan = -1; 16948 } else if (!strcasecmp(v->value, "redundant")) { 16949 confp->pri.pri.dialplan = -2; 16950 } else { 16951 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 16952 } 16953 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 16954 if (!strcasecmp(v->value, "national")) { 16955 confp->pri.pri.localdialplan = PRI_NATIONAL_ISDN + 1; 16956 } else if (!strcasecmp(v->value, "unknown")) { 16957 confp->pri.pri.localdialplan = PRI_UNKNOWN + 1; 16958 } else if (!strcasecmp(v->value, "private")) { 16959 confp->pri.pri.localdialplan = PRI_PRIVATE + 1; 16960 } else if (!strcasecmp(v->value, "international")) { 16961 confp->pri.pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1; 16962 } else if (!strcasecmp(v->value, "local")) { 16963 confp->pri.pri.localdialplan = PRI_LOCAL_ISDN + 1; 16964 } else if (!strcasecmp(v->value, "dynamic")) { 16965 confp->pri.pri.localdialplan = -1; 16966 } else if (!strcasecmp(v->value, "redundant")) { 16967 confp->pri.pri.localdialplan = -2; 16968 } else { 16969 ast_log(LOG_WARNING, "Unknown PRI localdialplan '%s' at line %d.\n", v->value, v->lineno); 16970 } 16971 } else if (!strcasecmp(v->name, "switchtype")) { 16972 if (!strcasecmp(v->value, "national")) 16973 confp->pri.pri.switchtype = PRI_SWITCH_NI2; 16974 else if (!strcasecmp(v->value, "ni1")) 16975 confp->pri.pri.switchtype = PRI_SWITCH_NI1; 16976 else if (!strcasecmp(v->value, "dms100")) 16977 confp->pri.pri.switchtype = PRI_SWITCH_DMS100; 16978 else if (!strcasecmp(v->value, "4ess")) 16979 confp->pri.pri.switchtype = PRI_SWITCH_ATT4ESS; 16980 else if (!strcasecmp(v->value, "5ess")) 16981 confp->pri.pri.switchtype = PRI_SWITCH_LUCENT5E; 16982 else if (!strcasecmp(v->value, "euroisdn")) 16983 confp->pri.pri.switchtype = PRI_SWITCH_EUROISDN_E1; 16984 else if (!strcasecmp(v->value, "qsig")) 16985 confp->pri.pri.switchtype = PRI_SWITCH_QSIG; 16986 else { 16987 ast_log(LOG_ERROR, "Unknown switchtype '%s' at line %d.\n", v->value, v->lineno); 16988 return -1; 16989 } 16990 } else if (!strcasecmp(v->name, "msn")) { 16991 ast_copy_string(confp->pri.pri.msn_list, v->value, 16992 sizeof(confp->pri.pri.msn_list)); 16993 } else if (!strcasecmp(v->name, "nsf")) { 16994 if (!strcasecmp(v->value, "sdn")) 16995 confp->pri.pri.nsf = PRI_NSF_SDN; 16996 else if (!strcasecmp(v->value, "megacom")) 16997 confp->pri.pri.nsf = PRI_NSF_MEGACOM; 16998 else if (!strcasecmp(v->value, "tollfreemegacom")) 16999 confp->pri.pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM; 17000 else if (!strcasecmp(v->value, "accunet")) 17001 confp->pri.pri.nsf = PRI_NSF_ACCUNET; 17002 else if (!strcasecmp(v->value, "none")) 17003 confp->pri.pri.nsf = PRI_NSF_NONE; 17004 else { 17005 ast_log(LOG_WARNING, "Unknown network-specific facility '%s' at line %d.\n", v->value, v->lineno); 17006 confp->pri.pri.nsf = PRI_NSF_NONE; 17007 } 17008 } else if (!strcasecmp(v->name, "priindication")) { 17009 if (!strcasecmp(v->value, "outofband")) 17010 confp->chan.priindication_oob = 1; 17011 else if (!strcasecmp(v->value, "inband")) 17012 confp->chan.priindication_oob = 0; 17013 else 17014 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d.\n", 17015 v->value, v->lineno); 17016 } else if (!strcasecmp(v->name, "priexclusive")) { 17017 confp->chan.priexclusive = ast_true(v->value); 17018 } else if (!strcasecmp(v->name, "internationalprefix")) { 17019 ast_copy_string(confp->pri.pri.internationalprefix, v->value, sizeof(confp->pri.pri.internationalprefix)); 17020 } else if (!strcasecmp(v->name, "nationalprefix")) { 17021 ast_copy_string(confp->pri.pri.nationalprefix, v->value, sizeof(confp->pri.pri.nationalprefix)); 17022 } else if (!strcasecmp(v->name, "localprefix")) { 17023 ast_copy_string(confp->pri.pri.localprefix, v->value, sizeof(confp->pri.pri.localprefix)); 17024 } else if (!strcasecmp(v->name, "privateprefix")) { 17025 ast_copy_string(confp->pri.pri.privateprefix, v->value, sizeof(confp->pri.pri.privateprefix)); 17026 } else if (!strcasecmp(v->name, "unknownprefix")) { 17027 ast_copy_string(confp->pri.pri.unknownprefix, v->value, sizeof(confp->pri.pri.unknownprefix)); 17028 } else if (!strcasecmp(v->name, "resetinterval")) { 17029 if (!strcasecmp(v->value, "never")) 17030 confp->pri.pri.resetinterval = -1; 17031 else if (atoi(v->value) >= 60) 17032 confp->pri.pri.resetinterval = atoi(v->value); 17033 else 17034 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n", 17035 v->value, v->lineno); 17036 } else if (!strcasecmp(v->name, "minunused")) { 17037 confp->pri.pri.minunused = atoi(v->value); 17038 } else if (!strcasecmp(v->name, "minidle")) { 17039 confp->pri.pri.minidle = atoi(v->value); 17040 } else if (!strcasecmp(v->name, "idleext")) { 17041 ast_copy_string(confp->pri.pri.idleext, v->value, sizeof(confp->pri.pri.idleext)); 17042 } else if (!strcasecmp(v->name, "idledial")) { 17043 ast_copy_string(confp->pri.pri.idledial, v->value, sizeof(confp->pri.pri.idledial)); 17044 } else if (!strcasecmp(v->name, "overlapdial")) { 17045 if (ast_true(v->value)) { 17046 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH; 17047 } else if (!strcasecmp(v->value, "incoming")) { 17048 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_INCOMING; 17049 } else if (!strcasecmp(v->value, "outgoing")) { 17050 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_OUTGOING; 17051 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) { 17052 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH; 17053 } else { 17054 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_NONE; 17055 } 17056 #ifdef HAVE_PRI_PROG_W_CAUSE 17057 } else if (!strcasecmp(v->name, "qsigchannelmapping")) { 17058 if (!strcasecmp(v->value, "logical")) { 17059 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_LOGICAL; 17060 } else if (!strcasecmp(v->value, "physical")) { 17061 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL; 17062 } else { 17063 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL; 17064 } 17065 #endif 17066 } else if (!strcasecmp(v->name, "discardremoteholdretrieval")) { 17067 confp->pri.pri.discardremoteholdretrieval = ast_true(v->value); 17068 #if defined(HAVE_PRI_SERVICE_MESSAGES) 17069 } else if (!strcasecmp(v->name, "service_message_support")) { 17070 /* assuming switchtype for this channel group has been configured already */ 17071 if ((confp->pri.pri.switchtype == PRI_SWITCH_ATT4ESS 17072 || confp->pri.pri.switchtype == PRI_SWITCH_LUCENT5E 17073 || confp->pri.pri.switchtype == PRI_SWITCH_NI2) && ast_true(v->value)) { 17074 confp->pri.pri.enable_service_message_support = 1; 17075 } else { 17076 confp->pri.pri.enable_service_message_support = 0; 17077 } 17078 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 17079 #ifdef HAVE_PRI_INBANDDISCONNECT 17080 } else if (!strcasecmp(v->name, "inbanddisconnect")) { 17081 confp->pri.pri.inbanddisconnect = ast_true(v->value); 17082 #endif 17083 } else if (!strcasecmp(v->name, "pritimer")) { 17084 #ifdef PRI_GETSET_TIMERS 17085 char tmp[20]; 17086 char *timerc; 17087 char *c; 17088 int timer; 17089 int timeridx; 17090 17091 ast_copy_string(tmp, v->value, sizeof(tmp)); 17092 c = tmp; 17093 timerc = strsep(&c, ","); 17094 if (!ast_strlen_zero(timerc) && !ast_strlen_zero(c)) { 17095 timeridx = pri_timer2idx(timerc); 17096 timer = atoi(c); 17097 if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) { 17098 ast_log(LOG_WARNING, 17099 "'%s' is not a valid ISDN timer at line %d.\n", timerc, 17100 v->lineno); 17101 } else if (!timer) { 17102 ast_log(LOG_WARNING, 17103 "'%s' is not a valid value for ISDN timer '%s' at line %d.\n", 17104 c, timerc, v->lineno); 17105 } else { 17106 confp->pri.pri.pritimers[timeridx] = timer; 17107 } 17108 } else { 17109 ast_log(LOG_WARNING, 17110 "'%s' is not a valid ISDN timer configuration string at line %d.\n", 17111 v->value, v->lineno); 17112 } 17113 #endif /* PRI_GETSET_TIMERS */ 17114 } else if (!strcasecmp(v->name, "facilityenable")) { 17115 confp->pri.pri.facilityenable = ast_true(v->value); 17116 #if defined(HAVE_PRI_AOC_EVENTS) 17117 } else if (!strcasecmp(v->name, "aoc_enable")) { 17118 confp->pri.pri.aoc_passthrough_flag = 0; 17119 if (strchr(v->value, 's') || strchr(v->value, 'S')) { 17120 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_S; 17121 } 17122 if (strchr(v->value, 'd') || strchr(v->value, 'D')) { 17123 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_D; 17124 } 17125 if (strchr(v->value, 'e') || strchr(v->value, 'E')) { 17126 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_E; 17127 } 17128 } else if (!strcasecmp(v->name, "aoce_delayhangup")) { 17129 confp->pri.pri.aoce_delayhangup = ast_true(v->value); 17130 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 17131 #if defined(HAVE_PRI_CALL_HOLD) 17132 } else if (!strcasecmp(v->name, "hold_disconnect_transfer")) { 17133 confp->pri.pri.hold_disconnect_transfer = ast_true(v->value); 17134 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 17135 #if defined(HAVE_PRI_CCSS) 17136 } else if (!strcasecmp(v->name, "cc_ptmp_recall_mode")) { 17137 if (!strcasecmp(v->value, "global")) { 17138 confp->pri.pri.cc_ptmp_recall_mode = 0;/* globalRecall */ 17139 } else if (!strcasecmp(v->value, "specific")) { 17140 confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */ 17141 } else { 17142 confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */ 17143 } 17144 } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_req")) { 17145 if (!strcasecmp(v->value, "release")) { 17146 confp->pri.pri.cc_qsig_signaling_link_req = 0;/* release */ 17147 } else if (!strcasecmp(v->value, "retain")) { 17148 confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */ 17149 } else if (!strcasecmp(v->value, "do_not_care")) { 17150 confp->pri.pri.cc_qsig_signaling_link_req = 2;/* do-not-care */ 17151 } else { 17152 confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */ 17153 } 17154 } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_rsp")) { 17155 if (!strcasecmp(v->value, "release")) { 17156 confp->pri.pri.cc_qsig_signaling_link_rsp = 0;/* release */ 17157 } else if (!strcasecmp(v->value, "retain")) { 17158 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */ 17159 } else { 17160 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */ 17161 } 17162 #endif /* defined(HAVE_PRI_CCSS) */ 17163 #if defined(HAVE_PRI_CALL_WAITING) 17164 } else if (!strcasecmp(v->name, "max_call_waiting_calls")) { 17165 confp->pri.pri.max_call_waiting_calls = atoi(v->value); 17166 if (confp->pri.pri.max_call_waiting_calls < 0) { 17167 /* Negative values are not allowed. */ 17168 confp->pri.pri.max_call_waiting_calls = 0; 17169 } 17170 } else if (!strcasecmp(v->name, "allow_call_waiting_calls")) { 17171 confp->pri.pri.allow_call_waiting_calls = ast_true(v->value); 17172 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 17173 #if defined(HAVE_PRI_MWI) 17174 } else if (!strcasecmp(v->name, "mwi_mailboxes")) { 17175 ast_copy_string(confp->pri.pri.mwi_mailboxes, v->value, 17176 sizeof(confp->pri.pri.mwi_mailboxes)); 17177 #endif /* defined(HAVE_PRI_MWI) */ 17178 } else if (!strcasecmp(v->name, "append_msn_to_cid_tag")) { 17179 confp->pri.pri.append_msn_to_user_tag = ast_true(v->value); 17180 #endif /* HAVE_PRI */ 17181 #if defined(HAVE_SS7) 17182 } else if (!strcasecmp(v->name, "ss7type")) { 17183 if (!strcasecmp(v->value, "itu")) { 17184 cur_ss7type = SS7_ITU; 17185 } else if (!strcasecmp(v->value, "ansi")) { 17186 cur_ss7type = SS7_ANSI; 17187 } else 17188 ast_log(LOG_WARNING, "'%s' is an unknown ss7 switch type at line %d.!\n", v->value, v->lineno); 17189 } else if (!strcasecmp(v->name, "linkset")) { 17190 cur_linkset = atoi(v->value); 17191 } else if (!strcasecmp(v->name, "pointcode")) { 17192 cur_pointcode = parse_pointcode(v->value); 17193 } else if (!strcasecmp(v->name, "adjpointcode")) { 17194 cur_adjpointcode = parse_pointcode(v->value); 17195 } else if (!strcasecmp(v->name, "defaultdpc")) { 17196 cur_defaultdpc = parse_pointcode(v->value); 17197 } else if (!strcasecmp(v->name, "cicbeginswith")) { 17198 cur_cicbeginswith = atoi(v->value); 17199 } else if (!strcasecmp(v->name, "networkindicator")) { 17200 if (!strcasecmp(v->value, "national")) 17201 cur_networkindicator = SS7_NI_NAT; 17202 else if (!strcasecmp(v->value, "national_spare")) 17203 cur_networkindicator = SS7_NI_NAT_SPARE; 17204 else if (!strcasecmp(v->value, "international")) 17205 cur_networkindicator = SS7_NI_INT; 17206 else if (!strcasecmp(v->value, "international_spare")) 17207 cur_networkindicator = SS7_NI_INT_SPARE; 17208 else 17209 cur_networkindicator = -1; 17210 } else if (!strcasecmp(v->name, "ss7_internationalprefix")) { 17211 ast_copy_string(confp->ss7.ss7.internationalprefix, v->value, sizeof(confp->ss7.ss7.internationalprefix)); 17212 } else if (!strcasecmp(v->name, "ss7_nationalprefix")) { 17213 ast_copy_string(confp->ss7.ss7.nationalprefix, v->value, sizeof(confp->ss7.ss7.nationalprefix)); 17214 } else if (!strcasecmp(v->name, "ss7_subscriberprefix")) { 17215 ast_copy_string(confp->ss7.ss7.subscriberprefix, v->value, sizeof(confp->ss7.ss7.subscriberprefix)); 17216 } else if (!strcasecmp(v->name, "ss7_unknownprefix")) { 17217 ast_copy_string(confp->ss7.ss7.unknownprefix, v->value, sizeof(confp->ss7.ss7.unknownprefix)); 17218 } else if (!strcasecmp(v->name, "ss7_called_nai")) { 17219 if (!strcasecmp(v->value, "national")) { 17220 confp->ss7.ss7.called_nai = SS7_NAI_NATIONAL; 17221 } else if (!strcasecmp(v->value, "international")) { 17222 confp->ss7.ss7.called_nai = SS7_NAI_INTERNATIONAL; 17223 } else if (!strcasecmp(v->value, "subscriber")) { 17224 confp->ss7.ss7.called_nai = SS7_NAI_SUBSCRIBER; 17225 } else if (!strcasecmp(v->value, "unknown")) { 17226 confp->ss7.ss7.called_nai = SS7_NAI_UNKNOWN; 17227 } else if (!strcasecmp(v->value, "dynamic")) { 17228 confp->ss7.ss7.called_nai = SS7_NAI_DYNAMIC; 17229 } else { 17230 ast_log(LOG_WARNING, "Unknown SS7 called_nai '%s' at line %d.\n", v->value, v->lineno); 17231 } 17232 } else if (!strcasecmp(v->name, "ss7_calling_nai")) { 17233 if (!strcasecmp(v->value, "national")) { 17234 confp->ss7.ss7.calling_nai = SS7_NAI_NATIONAL; 17235 } else if (!strcasecmp(v->value, "international")) { 17236 confp->ss7.ss7.calling_nai = SS7_NAI_INTERNATIONAL; 17237 } else if (!strcasecmp(v->value, "subscriber")) { 17238 confp->ss7.ss7.calling_nai = SS7_NAI_SUBSCRIBER; 17239 } else if (!strcasecmp(v->value, "unknown")) { 17240 confp->ss7.ss7.calling_nai = SS7_NAI_UNKNOWN; 17241 } else if (!strcasecmp(v->value, "dynamic")) { 17242 confp->ss7.ss7.calling_nai = SS7_NAI_DYNAMIC; 17243 } else { 17244 ast_log(LOG_WARNING, "Unknown SS7 calling_nai '%s' at line %d.\n", v->value, v->lineno); 17245 } 17246 } else if (!strcasecmp(v->name, "sigchan")) { 17247 int sigchan, res; 17248 sigchan = atoi(v->value); 17249 res = linkset_addsigchan(sigchan); 17250 if (res < 0) 17251 return -1; 17252 17253 } else if (!strcasecmp(v->name, "ss7_explicitacm")) { 17254 struct dahdi_ss7 *link; 17255 link = ss7_resolve_linkset(cur_linkset); 17256 if (!link) { 17257 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1); 17258 return -1; 17259 } 17260 if (ast_true(v->value)) 17261 link->ss7.flags |= LINKSET_FLAG_EXPLICITACM; 17262 #endif /* defined(HAVE_SS7) */ 17263 #ifdef HAVE_OPENR2 17264 } else if (!strcasecmp(v->name, "mfcr2_advanced_protocol_file")) { 17265 ast_copy_string(confp->mfcr2.r2proto_file, v->value, sizeof(confp->mfcr2.r2proto_file)); 17266 ast_log(LOG_WARNING, "MFC/R2 Protocol file '%s' will be used, you only should use this if you *REALLY KNOW WHAT YOU ARE DOING*.\n", confp->mfcr2.r2proto_file); 17267 } else if (!strcasecmp(v->name, "mfcr2_logdir")) { 17268 ast_copy_string(confp->mfcr2.logdir, v->value, sizeof(confp->mfcr2.logdir)); 17269 } else if (!strcasecmp(v->name, "mfcr2_variant")) { 17270 confp->mfcr2.variant = openr2_proto_get_variant(v->value); 17271 if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) { 17272 ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d, defaulting to ITU.\n", v->value, v->lineno); 17273 confp->mfcr2.variant = OR2_VAR_ITU; 17274 } 17275 } else if (!strcasecmp(v->name, "mfcr2_mfback_timeout")) { 17276 confp->mfcr2.mfback_timeout = atoi(v->value); 17277 if (!confp->mfcr2.mfback_timeout) { 17278 ast_log(LOG_WARNING, "MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n"); 17279 confp->mfcr2.mfback_timeout = -1; 17280 } else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) { 17281 ast_log(LOG_WARNING, "MF timeout less than 500ms is not recommended, you have been warned!\n"); 17282 } 17283 } else if (!strcasecmp(v->name, "mfcr2_metering_pulse_timeout")) { 17284 confp->mfcr2.metering_pulse_timeout = atoi(v->value); 17285 if (confp->mfcr2.metering_pulse_timeout > 500) { 17286 ast_log(LOG_WARNING, "Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n"); 17287 } 17288 } else if (!strcasecmp(v->name, "mfcr2_get_ani_first")) { 17289 confp->mfcr2.get_ani_first = ast_true(v->value) ? 1 : 0; 17290 } else if (!strcasecmp(v->name, "mfcr2_double_answer")) { 17291 confp->mfcr2.double_answer = ast_true(v->value) ? 1 : 0; 17292 } else if (!strcasecmp(v->name, "mfcr2_charge_calls")) { 17293 confp->mfcr2.charge_calls = ast_true(v->value) ? 1 : 0; 17294 } else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) { 17295 confp->mfcr2.accept_on_offer = ast_true(v->value) ? 1 : 0; 17296 } else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) { 17297 confp->mfcr2.allow_collect_calls = ast_true(v->value) ? 1 : 0; 17298 } else if (!strcasecmp(v->name, "mfcr2_forced_release")) { 17299 confp->mfcr2.forced_release = ast_true(v->value) ? 1 : 0; 17300 } else if (!strcasecmp(v->name, "mfcr2_immediate_accept")) { 17301 confp->mfcr2.immediate_accept = ast_true(v->value) ? 1 : 0; 17302 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 17303 } else if (!strcasecmp(v->name, "mfcr2_skip_category")) { 17304 confp->mfcr2.skip_category_request = ast_true(v->value) ? 1 : 0; 17305 #endif 17306 } else if (!strcasecmp(v->name, "mfcr2_call_files")) { 17307 confp->mfcr2.call_files = ast_true(v->value) ? 1 : 0; 17308 } else if (!strcasecmp(v->name, "mfcr2_max_ani")) { 17309 confp->mfcr2.max_ani = atoi(v->value); 17310 if (confp->mfcr2.max_ani >= AST_MAX_EXTENSION){ 17311 confp->mfcr2.max_ani = AST_MAX_EXTENSION - 1; 17312 } 17313 } else if (!strcasecmp(v->name, "mfcr2_max_dnis")) { 17314 confp->mfcr2.max_dnis = atoi(v->value); 17315 if (confp->mfcr2.max_dnis >= AST_MAX_EXTENSION){ 17316 confp->mfcr2.max_dnis = AST_MAX_EXTENSION - 1; 17317 } 17318 } else if (!strcasecmp(v->name, "mfcr2_category")) { 17319 confp->mfcr2.category = openr2_proto_get_category(v->value); 17320 if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) { 17321 confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER; 17322 ast_log(LOG_WARNING, "Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n", 17323 v->value, v->lineno); 17324 } 17325 } else if (!strcasecmp(v->name, "mfcr2_logging")) { 17326 openr2_log_level_t tmplevel; 17327 char *clevel; 17328 char *logval = ast_strdupa(v->value); 17329 while (logval) { 17330 clevel = strsep(&logval,","); 17331 if (-1 == (tmplevel = openr2_log_get_level(clevel))) { 17332 ast_log(LOG_WARNING, "Ignoring invalid logging level: '%s' at line %d.\n", clevel, v->lineno); 17333 continue; 17334 } 17335 confp->mfcr2.loglevel |= tmplevel; 17336 } 17337 #endif /* HAVE_OPENR2 */ 17338 } else if (!strcasecmp(v->name, "cadence")) { 17339 /* setup to scan our argument */ 17340 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 17341 int i; 17342 struct dahdi_ring_cadence new_cadence; 17343 int cid_location = -1; 17344 int firstcadencepos = 0; 17345 char original_args[80]; 17346 int cadence_is_ok = 1; 17347 17348 ast_copy_string(original_args, v->value, sizeof(original_args)); 17349 /* 16 cadences allowed (8 pairs) */ 17350 element_count = sscanf(v->value, "%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d", &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]); 17351 17352 /* Cadence must be even (on/off) */ 17353 if (element_count % 2 == 1) { 17354 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s at line %d.\n", original_args, v->lineno); 17355 cadence_is_ok = 0; 17356 } 17357 17358 /* Ring cadences cannot be negative */ 17359 for (i = 0; i < element_count; i++) { 17360 if (c[i] == 0) { 17361 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s at line %d.\n", original_args, v->lineno); 17362 cadence_is_ok = 0; 17363 break; 17364 } else if (c[i] < 0) { 17365 if (i % 2 == 1) { 17366 /* Silence duration, negative possibly okay */ 17367 if (cid_location == -1) { 17368 cid_location = i; 17369 c[i] *= -1; 17370 } else { 17371 ast_log(LOG_ERROR, "CID location specified twice: %s at line %d.\n", original_args, v->lineno); 17372 cadence_is_ok = 0; 17373 break; 17374 } 17375 } else { 17376 if (firstcadencepos == 0) { 17377 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 17378 /* duration will be passed negative to the DAHDI driver */ 17379 } else { 17380 ast_log(LOG_ERROR, "First cadence position specified twice: %s at line %d.\n", original_args, v->lineno); 17381 cadence_is_ok = 0; 17382 break; 17383 } 17384 } 17385 } 17386 } 17387 17388 /* Substitute our scanned cadence */ 17389 for (i = 0; i < 16; i++) { 17390 new_cadence.ringcadence[i] = c[i]; 17391 } 17392 17393 if (cadence_is_ok) { 17394 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 17395 if (element_count < 2) { 17396 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s at line %d.\n", original_args, v->lineno); 17397 } else { 17398 if (cid_location == -1) { 17399 /* user didn't say; default to first pause */ 17400 cid_location = 1; 17401 } else { 17402 /* convert element_index to cidrings value */ 17403 cid_location = (cid_location + 1) / 2; 17404 } 17405 /* ---we like their cadence; try to install it--- */ 17406 if (!user_has_defined_cadences++) 17407 /* this is the first user-defined cadence; clear the default user cadences */ 17408 num_cadence = 0; 17409 if ((num_cadence+1) >= NUM_CADENCE_MAX) 17410 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s at line %d.\n", NUM_CADENCE_MAX, original_args, v->lineno); 17411 else { 17412 cadences[num_cadence] = new_cadence; 17413 cidrings[num_cadence++] = cid_location; 17414 ast_verb(3, "cadence 'r%d' added: %s\n",num_cadence,original_args); 17415 } 17416 } 17417 } 17418 } else if (!strcasecmp(v->name, "ringtimeout")) { 17419 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 17420 } else if (!strcasecmp(v->name, "prewink")) { 17421 confp->timing.prewinktime = atoi(v->value); 17422 } else if (!strcasecmp(v->name, "preflash")) { 17423 confp->timing.preflashtime = atoi(v->value); 17424 } else if (!strcasecmp(v->name, "wink")) { 17425 confp->timing.winktime = atoi(v->value); 17426 } else if (!strcasecmp(v->name, "flash")) { 17427 confp->timing.flashtime = atoi(v->value); 17428 } else if (!strcasecmp(v->name, "start")) { 17429 confp->timing.starttime = atoi(v->value); 17430 } else if (!strcasecmp(v->name, "rxwink")) { 17431 confp->timing.rxwinktime = atoi(v->value); 17432 } else if (!strcasecmp(v->name, "rxflash")) { 17433 confp->timing.rxflashtime = atoi(v->value); 17434 } else if (!strcasecmp(v->name, "debounce")) { 17435 confp->timing.debouncetime = atoi(v->value); 17436 } else if (!strcasecmp(v->name, "toneduration")) { 17437 int toneduration; 17438 int ctlfd; 17439 int res; 17440 struct dahdi_dialparams dps; 17441 17442 ctlfd = open("/dev/dahdi/ctl", O_RDWR); 17443 if (ctlfd == -1) { 17444 ast_log(LOG_ERROR, "Unable to open /dev/dahdi/ctl to set toneduration at line %d.\n", v->lineno); 17445 return -1; 17446 } 17447 17448 toneduration = atoi(v->value); 17449 if (toneduration > -1) { 17450 memset(&dps, 0, sizeof(dps)); 17451 17452 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 17453 res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps); 17454 if (res < 0) { 17455 ast_log(LOG_ERROR, "Invalid tone duration: %d ms at line %d: %s\n", toneduration, v->lineno, strerror(errno)); 17456 close(ctlfd); 17457 return -1; 17458 } 17459 } 17460 close(ctlfd); 17461 } else if (!strcasecmp(v->name, "defaultcic")) { 17462 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 17463 } else if (!strcasecmp(v->name, "defaultozz")) { 17464 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 17465 } else if (!strcasecmp(v->name, "mwilevel")) { 17466 mwilevel = atoi(v->value); 17467 } else if (!strcasecmp(v->name, "dtmfcidlevel")) { 17468 dtmfcid_level = atoi(v->value); 17469 } else if (!strcasecmp(v->name, "reportalarms")) { 17470 if (!strcasecmp(v->value, "all")) 17471 report_alarms = REPORT_CHANNEL_ALARMS | REPORT_SPAN_ALARMS; 17472 if (!strcasecmp(v->value, "none")) 17473 report_alarms = 0; 17474 else if (!strcasecmp(v->value, "channels")) 17475 report_alarms = REPORT_CHANNEL_ALARMS; 17476 else if (!strcasecmp(v->value, "spans")) 17477 report_alarms = REPORT_SPAN_ALARMS; 17478 } 17479 } else if (!(options & PROC_DAHDI_OPT_NOWARN) ) 17480 ast_log(LOG_WARNING, "Ignoring any changes to '%s' (on reload) at line %d.\n", v->name, v->lineno); 17481 } 17482 if (dahdichan[0]) { 17483 /* The user has set 'dahdichan' */ 17484 /*< \todo pass proper line number instead of 0 */ 17485 if (build_channels(confp, dahdichan, reload, 0, &found_pseudo)) { 17486 return -1; 17487 } 17488 } 17489 17490 /* mark the first channels of each DAHDI span to watch for their span alarms */ 17491 for (tmp = iflist, y=-1; tmp; tmp = tmp->next) { 17492 if (!tmp->destroy && tmp->span != y) { 17493 tmp->manages_span_alarms = 1; 17494 y = tmp->span; 17495 } else { 17496 tmp->manages_span_alarms = 0; 17497 } 17498 } 17499 17500 /*< \todo why check for the pseudo in the per-channel section. 17501 * Any actual use for manual setup of the pseudo channel? */ 17502 if (!found_pseudo && reload != 1) { 17503 /* use the default configuration for a channel, so 17504 that any settings from real configured channels 17505 don't "leak" into the pseudo channel config 17506 */ 17507 struct dahdi_chan_conf conf = dahdi_chan_conf_default(); 17508 17509 if (conf.chan.cc_params) { 17510 tmp = mkintf(CHAN_PSEUDO, &conf, reload); 17511 } else { 17512 tmp = NULL; 17513 } 17514 if (tmp) { 17515 ast_verb(3, "Automatically generated pseudo channel\n"); 17516 } else { 17517 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 17518 } 17519 ast_cc_config_params_destroy(conf.chan.cc_params); 17520 } 17521 return 0; 17522 }
static void process_echocancel | ( | struct dahdi_chan_conf * | confp, | |
const char * | data, | |||
unsigned int | line | |||
) | [static] |
Definition at line 16381 of file chan_dahdi.c.
References ARRAY_LEN, ast_app_separate_args, ast_log(), ast_strdupa, ast_strlen_zero(), ast_true(), dahdi_chan_conf::chan, dahdi_pvt::echocancel, dahdi_pvt::head, name, dahdi_pvt::params, parse(), and value.
16382 { 16383 char *parse = ast_strdupa(data); 16384 char *params[DAHDI_MAX_ECHOCANPARAMS + 1]; 16385 unsigned int param_count; 16386 unsigned int x; 16387 16388 if (!(param_count = ast_app_separate_args(parse, ',', params, ARRAY_LEN(params)))) 16389 return; 16390 16391 memset(&confp->chan.echocancel, 0, sizeof(confp->chan.echocancel)); 16392 16393 /* first parameter is tap length, process it here */ 16394 16395 x = ast_strlen_zero(params[0]) ? 0 : atoi(params[0]); 16396 16397 if ((x == 32) || (x == 64) || (x == 128) || (x == 256) || (x == 512) || (x == 1024)) 16398 confp->chan.echocancel.head.tap_length = x; 16399 else if ((confp->chan.echocancel.head.tap_length = ast_true(params[0]))) 16400 confp->chan.echocancel.head.tap_length = 128; 16401 16402 /* now process any remaining parameters */ 16403 16404 for (x = 1; x < param_count; x++) { 16405 struct { 16406 char *name; 16407 char *value; 16408 } param; 16409 16410 if (ast_app_separate_args(params[x], '=', (char **) ¶m, 2) < 1) { 16411 ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %d: '%s'\n", line, params[x]); 16412 continue; 16413 } 16414 16415 if (ast_strlen_zero(param.name) || (strlen(param.name) > sizeof(confp->chan.echocancel.params[0].name)-1)) { 16416 ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %d: '%s'\n", line, param.name); 16417 continue; 16418 } 16419 16420 strcpy(confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].name, param.name); 16421 16422 if (param.value) { 16423 if (sscanf(param.value, "%30d", &confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].value) != 1) { 16424 ast_log(LOG_WARNING, "Invalid echocancel parameter value supplied at line %d: '%s'\n", line, param.value); 16425 continue; 16426 } 16427 } 16428 confp->chan.echocancel.head.param_count++; 16429 } 16430 }
static int reload | ( | void | ) | [static] |
Definition at line 18151 of file chan_dahdi.c.
References ast_log(), and setup_dahdi().
18152 { 18153 int res = 0; 18154 18155 res = setup_dahdi(1); 18156 if (res) { 18157 ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n"); 18158 return -1; 18159 } 18160 return 0; 18161 }
static int reset_conf | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4678 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, dahdi_pvt::confno, dahdi_subchannel::dfd, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_hangup(), and my_all_subchannels_hungup().
04679 { 04680 p->confno = -1; 04681 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf)); 04682 if (p->subs[SUB_REAL].dfd > -1) { 04683 struct dahdi_confinfo zi; 04684 04685 memset(&zi, 0, sizeof(zi)); 04686 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi)) 04687 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno)); 04688 } 04689 return 0; 04690 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 11590 of file chan_dahdi.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, monitor_thread, and monlock.
Referenced by dahdi_hangup(), dahdi_request(), h323_reload(), load_module(), mgcp_reload(), mgcp_request(), my_all_subchannels_hungup(), oh323_request(), phone_hangup(), phone_request(), sip_reload(), sip_request_call(), skinny_request(), unistim_reload(), and unistim_request().
11591 { 11592 /* If we're supposed to be stopped -- stay stopped */ 11593 if (monitor_thread == AST_PTHREADT_STOP) 11594 return 0; 11595 ast_mutex_lock(&monlock); 11596 if (monitor_thread == pthread_self()) { 11597 ast_mutex_unlock(&monlock); 11598 ast_log(LOG_WARNING, "Cannot kill myself\n"); 11599 return -1; 11600 } 11601 if (monitor_thread != AST_PTHREADT_NULL) { 11602 /* Wake up the thread */ 11603 pthread_kill(monitor_thread, SIGURG); 11604 } else { 11605 /* Start a new monitor */ 11606 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 11607 ast_mutex_unlock(&monlock); 11608 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 11609 return -1; 11610 } 11611 } 11612 ast_mutex_unlock(&monlock); 11613 return 0; 11614 }
static int restore_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5091 of file chan_dahdi.c.
References ast_debug, ast_log(), errno, LOG_WARNING, dahdi_pvt::saveconf, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_handle_event(), dahdi_read(), handle_init_event(), my_cancel_cidspill(), and send_callerid().
05092 { 05093 int res; 05094 if (p->saveconf.confmode) { 05095 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf); 05096 p->saveconf.confmode = 0; 05097 if (res) { 05098 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno)); 05099 return -1; 05100 } 05101 ast_debug(1, "Restored conferencing\n"); 05102 } 05103 return 0; 05104 }
static int restore_gains | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4998 of file chan_dahdi.c.
References ast_log(), errno, dahdi_pvt::law, LOG_WARNING, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, set_actual_gain(), SUB_REAL, dahdi_pvt::subs, dahdi_pvt::txdrc, and dahdi_pvt::txgain.
Referenced by analog_ss_thread(), dahdi_hangup(), and mwi_thread().
04999 { 05000 int res; 05001 05002 res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law); 05003 if (res) { 05004 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno)); 05005 return -1; 05006 } 05007 05008 return 0; 05009 }
static int revert_fax_buffers | ( | struct dahdi_pvt * | p, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 5981 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::buf_no, dahdi_pvt::buf_policy, dahdi_pvt::bufferoverrideinuse, dahdi_pvt::bufsize, errno, LOG_WARNING, ast_channel::name, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_hangup().
05982 { 05983 if (p->bufferoverrideinuse) { 05984 /* faxbuffers are in use, revert them */ 05985 struct dahdi_bufferinfo bi = { 05986 .txbufpolicy = p->buf_policy, 05987 .rxbufpolicy = p->buf_policy, 05988 .bufsize = p->bufsize, 05989 .numbufs = p->buf_no 05990 }; 05991 int bpres; 05992 05993 if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 05994 ast_log(LOG_WARNING, "Channel '%s' unable to revert buffer policy: %s\n", ast->name, strerror(errno)); 05995 } 05996 p->bufferoverrideinuse = 0; 05997 return bpres; 05998 } 05999 06000 return -1; 06001 }
static int save_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5065 of file chan_dahdi.c.
References ast_debug, ast_log(), errno, LOG_WARNING, dahdi_pvt::saveconf, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_callwait(), dahdi_handle_event(), and my_callwait().
05066 { 05067 struct dahdi_confinfo c; 05068 int res; 05069 if (p->saveconf.confmode) { 05070 ast_log(LOG_WARNING, "Can't save conference -- already in use\n"); 05071 return -1; 05072 } 05073 p->saveconf.chan = 0; 05074 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf); 05075 if (res) { 05076 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno)); 05077 p->saveconf.confmode = 0; 05078 return -1; 05079 } 05080 memset(&c, 0, sizeof(c)); 05081 c.confmode = DAHDI_CONF_NORMAL; 05082 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c); 05083 if (res) { 05084 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno)); 05085 return -1; 05086 } 05087 ast_debug(1, "Disabled conferencing\n"); 05088 return 0; 05089 }
static int send_callerid | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5149 of file chan_dahdi.c.
References ast_debug, ast_free, ast_log(), dahdi_pvt::callwaitcas, CALLWAITING_SUPPRESS_SAMPLES, dahdi_pvt::cid_suppress_expire, CIDCW_EXPIRE_SAMPLES, dahdi_pvt::cidcwexpire, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, dahdi_setlinear(), errno, dahdi_subchannel::linear, LOG_WARNING, restore_conference(), SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_callwait(), dahdi_read(), my_callwait(), my_send_callerid(), and send_cwcidspill().
05150 { 05151 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */ 05152 int res; 05153 /* Take out of linear mode if necessary */ 05154 if (p->subs[SUB_REAL].linear) { 05155 p->subs[SUB_REAL].linear = 0; 05156 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 05157 } 05158 while (p->cidpos < p->cidlen) { 05159 res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos); 05160 ast_debug(4, "writing callerid at pos %d of %d, res = %d\n", p->cidpos, p->cidlen, res); 05161 if (res < 0) { 05162 if (errno == EAGAIN) 05163 return 0; 05164 else { 05165 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 05166 return -1; 05167 } 05168 } 05169 if (!res) 05170 return 0; 05171 p->cidpos += res; 05172 } 05173 p->cid_suppress_expire = CALLWAITING_SUPPRESS_SAMPLES; 05174 ast_free(p->cidspill); 05175 p->cidspill = NULL; 05176 if (p->callwaitcas) { 05177 /* Wait for CID/CW to expire */ 05178 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES; 05179 p->cid_suppress_expire = p->cidcwexpire; 05180 } else 05181 restore_conference(p); 05182 return 0; 05183 }
static int send_cwcidspill | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5106 of file chan_dahdi.c.
References ast_callerid_callwaiting_generate(), AST_LAW, ast_malloc, ast_verb, dahdi_pvt::callwait_name, dahdi_pvt::callwait_num, dahdi_pvt::callwaitcas, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cidcwexpire, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, MAX_CALLERID_SIZE, READ_SIZE, and send_callerid().
Referenced by dahdi_handle_dtmf().
05107 { 05108 p->callwaitcas = 0; 05109 p->cidcwexpire = 0; 05110 p->cid_suppress_expire = 0; 05111 if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) 05112 return -1; 05113 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p)); 05114 /* Make sure we account for the end */ 05115 p->cidlen += READ_SIZE * 4; 05116 p->cidpos = 0; 05117 send_callerid(p); 05118 ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num); 05119 return 0; 05120 }
static int set_actual_gain | ( | int | fd, | |
float | rxgain, | |||
float | txgain, | |||
float | rxdrc, | |||
float | txdrc, | |||
int | law | |||
) | [static] |
Definition at line 4979 of file chan_dahdi.c.
References set_actual_rxgain(), and set_actual_txgain().
Referenced by bump_gains(), dahdi_call(), my_pri_open_media(), and restore_gains().
04980 { 04981 return set_actual_txgain(fd, txgain, txdrc, law) | set_actual_rxgain(fd, rxgain, rxdrc, law); 04982 }
static int set_actual_rxgain | ( | int | fd, | |
float | gain, | |||
float | drc, | |||
int | law | |||
) | [static] |
Definition at line 4962 of file chan_dahdi.c.
References ast_debug, errno, and fill_rxgain().
Referenced by dahdi_set_swgain(), dahdi_setoption(), and set_actual_gain().
04963 { 04964 struct dahdi_gains g; 04965 int res; 04966 04967 memset(&g, 0, sizeof(g)); 04968 res = ioctl(fd, DAHDI_GETGAINS, &g); 04969 if (res) { 04970 ast_debug(1, "Failed to read gains: %s\n", strerror(errno)); 04971 return res; 04972 } 04973 04974 fill_rxgain(&g, gain, drc, law); 04975 04976 return ioctl(fd, DAHDI_SETGAINS, &g); 04977 }
static int set_actual_txgain | ( | int | fd, | |
float | gain, | |||
float | drc, | |||
int | law | |||
) | [static] |
Definition at line 4945 of file chan_dahdi.c.
References ast_debug, errno, and fill_txgain().
Referenced by dahdi_set_swgain(), dahdi_setoption(), and set_actual_gain().
04946 { 04947 struct dahdi_gains g; 04948 int res; 04949 04950 memset(&g, 0, sizeof(g)); 04951 res = ioctl(fd, DAHDI_GETGAINS, &g); 04952 if (res) { 04953 ast_debug(1, "Failed to read gains: %s\n", strerror(errno)); 04954 return res; 04955 } 04956 04957 fill_txgain(&g, gain, drc, law); 04958 04959 return ioctl(fd, DAHDI_SETGAINS, &g); 04960 }
static int setup_dahdi | ( | int | reload | ) | [static] |
Definition at line 17796 of file chan_dahdi.c.
References ast_cc_config_params_destroy(), dahdi_pvt::cc_params, dahdi_chan_conf::chan, dahdi_chan_conf_default(), and setup_dahdi_int().
Referenced by load_module(), and reload().
17797 { 17798 int res; 17799 struct dahdi_chan_conf base_conf = dahdi_chan_conf_default(); 17800 struct dahdi_chan_conf conf = dahdi_chan_conf_default(); 17801 17802 if (base_conf.chan.cc_params && conf.chan.cc_params) { 17803 res = setup_dahdi_int(reload, &base_conf, &conf); 17804 } else { 17805 res = -1; 17806 } 17807 ast_cc_config_params_destroy(base_conf.chan.cc_params); 17808 ast_cc_config_params_destroy(conf.chan.cc_params); 17809 17810 return res; 17811 }
static int setup_dahdi_int | ( | int | reload, | |
struct dahdi_chan_conf * | base_conf, | |||
struct dahdi_chan_conf * | conf | |||
) | [static] |
Definition at line 17555 of file chan_dahdi.c.
References ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, config, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, deep_copy_dahdi_chan_conf(), default_jbconf, global_jbconf, ast_variable::lineno, LOG_NOTICE, mwimonitornotify, ast_variable::name, ast_variable::next, prepare_pri(), pri_create_spanmap(), pri_create_trunkgroup(), PROC_DAHDI_OPT_NOCHAN, PROC_DAHDI_OPT_NOWARN, process_dahdi(), sig_pri_start_pri(), and ast_variable::value.
Referenced by setup_dahdi().
17556 { 17557 struct ast_config *cfg; 17558 struct ast_config *ucfg; 17559 struct ast_variable *v; 17560 struct ast_flags config_flags = { reload == 1 ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 17561 const char *cat; 17562 int res; 17563 17564 #ifdef HAVE_PRI 17565 char *c; 17566 int spanno; 17567 int i; 17568 int logicalspan; 17569 int trunkgroup; 17570 int dchannels[SIG_PRI_NUM_DCHANS]; 17571 #endif 17572 17573 cfg = ast_config_load(config, config_flags); 17574 17575 /* Error if we have no config file */ 17576 if (!cfg) { 17577 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 17578 return 0; 17579 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 17580 ucfg = ast_config_load("users.conf", config_flags); 17581 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 17582 return 0; 17583 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 17584 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n"); 17585 return 0; 17586 } 17587 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 17588 if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) { 17589 ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config); 17590 ast_config_destroy(ucfg); 17591 return 0; 17592 } 17593 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 17594 ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config); 17595 return 0; 17596 } else { 17597 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 17598 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 17599 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n"); 17600 ast_config_destroy(cfg); 17601 return 0; 17602 } 17603 } 17604 17605 /* It's a little silly to lock it, but we might as well just to be sure */ 17606 ast_mutex_lock(&iflock); 17607 #ifdef HAVE_PRI 17608 if (reload != 1) { 17609 /* Process trunkgroups first */ 17610 v = ast_variable_browse(cfg, "trunkgroups"); 17611 while (v) { 17612 if (!strcasecmp(v->name, "trunkgroup")) { 17613 trunkgroup = atoi(v->value); 17614 if (trunkgroup > 0) { 17615 if ((c = strchr(v->value, ','))) { 17616 i = 0; 17617 memset(dchannels, 0, sizeof(dchannels)); 17618 while (c && (i < SIG_PRI_NUM_DCHANS)) { 17619 dchannels[i] = atoi(c + 1); 17620 if (dchannels[i] < 0) { 17621 ast_log(LOG_WARNING, "D-channel for trunk group %d must be a postiive number at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno); 17622 } else 17623 i++; 17624 c = strchr(c + 1, ','); 17625 } 17626 if (i) { 17627 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 17628 ast_log(LOG_WARNING, "Unable to create trunk group %d with Primary D-channel %d at line %d of chan_dahdi.conf\n", trunkgroup, dchannels[0], v->lineno); 17629 } else 17630 ast_verb(2, "Created trunk group %d with Primary D-channel %d and %d backup%s\n", trunkgroup, dchannels[0], i - 1, (i == 1) ? "" : "s"); 17631 } else 17632 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno); 17633 } else 17634 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno); 17635 } else 17636 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->lineno); 17637 } else if (!strcasecmp(v->name, "spanmap")) { 17638 spanno = atoi(v->value); 17639 if (spanno > 0) { 17640 if ((c = strchr(v->value, ','))) { 17641 trunkgroup = atoi(c + 1); 17642 if (trunkgroup > 0) { 17643 if ((c = strchr(c + 1, ','))) 17644 logicalspan = atoi(c + 1); 17645 else 17646 logicalspan = 0; 17647 if (logicalspan >= 0) { 17648 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 17649 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 17650 } else 17651 ast_verb(2, "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 17652 } else 17653 ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of chan_dahdi.conf\n", v->lineno); 17654 } else 17655 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of chan_dahdi.conf\n", v->lineno); 17656 } else 17657 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of chan_dahdi.conf\n", v->lineno); 17658 } else 17659 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of chan_dahdi.conf\n", v->lineno); 17660 } else { 17661 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 17662 } 17663 v = v->next; 17664 } 17665 } 17666 #endif 17667 17668 /* Copy the default jb config over global_jbconf */ 17669 memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf)); 17670 17671 mwimonitornotify[0] = '\0'; 17672 17673 v = ast_variable_browse(cfg, "channels"); 17674 if ((res = process_dahdi(base_conf, "", v, reload, 0))) { 17675 ast_mutex_unlock(&iflock); 17676 ast_config_destroy(cfg); 17677 if (ucfg) { 17678 ast_config_destroy(ucfg); 17679 } 17680 return res; 17681 } 17682 17683 /* Now get configuration from all normal sections in chan_dahdi.conf: */ 17684 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 17685 /* [channels] and [trunkgroups] are used. Let's also reserve 17686 * [globals] and [general] for future use 17687 */ 17688 if (!strcasecmp(cat, "general") || 17689 !strcasecmp(cat, "trunkgroups") || 17690 !strcasecmp(cat, "globals") || 17691 !strcasecmp(cat, "channels")) { 17692 continue; 17693 } 17694 17695 /* Copy base_conf to conf. */ 17696 deep_copy_dahdi_chan_conf(conf, base_conf); 17697 17698 if ((res = process_dahdi(conf, cat, ast_variable_browse(cfg, cat), reload, PROC_DAHDI_OPT_NOCHAN))) { 17699 ast_mutex_unlock(&iflock); 17700 ast_config_destroy(cfg); 17701 if (ucfg) { 17702 ast_config_destroy(ucfg); 17703 } 17704 return res; 17705 } 17706 } 17707 17708 ast_config_destroy(cfg); 17709 17710 if (ucfg) { 17711 const char *chans; 17712 17713 process_dahdi(base_conf, "", ast_variable_browse(ucfg, "general"), 1, 0); 17714 17715 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 17716 if (!strcasecmp(cat, "general")) { 17717 continue; 17718 } 17719 17720 chans = ast_variable_retrieve(ucfg, cat, "dahdichan"); 17721 17722 if (ast_strlen_zero(chans)) { 17723 continue; 17724 } 17725 17726 /* Copy base_conf to conf. */ 17727 deep_copy_dahdi_chan_conf(conf, base_conf); 17728 17729 if ((res = process_dahdi(conf, cat, ast_variable_browse(ucfg, cat), reload, PROC_DAHDI_OPT_NOCHAN | PROC_DAHDI_OPT_NOWARN))) { 17730 ast_config_destroy(ucfg); 17731 ast_mutex_unlock(&iflock); 17732 return res; 17733 } 17734 } 17735 ast_config_destroy(ucfg); 17736 } 17737 ast_mutex_unlock(&iflock); 17738 17739 #ifdef HAVE_PRI 17740 if (reload != 1) { 17741 int x; 17742 for (x = 0; x < NUM_SPANS; x++) { 17743 if (pris[x].pri.pvts[0]) { 17744 prepare_pri(pris + x); 17745 if (sig_pri_start_pri(&pris[x].pri)) { 17746 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 17747 return -1; 17748 } else 17749 ast_verb(2, "Starting D-Channel on span %d\n", x + 1); 17750 } 17751 } 17752 } 17753 #endif 17754 #if defined(HAVE_SS7) 17755 if (reload != 1) { 17756 int x; 17757 for (x = 0; x < NUM_SPANS; x++) { 17758 if (linksets[x].ss7.ss7) { 17759 linksets[x].ss7.calls = &dahdi_ss7_callbacks; 17760 if (ast_pthread_create(&linksets[x].ss7.master, NULL, ss7_linkset, &linksets[x].ss7)) { 17761 ast_log(LOG_ERROR, "Unable to start SS7 linkset on span %d\n", x + 1); 17762 return -1; 17763 } else 17764 ast_verb(2, "Starting SS7 linkset on span %d\n", x + 1); 17765 } 17766 } 17767 } 17768 #endif /* defined(HAVE_SS7) */ 17769 #ifdef HAVE_OPENR2 17770 if (reload != 1) { 17771 int x; 17772 for (x = 0; x < r2links_count; x++) { 17773 if (ast_pthread_create(&r2links[x]->r2master, NULL, mfcr2_monitor, r2links[x])) { 17774 ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1); 17775 return -1; 17776 } else { 17777 ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1); 17778 } 17779 } 17780 } 17781 #endif 17782 /* And start the monitor for the first time */ 17783 restart_monitor(); 17784 return 0; 17785 }
static int sig_pri_tone_to_dahditone | ( | enum sig_pri_tone | tone | ) | [static] |
Definition at line 2972 of file chan_dahdi.c.
References SIG_PRI_TONE_BUSY, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_DIALRECALL, SIG_PRI_TONE_DIALTONE, SIG_PRI_TONE_INFO, SIG_PRI_TONE_RINGTONE, and SIG_PRI_TONE_STUTTER.
Referenced by my_pri_play_tone().
02973 { 02974 switch (tone) { 02975 case SIG_PRI_TONE_RINGTONE: 02976 return DAHDI_TONE_RINGTONE; 02977 case SIG_PRI_TONE_STUTTER: 02978 return DAHDI_TONE_STUTTER; 02979 case SIG_PRI_TONE_CONGESTION: 02980 return DAHDI_TONE_CONGESTION; 02981 case SIG_PRI_TONE_DIALTONE: 02982 return DAHDI_TONE_DIALTONE; 02983 case SIG_PRI_TONE_DIALRECALL: 02984 return DAHDI_TONE_DIALRECALL; 02985 case SIG_PRI_TONE_INFO: 02986 return DAHDI_TONE_INFO; 02987 case SIG_PRI_TONE_BUSY: 02988 return DAHDI_TONE_BUSY; 02989 default: 02990 return -1; 02991 } 02992 }
static int sig_ss7_tone_to_dahditone | ( | enum sig_ss7_tone | tone | ) | [static] |
Definition at line 3401 of file chan_dahdi.c.
References SIG_SS7_TONE_BUSY, SIG_SS7_TONE_CONGESTION, SIG_SS7_TONE_DIALRECALL, SIG_SS7_TONE_DIALTONE, SIG_SS7_TONE_INFO, SIG_SS7_TONE_RINGTONE, and SIG_SS7_TONE_STUTTER.
Referenced by my_ss7_play_tone().
03402 { 03403 switch (tone) { 03404 case SIG_SS7_TONE_RINGTONE: 03405 return DAHDI_TONE_RINGTONE; 03406 case SIG_SS7_TONE_STUTTER: 03407 return DAHDI_TONE_STUTTER; 03408 case SIG_SS7_TONE_CONGESTION: 03409 return DAHDI_TONE_CONGESTION; 03410 case SIG_SS7_TONE_DIALTONE: 03411 return DAHDI_TONE_DIALTONE; 03412 case SIG_SS7_TONE_DIALRECALL: 03413 return DAHDI_TONE_DIALRECALL; 03414 case SIG_SS7_TONE_INFO: 03415 return DAHDI_TONE_INFO; 03416 case SIG_SS7_TONE_BUSY: 03417 return DAHDI_TONE_BUSY; 03418 default: 03419 return -1; 03420 } 03421 }
static int sigtype_to_signalling | ( | int | sigtype | ) | [static] |
static struct dahdi_ss7* ss7_resolve_linkset | ( | int | linkset | ) | [static] |
Definition at line 11755 of file chan_dahdi.c.
References linksets, and NUM_SPANS.
Referenced by linkset_addsigchan().
11756 { 11757 if ((linkset < 0) || (linkset >= NUM_SPANS)) 11758 return NULL; 11759 else 11760 return &linksets[linkset - 1]; 11761 }
static void string_replace | ( | char * | str, | |
int | char1, | |||
int | char2 | |||
) | [static] |
Definition at line 16285 of file chan_dahdi.c.
Referenced by parse_spanchan().
16286 { 16287 for (; *str; str++) { 16288 if (*str == char1) { 16289 *str = char2; 16290 } 16291 } 16292 }
static void swap_subs | ( | struct dahdi_pvt * | p, | |
int | a, | |||
int | b | |||
) | [static] |
Definition at line 4137 of file chan_dahdi.c.
References ast_channel_set_fd(), ast_debug, dahdi_subchannel::chan, dahdi_subchannel::dfd, dahdi_subchannel::inthreeway, dahdi_subchannel::owner, dahdi_pvt::subs, and wakeup_sub().
Referenced by analog_ss_thread(), attempt_transfer(), dahdi_handle_event(), dahdi_hangup(), HandleCallOutgoing(), and unistim_hangup().
04138 { 04139 int tchan; 04140 int tinthreeway; 04141 struct ast_channel *towner; 04142 04143 ast_debug(1, "Swapping %d and %d\n", a, b); 04144 04145 tchan = p->subs[a].chan; 04146 towner = p->subs[a].owner; 04147 tinthreeway = p->subs[a].inthreeway; 04148 04149 p->subs[a].chan = p->subs[b].chan; 04150 p->subs[a].owner = p->subs[b].owner; 04151 p->subs[a].inthreeway = p->subs[b].inthreeway; 04152 04153 p->subs[b].chan = tchan; 04154 p->subs[b].owner = towner; 04155 p->subs[b].inthreeway = tinthreeway; 04156 04157 if (p->subs[a].owner) 04158 ast_channel_set_fd(p->subs[a].owner, 0, p->subs[a].dfd); 04159 if (p->subs[b].owner) 04160 ast_channel_set_fd(p->subs[b].owner, 0, p->subs[b].dfd); 04161 wakeup_sub(p, a); 04162 wakeup_sub(p, b); 04163 }
static int unalloc_sub | ( | struct dahdi_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 4283 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_subchannel::chan, dahdi_pvt::channel, dahdi_subchannel::curconf, dahdi_close_sub(), dahdi_subchannel::inthreeway, dahdi_subchannel::linear, LOG_WARNING, dahdi_subchannel::owner, dahdi_pvt::polarity, POLARITY_IDLE, and dahdi_pvt::subs.
Referenced by analog_ss_thread(), attempt_transfer(), dahdi_handle_event(), dahdi_hangup(), my_unallocate_sub(), and unistim_hangup().
04284 { 04285 if (!x) { 04286 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel); 04287 return -1; 04288 } 04289 ast_debug(1, "Released sub %d of channel %d\n", x, p->channel); 04290 dahdi_close_sub(p, x); 04291 p->subs[x].linear = 0; 04292 p->subs[x].chan = 0; 04293 p->subs[x].owner = NULL; 04294 p->subs[x].inthreeway = 0; 04295 p->polarity = POLARITY_IDLE; 04296 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf)); 04297 return 0; 04298 }
static int unload_module | ( | void | ) | [static] |
Definition at line 16269 of file chan_dahdi.c.
References __unload_module(), ast_mutex_destroy, sig_ss7_linkset::lock, sig_pri_span::lock, dahdi_pvt::pri, and dahdi_pvt::ss7.
16270 { 16271 #if defined(HAVE_PRI) || defined(HAVE_SS7) 16272 int y; 16273 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 16274 #ifdef HAVE_PRI 16275 for (y = 0; y < NUM_SPANS; y++) 16276 ast_mutex_destroy(&pris[y].pri.lock); 16277 #endif 16278 #if defined(HAVE_SS7) 16279 for (y = 0; y < NUM_SPANS; y++) 16280 ast_mutex_destroy(&linksets[y].ss7.lock); 16281 #endif /* defined(HAVE_SS7) */ 16282 return __unload_module(); 16283 }
static int update_conf | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4692 of file chan_dahdi.c.
References conf_add(), conf_del(), dahdi_subchannel::dfd, dahdi_subchannel::inthreeway, isslavenative(), and dahdi_pvt::subs.
Referenced by __dahdi_exception(), dahdi_bridge(), dahdi_handle_event(), and dahdi_hangup().
04693 { 04694 int needconf = 0; 04695 int x; 04696 int useslavenative; 04697 struct dahdi_pvt *slave = NULL; 04698 04699 useslavenative = isslavenative(p, &slave); 04700 /* Start with the obvious, general stuff */ 04701 for (x = 0; x < 3; x++) { 04702 /* Look for three way calls */ 04703 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) { 04704 conf_add(p, &p->subs[x], x, 0); 04705 needconf++; 04706 } else { 04707 conf_del(p, &p->subs[x], x); 04708 } 04709 } 04710 /* If we have a slave, add him to our conference now. or DAX 04711 if this is slave native */ 04712 for (x = 0; x < MAX_SLAVES; x++) { 04713 if (p->slaves[x]) { 04714 if (useslavenative) 04715 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 04716 else { 04717 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 04718 needconf++; 04719 } 04720 } 04721 } 04722 /* If we're supposed to be in there, do so now */ 04723 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 04724 if (useslavenative) 04725 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 04726 else { 04727 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 04728 needconf++; 04729 } 04730 } 04731 /* If we have a master, add ourselves to his conference */ 04732 if (p->master) { 04733 if (isslavenative(p->master, NULL)) { 04734 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 04735 } else { 04736 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 04737 } 04738 } 04739 if (!needconf) { 04740 /* Nobody is left (or should be left) in our conference. 04741 Kill it. */ 04742 p->confno = -1; 04743 } 04744 ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 04745 return 0; 04746 }
static void wakeup_sub | ( | struct dahdi_pvt * | p, | |
int | a | |||
) | [static] |
Definition at line 3650 of file chan_dahdi.c.
References ast_channel_unlock, ast_null_frame, ast_queue_frame(), dahdi_lock_sub_owner(), dahdi_subchannel::owner, and dahdi_pvt::subs.
Referenced by my_swap_subchannels(), and swap_subs().
03651 { 03652 dahdi_lock_sub_owner(p, a); 03653 if (p->subs[a].owner) { 03654 ast_queue_frame(p->subs[a].owner, &ast_null_frame); 03655 ast_channel_unlock(p->subs[a].owner); 03656 } 03657 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = tdesc , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_smdi", } [static] |
Definition at line 18173 of file chan_dahdi.c.
int alarm |
struct { ... } alarms[] [static] |
Referenced by alarm2str().
struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}} [static] |
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 18173 of file chan_dahdi.c.
struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] [static] |
Definition at line 365 of file chan_dahdi.c.
Referenced by handle_dahdi_show_cadences(), and my_set_cadence().
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 376 of file chan_dahdi.c.
Referenced by handle_dahdi_show_cadences().
const char config[] = "chan_dahdi.conf" [static] |
Definition at line 319 of file chan_dahdi.c.
int cur_adjpointcode = -1 [static] |
int cur_cicbeginswith = -1 [static] |
Definition at line 521 of file chan_dahdi.c.
int cur_defaultdpc = -1 [static] |
int cur_linkset = -1 [static] |
int cur_networkindicator = -1 [static] |
int cur_pointcode = -1 [static] |
int cur_ss7type = -1 [static] |
const char* const dahdi_accept_r2_call_app = "DAHDIAcceptR2Call" [static] |
Definition at line 5839 of file chan_dahdi.c.
struct analog_callback dahdi_analog_callbacks [static] |
Definition at line 3528 of file chan_dahdi.c.
struct ast_data_handler dahdi_channels_data_provider [static] |
Initial value:
{ .version = AST_DATA_HANDLER_VERSION, .get = dahdi_channels_data_provider_get }
Definition at line 17954 of file chan_dahdi.c.
struct ast_cli_entry dahdi_cli[] [static] |
struct ast_data_entry dahdi_data_providers[] [static] |
Initial value:
{ AST_DATA_ENTRY("asterisk/channel/dahdi/status", &dahdi_status_data_provider), AST_DATA_ENTRY("asterisk/channel/dahdi/channels", &dahdi_channels_data_provider), }
Definition at line 17964 of file chan_dahdi.c.
Referenced by load_module().
struct ast_cli_entry dahdi_mfcr2_cli[] [static] |
struct sig_pri_callback dahdi_pri_callbacks [static] |
struct ast_cli_entry dahdi_pri_cli[] [static] |
struct dahdi_parms_pseudo dahdi_pseudo_parms [static] |
openr2_event_interface_t dahdi_r2_event_iface [static] |
Definition at line 4099 of file chan_dahdi.c.
openr2_transcoder_interface_t dahdi_r2_transcode_iface [static] |
Initial value:
Definition at line 4130 of file chan_dahdi.c.
char* dahdi_send_callrerouting_facility_app = "DAHDISendCallreroutingFacility" [static] |
Definition at line 5776 of file chan_dahdi.c.
char* dahdi_send_keypad_facility_app = "DAHDISendKeypadFacility" [static] |
Definition at line 5749 of file chan_dahdi.c.
struct sig_ss7_callback dahdi_ss7_callbacks [static] |
Definition at line 3434 of file chan_dahdi.c.
struct ast_cli_entry dahdi_ss7_cli[] [static] |
struct ast_data_handler dahdi_status_data_provider [static] |
Initial value:
{ .version = AST_DATA_HANDLER_VERSION, .get = dahdi_status_data_provider_get }
Definition at line 17949 of file chan_dahdi.c.
struct ast_channel_tech dahdi_tech [static] |
Definition at line 1492 of file chan_dahdi.c.
Referenced by __unload_module(), analog_ss_thread(), dahdi_accept_r2_call_exec(), dahdi_new(), dahdi_send_callrerouting_facility_exec(), and load_module().
struct ast_data_handler dahdi_version_data_provider [static] |
Initial value:
{ .version = AST_DATA_HANDLER_VERSION, .get = dahdi_version_data_provider_get }
Definition at line 17959 of file chan_dahdi.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 268 of file chan_dahdi.c.
char defaultcic[64] = "" [static] |
Definition at line 392 of file chan_dahdi.c.
char defaultozz[64] = "" [static] |
Definition at line 393 of file chan_dahdi.c.
int distinctiveringaftercid = 0 [static] |
Definition at line 406 of file chan_dahdi.c.
int dtmfcid_level = 256 [static] |
Definition at line 411 of file chan_dahdi.c.
const char* const events[] [static] |
Definition at line 4407 of file chan_dahdi.c.
int firstdigittimeout = 16000 [static] |
Wait up to 16 seconds for first digit (FXO logic).
Definition at line 423 of file chan_dahdi.c.
Referenced by analog_ss_thread(), disa_exec(), and mgcp_ss().
int gendigittimeout = 8000 [static] |
How long to wait for following digits (FXO logic).
Definition at line 426 of file chan_dahdi.c.
Referenced by analog_ss_thread(), and mgcp_ss().
struct ast_jb_conf global_jbconf [static] |
Definition at line 276 of file chan_dahdi.c.
int ifcount = 0 [static] |
Definition at line 435 of file chan_dahdi.c.
Referenced by destroy_all_channels(), and do_monitor().
Main interface list end
Definition at line 1296 of file chan_dahdi.c.
Referenced by dahdi_iflist_extract(), dahdi_request(), and determine_starting_point().
Main interface list start
Definition at line 1295 of file chan_dahdi.c.
Referenced by __oh323_destroy(), __unload_module(), action_dahdishowchannels(), dahdi_channels_data_provider_get(), dahdi_destroy_channel_bynum(), dahdi_iflist_extract(), dahdi_iflist_insert(), dahdi_request(), dahdi_set_dnd(), dahdi_set_hwgain(), dahdi_set_swgain(), dahdi_show_channel(), dahdi_show_channels(), dahdi_softhangup_all(), destroy_all_channels(), determine_starting_point(), do_monitor(), find_call_locked(), find_channel(), handle_mfcr2_call_files(), handle_mfcr2_set_blocked(), handle_mfcr2_set_debug(), handle_mfcr2_set_idle(), handle_mfcr2_show_channels(), load_module(), mkintf(), oh323_alloc(), phone_request(), and unload_module().
ast_mutex_t iflock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static] |
Protect the interface list (of dahdi_pvt's).
Definition at line 432 of file chan_dahdi.c.
Referenced by __unload_module(), dahdi_cc_callback(), dahdi_destroy_channel_bynum(), dahdi_hangup(), dahdi_request(), destroy_all_channels(), do_monitor(), find_call_locked(), load_module(), oh323_alloc(), oh323_destroy(), phone_request(), restart_monitor(), and unload_module().
const char* const lbostr[] [static] |
Definition at line 256 of file chan_dahdi.c.
Referenced by dahdi_show_status(), and dahdi_status_data_provider_get().
Definition at line 516 of file chan_dahdi.c.
Referenced by dahdi_ss7_error(), dahdi_ss7_message(), and ss7_resolve_linkset().
int matchdigittimeout = 3000 [static] |
How long to wait for an extra digit, if there is an ambiguous match.
Definition at line 429 of file chan_dahdi.c.
Referenced by analog_ss_thread(), and mgcp_ss().
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 447 of file chan_dahdi.c.
Referenced by __sip_reliable_xmit(), __unload_module(), restart_monitor(), and unload_module().
ast_mutex_t monlock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static] |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
Definition at line 443 of file chan_dahdi.c.
Referenced by __unload_module(), do_monitor(), restart_monitor(), and unload_module().
int mwilevel = 512 [static] |
char mwimonitornotify[PATH_MAX] = "" [static] |
Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled
Definition at line 398 of file chan_dahdi.c.
Referenced by notify_message(), and setup_dahdi_int().
char* name |
Definition at line 4431 of file chan_dahdi.c.
int num_cadence = 4 [static] |
Definition at line 362 of file chan_dahdi.c.
Referenced by handle_dahdi_show_cadences(), and my_set_cadence().
int num_restart_pending = 0 [static] |
Definition at line 452 of file chan_dahdi.c.
Referenced by dahdi_hangup(), dahdi_softhangup_all(), destroy_all_channels(), and my_all_subchannels_hungup().
int numbufs = 4 [static] |
Definition at line 408 of file chan_dahdi.c.
char parkinglot[AST_MAX_EXTENSION] = "" [static] |
Default parking lot for this channel
Definition at line 395 of file chan_dahdi.c.
Referenced by __find_callno(), ast_iax2_new(), build_parkinglot(), build_peer(), build_user(), builtin_atxfer(), check_access(), check_peer_ok(), copy_parkinglot(), create_addr_from_peer(), dahdi_new(), find_parkinglot(), find_parkinglot_by_exten_cb(), find_parkinglot_by_position_cb(), findparkinglotname(), func_channel_write_real(), gtalk_load_config(), gtalk_new(), park_exec_full(), park_space_reserve(), parkinglot_addref(), parkinglot_cmp_cb(), parkinglot_hash_cb(), parkinglot_is_marked_cb(), parkinglot_markall_cb(), parkinglot_unref(), set_pvt_defaults(), sip_alloc(), sip_new(), sip_park(), skinny_new(), and store_config_core().
int pridebugfd = -1 [static] |
Definition at line 418 of file chan_dahdi.c.
Referenced by dahdi_pri_error(), dahdi_pri_message(), and handle_pri_set_debug_file().
ast_mutex_t pridebugfdlock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static] |
Definition at line 438 of file chan_dahdi.c.
Referenced by dahdi_pri_error(), dahdi_pri_message(), and handle_pri_set_debug_file().
char pridebugfilename[1024] = "" [static] |
Definition at line 575 of file chan_dahdi.c.
Referenced by complete_span_helper(), dahdi_devicestate(), dahdi_pri_error(), dahdi_pri_message(), dahdi_restart(), destroy_all_channels(), handle_pri_debug(), handle_pri_service_generic(), handle_pri_show_debug(), handle_pri_show_span(), handle_pri_show_spans(), prepare_pri(), pri_create_spanmap(), pri_create_trunkgroup(), and pri_resolve_span().
char progzone[10] = "" [static] |
struct dahdi_mfcr2** r2links [static] |
Definition at line 560 of file chan_dahdi.c.
Referenced by dahdi_r2_destroy_links(), and dahdi_r2_get_link().
int r2links_count = 0 [static] |
Definition at line 562 of file chan_dahdi.c.
Referenced by dahdi_r2_destroy_links(), and dahdi_r2_get_link().
int report_alarms = REPORT_CHANNEL_ALARMS [static] |
Definition at line 415 of file chan_dahdi.c.
Referenced by handle_alarms(), and handle_clear_alarms().
ast_mutex_t restart_lock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static] |
int ringt_base = DEFAULT_RINGT [static] |
Configured ring timeout base.
Definition at line 508 of file chan_dahdi.c.
struct dahdi_pvt* round_robin[32] [static] |
Round robin search locations.
Definition at line 3597 of file chan_dahdi.c.
Referenced by dahdi_request(), determine_starting_point(), and load_module().
ast_cond_t ss_thread_complete [static] |
Definition at line 448 of file chan_dahdi.c.
Referenced by __unload_module(), load_module(), and my_decrease_ss_count().
int ss_thread_count = 0 [static] |
Definition at line 451 of file chan_dahdi.c.
Referenced by analog_ss_thread(), my_decrease_ss_count(), and my_increase_ss_count().
ast_mutex_t ss_thread_lock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static] |
Definition at line 449 of file chan_dahdi.c.
Referenced by analog_ss_thread(), my_decrease_ss_count(), and my_increase_ss_count().
const char* const subnames[] [static] |
Initial value:
{ "Real", "Callwait", "Threeway" }
Definition at line 608 of file chan_dahdi.c.
Referenced by alloc_sub(), dahdi_bridge(), and dahdi_new().
const char tdesc[] [static] |
Definition at line 298 of file chan_dahdi.c.
int usedistinctiveringdetection = 0 [static] |
Definition at line 405 of file chan_dahdi.c.
int user_has_defined_cadences = 0 [static] |
Definition at line 363 of file chan_dahdi.c.