#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 <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_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 | canmatch_featurecode (const char *exten) |
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 void | dahdi_ami_channel_event (struct dahdi_pvt *p, struct ast_channel *chan) |
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_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_cc_agent_destructor (struct ast_cc_agent *agent) |
static int | dahdi_pri_cc_agent_init (struct ast_cc_agent *agent, struct ast_channel *chan) |
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 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 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_channel_from_str (const char *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_channels (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 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 | 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_ami_channel_event (void *pvt, struct ast_channel *chan) |
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_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 int | my_have_progressdetect (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 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_dial_digits (void *p, const char *dial_string) |
static void | my_pri_fixup_chans (void *chan_old, void *chan_new) |
static void | my_pri_init_config (void *priv, struct sig_pri_span *pri) |
static void | my_pri_make_cc_dialstring (void *priv, char *buf, size_t buf_size) |
static int | my_pri_play_tone (void *pvt, enum sig_pri_tone tone) |
static void | my_pri_ss7_open_media (void *p) |
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 *cid_rings, 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_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_needringing (void *pvt, int value) |
static void | my_set_new_owner (void *pvt, struct ast_channel *new_owner) |
static void | my_set_outgoing (void *pvt, int is_outgoing) |
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_ringtimeout (void *pvt, int ringt) |
static void | my_set_waitingfordt (void *pvt, struct ast_channel *ast) |
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 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 *default_conf, 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 | sigtype_to_signalling (int sigtype) |
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 = "ac1f6a56484a8820659555499174e588" , .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 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_cc_agent_callbacks | dahdi_pri_cc_agent_callbacks |
static struct ast_cc_monitor_callbacks | dahdi_pri_cc_monitor_callbacks |
static const char | dahdi_pri_cc_type [] = "DAHDI/PRI" |
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 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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
Protect the interface list (of dahdi_pvt's). | |
static const char *const | lbostr [] |
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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
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 int | pridebugfd = -1 |
static ast_mutex_t | pridebugfdlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
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 314 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 381 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 |
Definition at line 378 of file chan_dahdi.c.
Referenced by dahdi_handle_event(), dahdi_new(), and my_have_progressdetect().
#define CALLWAITING_REPEAT_SAMPLES ((10000 * 8) / READ_SIZE) |
10,000 ms
Definition at line 516 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 515 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 412 of file chan_dahdi.c.
Referenced by dahdi_handle_event(), dahdi_new(), my_have_progressdetect(), and my_set_waitingfordt().
#define CHAN_PSEUDO -2 |
Definition at line 376 of file chan_dahdi.c.
Referenced by build_channels(), create_channel_name(), dahdi_ami_channel_event(), 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 652 of file chan_dahdi.c.
#define CONF_USER_THIRDCALL (1 << 1) |
Definition at line 653 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 3740 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 1244 of file chan_dahdi.c.
#define DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID.
Definition at line 312 of file chan_dahdi.c.
Referenced by dahdi_chan_conf_default().
#define DEFAULT_RINGT ((8000 * 8) / READ_SIZE) |
8,000 ms
Definition at line 520 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(), 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 15879 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_proceeding(), build_progress(), build_release(), build_release_complete(), build_restart(), build_retrieve_acknowledge(), build_setup(), build_setup_acknowledge(), 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 408 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 512 of file chan_dahdi.c.
#define MASK_INUSE (1 << 1) |
Channel currently in use
Definition at line 513 of file chan_dahdi.c.
#define MAX_CHANLIST_LEN 80 |
The length of the parameters list of 'dahdichan'.
Definition at line 16901 of file chan_dahdi.c.
#define MAX_SLAVES 4 |
Definition at line 655 of file chan_dahdi.c.
Referenced by isslavenative(), and my_complete_conference_update().
#define MIN_MS_SINCE_FLASH ((2000) ) |
2000 ms
Definition at line 519 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 318 of file chan_dahdi.c.
Referenced by analog_ss_thread(), and dahdi_new().
#define NUM_CADENCE_MAX 25 |
Definition at line 383 of file chan_dahdi.c.
#define NUM_SPANS 32 |
Definition at line 373 of file chan_dahdi.c.
Referenced by destroy_all_channels(), pri_create_trunkgroup(), and pri_resolve_span().
#define POLARITY_IDLE 0 |
Definition at line 612 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 613 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 16955 of file chan_dahdi.c.
Referenced by process_dahdi().
#define PROC_DAHDI_OPT_NOWARN (1 << 1) |
process_dahdi() - No warnings on non-existing cofiguration keywords
Definition at line 16957 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 510 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 433 of file chan_dahdi.c.
Referenced by handle_alarms(), and handle_clear_alarms().
#define REPORT_SPAN_ALARMS 2 |
Definition at line 434 of file chan_dahdi.c.
Referenced by handle_alarms(), and handle_clear_alarms().
#define sig2str dahdi_sig2str |
Definition at line 4675 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 359 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 360 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 348 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 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_EM_E1 DAHDI_SIG_EM_E1 |
Definition at line 368 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 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_FEATB (0x0800000 | DAHDI_SIG_EM) |
Definition at line 347 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 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_FEATDMF (0x0400000 | DAHDI_SIG_EM) |
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_FEATDMF_TA (0x2000000 | DAHDI_SIG_EM) |
Definition at line 349 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 350 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 351 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 356 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 357 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 355 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 353 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 354 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 352 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 362 of file chan_dahdi.c.
Referenced by dahdi_answer(), dahdi_call(), dahdi_func_read(), 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 84 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 1539 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 363 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 367 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 365 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 366 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 364 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 361 of file chan_dahdi.c.
Referenced by available(), dahdi_answer(), dahdi_call(), dahdi_confmute(), dahdi_enable_ec(), dahdi_func_read(), 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 608 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 607 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_off_hook(), my_pri_dial_digits(), my_pri_fixup_chans(), my_pri_play_tone(), my_pri_ss7_open_media(), my_set_cadence(), my_set_needringing(), my_set_polarity(), 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 609 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 15878 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 676 of file chan_dahdi.c.
00676 { 00677 DAHDI_IFLIST_NONE, /*!< The dahdi_pvt is not in any list. */ 00678 DAHDI_IFLIST_MAIN, /*!< The dahdi_pvt is in the main interface list */ 00679 #if defined(HAVE_PRI) 00680 DAHDI_IFLIST_NO_B_CHAN, /*!< The dahdi_pvt is in a no B channel interface list */ 00681 #endif /* defined(HAVE_PRI) */ 00682 };
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 660 of file chan_dahdi.c.
00660 { 00661 MWI_SEND_NULL = 0, 00662 MWI_SEND_SA, 00663 MWI_SEND_SA_WAIT, 00664 MWI_SEND_PAUSE, 00665 MWI_SEND_SPILL, 00666 MWI_SEND_CLEANUP, 00667 MWI_SEND_DONE, 00668 } mwisend_states;
static struct ast_frame* __dahdi_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 8786 of file chan_dahdi.c.
References ast_bridged_channel(), ast_channel_lock, ast_channel_unlock, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_NULL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_queue_control(), ast_set_hangupsource(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, 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, dahdi_pvt::lock, ast_frame::mallocd, name, 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().
08787 { 08788 int res; 08789 int idx; 08790 struct ast_frame *f; 08791 int usedindex = -1; 08792 struct dahdi_pvt *p = ast->tech_pvt; 08793 08794 if ((idx = dahdi_get_index(ast, p, 0)) < 0) { 08795 idx = SUB_REAL; 08796 } 08797 08798 p->subs[idx].f.frametype = AST_FRAME_NULL; 08799 p->subs[idx].f.datalen = 0; 08800 p->subs[idx].f.samples = 0; 08801 p->subs[idx].f.mallocd = 0; 08802 p->subs[idx].f.offset = 0; 08803 p->subs[idx].f.subclass.integer = 0; 08804 p->subs[idx].f.delivery = ast_tv(0,0); 08805 p->subs[idx].f.src = "dahdi_exception"; 08806 p->subs[idx].f.data.ptr = NULL; 08807 08808 08809 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) { 08810 /* If nobody owns us, absorb the event appropriately, otherwise 08811 we loop indefinitely. This occurs when, during call waiting, the 08812 other end hangs up our channel so that it no longer exists, but we 08813 have neither FLASH'd nor ONHOOK'd to signify our desire to 08814 change to the other channel. */ 08815 if (p->fake_event) { 08816 res = p->fake_event; 08817 p->fake_event = 0; 08818 } else 08819 res = dahdi_get_event(p->subs[SUB_REAL].dfd); 08820 /* Switch to real if there is one and this isn't something really silly... */ 08821 if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) && 08822 (res != DAHDI_EVENT_HOOKCOMPLETE)) { 08823 ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res); 08824 p->owner = p->subs[SUB_REAL].owner; 08825 if (p->owner && ast_bridged_channel(p->owner)) 08826 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08827 p->subs[SUB_REAL].needunhold = 1; 08828 } 08829 switch (res) { 08830 case DAHDI_EVENT_ONHOOK: 08831 dahdi_disable_ec(p); 08832 if (p->owner) { 08833 ast_verb(3, "Channel %s still has call, ringing phone\n", p->owner->name); 08834 dahdi_ring_phone(p); 08835 p->callwaitingrepeat = 0; 08836 p->cidcwexpire = 0; 08837 p->cid_suppress_expire = 0; 08838 } else 08839 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 08840 update_conf(p); 08841 break; 08842 case DAHDI_EVENT_RINGOFFHOOK: 08843 dahdi_enable_ec(p); 08844 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 08845 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 08846 p->subs[SUB_REAL].needanswer = 1; 08847 p->dialing = 0; 08848 } 08849 break; 08850 case DAHDI_EVENT_HOOKCOMPLETE: 08851 case DAHDI_EVENT_RINGERON: 08852 case DAHDI_EVENT_RINGEROFF: 08853 /* Do nothing */ 08854 break; 08855 case DAHDI_EVENT_WINKFLASH: 08856 p->flashtime = ast_tvnow(); 08857 if (p->owner) { 08858 ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 08859 if (p->owner->_state != AST_STATE_UP) { 08860 /* Answer if necessary */ 08861 usedindex = dahdi_get_index(p->owner, p, 0); 08862 if (usedindex > -1) { 08863 p->subs[usedindex].needanswer = 1; 08864 } 08865 ast_setstate(p->owner, AST_STATE_UP); 08866 } 08867 p->callwaitingrepeat = 0; 08868 p->cidcwexpire = 0; 08869 p->cid_suppress_expire = 0; 08870 if (ast_bridged_channel(p->owner)) 08871 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08872 p->subs[SUB_REAL].needunhold = 1; 08873 } else 08874 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 08875 update_conf(p); 08876 break; 08877 default: 08878 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 08879 } 08880 f = &p->subs[idx].f; 08881 return f; 08882 } 08883 if (!(p->radio || (p->oprmode < 0))) 08884 ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 08885 /* If it's not us, return NULL immediately */ 08886 if (ast != p->owner) { 08887 if (p->owner) { 08888 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 08889 } 08890 f = &p->subs[idx].f; 08891 return f; 08892 } 08893 08894 f = dahdi_handle_event(ast); 08895 if (!f) { 08896 const char *name = ast_strdupa(ast->name); 08897 08898 /* Tell the CDR this DAHDI device hung up */ 08899 ast_mutex_unlock(&p->lock); 08900 ast_channel_unlock(ast); 08901 ast_set_hangupsource(ast, name, 0); 08902 ast_channel_lock(ast); 08903 ast_mutex_lock(&p->lock); 08904 } 08905 return f; 08906 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 18772 of file chan_dahdi.c.
static int __unload_module | ( | void | ) | [static] |
Definition at line 16701 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_mfcr2_cli, dahdi_pri_cc_agent_callbacks, dahdi_pri_cc_monitor_callbacks, dahdi_pri_cli, dahdi_r2_destroy_links(), 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(), and ss_thread_complete.
Referenced by load_module(), and unload_module().
16702 { 16703 struct dahdi_pvt *p; 16704 #if defined(HAVE_PRI) || defined(HAVE_SS7) 16705 int i, j; 16706 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 16707 16708 #ifdef HAVE_PRI 16709 for (i = 0; i < NUM_SPANS; i++) { 16710 if (pris[i].pri.master != AST_PTHREADT_NULL) 16711 pthread_cancel(pris[i].pri.master); 16712 } 16713 ast_cli_unregister_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli)); 16714 ast_unregister_application(dahdi_send_keypad_facility_app); 16715 #ifdef HAVE_PRI_PROG_W_CAUSE 16716 ast_unregister_application(dahdi_send_callrerouting_facility_app); 16717 #endif 16718 #endif 16719 #if defined(HAVE_SS7) 16720 for (i = 0; i < NUM_SPANS; i++) { 16721 if (linksets[i].ss7.master != AST_PTHREADT_NULL) 16722 pthread_cancel(linksets[i].ss7.master); 16723 } 16724 ast_cli_unregister_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli)); 16725 #endif /* defined(HAVE_SS7) */ 16726 #if defined(HAVE_OPENR2) 16727 dahdi_r2_destroy_links(); 16728 ast_cli_unregister_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli)); 16729 ast_unregister_application(dahdi_accept_r2_call_app); 16730 #endif 16731 16732 ast_cli_unregister_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli)); 16733 ast_manager_unregister("DAHDIDialOffhook"); 16734 ast_manager_unregister("DAHDIHangup"); 16735 ast_manager_unregister("DAHDITransfer"); 16736 ast_manager_unregister("DAHDIDNDoff"); 16737 ast_manager_unregister("DAHDIDNDon"); 16738 ast_manager_unregister("DAHDIShowChannels"); 16739 ast_manager_unregister("DAHDIRestart"); 16740 ast_data_unregister(NULL); 16741 ast_channel_unregister(&dahdi_tech); 16742 16743 /* Hangup all interfaces if they have an owner */ 16744 ast_mutex_lock(&iflock); 16745 for (p = iflist; p; p = p->next) { 16746 if (p->owner) 16747 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 16748 } 16749 ast_mutex_unlock(&iflock); 16750 16751 ast_mutex_lock(&monlock); 16752 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 16753 pthread_cancel(monitor_thread); 16754 pthread_kill(monitor_thread, SIGURG); 16755 pthread_join(monitor_thread, NULL); 16756 } 16757 monitor_thread = AST_PTHREADT_STOP; 16758 ast_mutex_unlock(&monlock); 16759 16760 destroy_all_channels(); 16761 16762 #if defined(HAVE_PRI) 16763 for (i = 0; i < NUM_SPANS; i++) { 16764 if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) 16765 pthread_join(pris[i].pri.master, NULL); 16766 for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) { 16767 dahdi_close_pri_fd(&(pris[i]), j); 16768 } 16769 sig_pri_stop_pri(&pris[i].pri); 16770 } 16771 #if defined(HAVE_PRI_CCSS) 16772 ast_cc_agent_unregister(&dahdi_pri_cc_agent_callbacks); 16773 ast_cc_monitor_unregister(&dahdi_pri_cc_monitor_callbacks); 16774 #endif /* defined(HAVE_PRI_CCSS) */ 16775 sig_pri_unload(); 16776 #endif 16777 16778 #if defined(HAVE_SS7) 16779 for (i = 0; i < NUM_SPANS; i++) { 16780 if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) 16781 pthread_join(linksets[i].ss7.master, NULL); 16782 for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) { 16783 dahdi_close_ss7_fd(&(linksets[i]), j); 16784 } 16785 } 16786 #endif /* defined(HAVE_SS7) */ 16787 ast_cond_destroy(&ss_thread_complete); 16788 return 0; 16789 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 18772 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 3741 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.
03742 { 03743 int res; 03744 if (p->subs[SUB_REAL].owner == ast) 03745 res = 0; 03746 else if (p->subs[SUB_CALLWAIT].owner == ast) 03747 res = 1; 03748 else if (p->subs[SUB_THREEWAY].owner == ast) 03749 res = 2; 03750 else { 03751 res = -1; 03752 if (!nullok) 03753 ast_log(LOG_WARNING, 03754 "Unable to get index for '%s' on channel %d (%s(), line %lu)\n", 03755 ast ? ast->name : "", p->channel, fname, line); 03756 } 03757 return res; 03758 }
static int action_dahdidialoffhook | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 16016 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_from_str(), and dahdi_pvt::owner.
Referenced by load_module().
16017 { 16018 struct dahdi_pvt *p; 16019 const char *channel = astman_get_header(m, "DAHDIChannel"); 16020 const char *number = astman_get_header(m, "Number"); 16021 int i; 16022 16023 if (ast_strlen_zero(channel)) { 16024 astman_send_error(s, m, "No channel specified"); 16025 return 0; 16026 } 16027 if (ast_strlen_zero(number)) { 16028 astman_send_error(s, m, "No number specified"); 16029 return 0; 16030 } 16031 p = find_channel_from_str(channel); 16032 if (!p) { 16033 astman_send_error(s, m, "No such channel"); 16034 return 0; 16035 } 16036 if (!p->owner) { 16037 astman_send_error(s, m, "Channel does not have it's owner"); 16038 return 0; 16039 } 16040 for (i = 0; i < strlen(number); i++) { 16041 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = number[i] }; 16042 dahdi_queue_frame(p, &f); 16043 } 16044 astman_send_ack(s, m, "DAHDIDialOffhook"); 16045 return 0; 16046 }
static int action_dahdidndoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 15951 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_from_str().
Referenced by load_module().
15952 { 15953 struct dahdi_pvt *p; 15954 const char *channel = astman_get_header(m, "DAHDIChannel"); 15955 15956 if (ast_strlen_zero(channel)) { 15957 astman_send_error(s, m, "No channel specified"); 15958 return 0; 15959 } 15960 p = find_channel_from_str(channel); 15961 if (!p) { 15962 astman_send_error(s, m, "No such channel"); 15963 return 0; 15964 } 15965 dahdi_dnd(p, 0); 15966 astman_send_ack(s, m, "DND Disabled"); 15967 return 0; 15968 }
static int action_dahdidndon | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 15932 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_from_str().
Referenced by load_module().
15933 { 15934 struct dahdi_pvt *p; 15935 const char *channel = astman_get_header(m, "DAHDIChannel"); 15936 15937 if (ast_strlen_zero(channel)) { 15938 astman_send_error(s, m, "No channel specified"); 15939 return 0; 15940 } 15941 p = find_channel_from_str(channel); 15942 if (!p) { 15943 astman_send_error(s, m, "No such channel"); 15944 return 0; 15945 } 15946 dahdi_dnd(p, 1); 15947 astman_send_ack(s, m, "DND Enabled"); 15948 return 0; 15949 }
static int action_dahdirestart | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 15215 of file chan_dahdi.c.
References astman_send_ack(), astman_send_error(), and dahdi_restart().
Referenced by load_module().
15216 { 15217 if (dahdi_restart() != 0) { 15218 astman_send_error(s, m, "Failed rereading DAHDI configuration"); 15219 return 1; 15220 } 15221 astman_send_ack(s, m, "DAHDIRestart: Success"); 15222 return 0; 15223 }
static int action_dahdishowchannels | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 16048 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().
16049 { 16050 struct dahdi_pvt *tmp = NULL; 16051 const char *id = astman_get_header(m, "ActionID"); 16052 const char *dahdichannel = astman_get_header(m, "DAHDIChannel"); 16053 char idText[256] = ""; 16054 int channels = 0; 16055 int dahdichanquery; 16056 16057 if (!dahdichannel || sscanf(dahdichannel, "%30d", &dahdichanquery) != 1) { 16058 /* Not numeric string. */ 16059 dahdichanquery = -1; 16060 } 16061 16062 astman_send_ack(s, m, "DAHDI channel status will follow"); 16063 if (!ast_strlen_zero(id)) 16064 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 16065 16066 ast_mutex_lock(&iflock); 16067 16068 for (tmp = iflist; tmp; tmp = tmp->next) { 16069 if (tmp->channel > 0) { 16070 int alm; 16071 16072 /* If a specific channel is queried for, only deliver status for that channel */ 16073 if (dahdichanquery > 0 && tmp->channel != dahdichanquery) 16074 continue; 16075 16076 alm = get_alarms(tmp); 16077 channels++; 16078 if (tmp->owner) { 16079 /* Add data if we have a current call */ 16080 astman_append(s, 16081 "Event: DAHDIShowChannels\r\n" 16082 "DAHDIChannel: %d\r\n" 16083 "Channel: %s\r\n" 16084 "Uniqueid: %s\r\n" 16085 "AccountCode: %s\r\n" 16086 "Signalling: %s\r\n" 16087 "SignallingCode: %d\r\n" 16088 "Context: %s\r\n" 16089 "DND: %s\r\n" 16090 "Alarm: %s\r\n" 16091 "%s" 16092 "\r\n", 16093 tmp->channel, 16094 tmp->owner->name, 16095 tmp->owner->uniqueid, 16096 tmp->owner->accountcode, 16097 sig2str(tmp->sig), 16098 tmp->sig, 16099 tmp->context, 16100 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled", 16101 alarm2str(alm), idText); 16102 } else { 16103 astman_append(s, 16104 "Event: DAHDIShowChannels\r\n" 16105 "DAHDIChannel: %d\r\n" 16106 "Signalling: %s\r\n" 16107 "SignallingCode: %d\r\n" 16108 "Context: %s\r\n" 16109 "DND: %s\r\n" 16110 "Alarm: %s\r\n" 16111 "%s" 16112 "\r\n", 16113 tmp->channel, sig2str(tmp->sig), tmp->sig, 16114 tmp->context, 16115 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled", 16116 alarm2str(alm), idText); 16117 } 16118 } 16119 } 16120 16121 ast_mutex_unlock(&iflock); 16122 16123 astman_append(s, 16124 "Event: DAHDIShowChannelsComplete\r\n" 16125 "%s" 16126 "Items: %d\r\n" 16127 "\r\n", 16128 idText, 16129 channels); 16130 return 0; 16131 }
static int action_transfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 15970 of file chan_dahdi.c.
References analog_lib_handles(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_fake_event(), find_channel_from_str(), dahdi_pvt::sig, and TRANSFER.
Referenced by load_module().
15971 { 15972 struct dahdi_pvt *p; 15973 const char *channel = astman_get_header(m, "DAHDIChannel"); 15974 15975 if (ast_strlen_zero(channel)) { 15976 astman_send_error(s, m, "No channel specified"); 15977 return 0; 15978 } 15979 p = find_channel_from_str(channel); 15980 if (!p) { 15981 astman_send_error(s, m, "No such channel"); 15982 return 0; 15983 } 15984 if (!analog_lib_handles(p->sig, 0, 0)) { 15985 astman_send_error(s, m, "Channel signaling is not analog"); 15986 return 0; 15987 } 15988 dahdi_fake_event(p,TRANSFER); 15989 astman_send_ack(s, m, "DAHDITransfer"); 15990 return 0; 15991 }
static int action_transferhangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 15993 of file chan_dahdi.c.
References analog_lib_handles(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_fake_event(), find_channel_from_str(), HANGUP, and dahdi_pvt::sig.
Referenced by load_module().
15994 { 15995 struct dahdi_pvt *p; 15996 const char *channel = astman_get_header(m, "DAHDIChannel"); 15997 15998 if (ast_strlen_zero(channel)) { 15999 astman_send_error(s, m, "No channel specified"); 16000 return 0; 16001 } 16002 p = find_channel_from_str(channel); 16003 if (!p) { 16004 astman_send_error(s, m, "No such channel"); 16005 return 0; 16006 } 16007 if (!analog_lib_handles(p->sig, 0, 0)) { 16008 astman_send_error(s, m, "Channel signaling is not analog"); 16009 return 0; 16010 } 16011 dahdi_fake_event(p,HANGUP); 16012 astman_send_ack(s, m, "DAHDIHangup"); 16013 return 0; 16014 }
static char* alarm2str | ( | int | alm | ) | [static] |
Definition at line 4592 of file chan_dahdi.c.
References alarm, alarms, and ARRAY_LEN.
Referenced by action_dahdishowchannels(), and handle_alarms().
04593 { 04594 int x; 04595 for (x = 0; x < ARRAY_LEN(alarms); x++) { 04596 if (alarms[x].alarm & alm) 04597 return alarms[x].name; 04598 } 04599 return alm ? "Unknown Alarm" : "No Alarm"; 04600 }
static int alloc_sub | ( | struct dahdi_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 4393 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().
04394 { 04395 struct dahdi_bufferinfo bi; 04396 int res; 04397 if (p->subs[x].dfd >= 0) { 04398 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel); 04399 return -1; 04400 } 04401 04402 p->subs[x].dfd = dahdi_open("/dev/dahdi/pseudo"); 04403 if (p->subs[x].dfd <= -1) { 04404 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 04405 return -1; 04406 } 04407 04408 res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi); 04409 if (!res) { 04410 bi.txbufpolicy = p->buf_policy; 04411 bi.rxbufpolicy = p->buf_policy; 04412 bi.numbufs = p->buf_no; 04413 res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi); 04414 if (res < 0) { 04415 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno)); 04416 } 04417 } else 04418 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno)); 04419 04420 if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) { 04421 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno)); 04422 dahdi_close_sub(p, x); 04423 p->subs[x].dfd = -1; 04424 return -1; 04425 } 04426 ast_debug(1, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan); 04427 return 0; 04428 }
static int analog_lib_handles | ( | int | signalling, | |
int | radio, | |||
int | oprmode | |||
) | [static] |
Definition at line 4677 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 action_transfer(), action_transferhangup(), 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().
04678 { 04679 switch (signalling) { 04680 case SIG_FXOLS: 04681 case SIG_FXOGS: 04682 case SIG_FXOKS: 04683 case SIG_FXSLS: 04684 case SIG_FXSGS: 04685 case SIG_FXSKS: 04686 case SIG_EMWINK: 04687 case SIG_EM: 04688 case SIG_EM_E1: 04689 case SIG_FEATD: 04690 case SIG_FEATDMF: 04691 case SIG_E911: 04692 case SIG_FGC_CAMA: 04693 case SIG_FGC_CAMAMF: 04694 case SIG_FEATB: 04695 case SIG_SFWINK: 04696 case SIG_SF: 04697 case SIG_SF_FEATD: 04698 case SIG_SF_FEATDMF: 04699 case SIG_FEATDMF_TA: 04700 case SIG_SF_FEATB: 04701 break; 04702 default: 04703 /* The rest of the function should cover the remainder of signalling types */ 04704 return 0; 04705 } 04706 04707 if (radio) 04708 return 0; 04709 04710 if (oprmode) 04711 return 0; 04712 04713 return 1; 04714 }
static void * analog_ss_thread | ( | void * | data | ) | [static] |
Definition at line 9927 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_exten(), 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, canmatch_featurecode(), 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, 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().
09928 { 09929 struct ast_channel *chan = data; 09930 struct dahdi_pvt *p = chan->tech_pvt; 09931 char exten[AST_MAX_EXTENSION] = ""; 09932 char exten2[AST_MAX_EXTENSION] = ""; 09933 unsigned char buf[256]; 09934 char dtmfcid[300]; 09935 char dtmfbuf[300]; 09936 struct callerid_state *cs = NULL; 09937 char *name = NULL, *number = NULL; 09938 int distMatches; 09939 int curRingData[3]; 09940 int receivedRingT; 09941 int counter1; 09942 int counter; 09943 int samples = 0; 09944 struct ast_smdi_md_message *smdi_msg = NULL; 09945 int flags = 0; 09946 int i; 09947 int timeout; 09948 int getforward = 0; 09949 char *s1, *s2; 09950 int len = 0; 09951 int res; 09952 int idx; 09953 09954 ast_mutex_lock(&ss_thread_lock); 09955 ss_thread_count++; 09956 ast_mutex_unlock(&ss_thread_lock); 09957 /* in the bizarre case where the channel has become a zombie before we 09958 even get started here, abort safely 09959 */ 09960 if (!p) { 09961 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 09962 ast_hangup(chan); 09963 goto quit; 09964 } 09965 ast_verb(3, "Starting simple switch on '%s'\n", chan->name); 09966 idx = dahdi_get_index(chan, p, 1); 09967 if (idx < 0) { 09968 ast_log(LOG_WARNING, "Huh?\n"); 09969 ast_hangup(chan); 09970 goto quit; 09971 } 09972 if (p->dsp) 09973 ast_dsp_digitreset(p->dsp); 09974 switch (p->sig) { 09975 case SIG_FEATD: 09976 case SIG_FEATDMF: 09977 case SIG_FEATDMF_TA: 09978 case SIG_E911: 09979 case SIG_FGC_CAMAMF: 09980 case SIG_FEATB: 09981 case SIG_EMWINK: 09982 case SIG_SF_FEATD: 09983 case SIG_SF_FEATDMF: 09984 case SIG_SF_FEATB: 09985 case SIG_SFWINK: 09986 if (dahdi_wink(p, idx)) 09987 goto quit; 09988 /* Fall through */ 09989 case SIG_EM: 09990 case SIG_EM_E1: 09991 case SIG_SF: 09992 case SIG_FGC_CAMA: 09993 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 09994 if (p->dsp) 09995 ast_dsp_digitreset(p->dsp); 09996 /* set digit mode appropriately */ 09997 if (p->dsp) { 09998 if (NEED_MFDETECT(p)) 09999 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 10000 else 10001 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 10002 } 10003 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 10004 /* Wait for the first digit only if immediate=no */ 10005 if (!p->immediate) 10006 /* Wait for the first digit (up to 5 seconds). */ 10007 res = ast_waitfordigit(chan, 5000); 10008 else 10009 res = 0; 10010 if (res > 0) { 10011 /* save first char */ 10012 dtmfbuf[0] = res; 10013 switch (p->sig) { 10014 case SIG_FEATD: 10015 case SIG_SF_FEATD: 10016 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 10017 if (res > 0) 10018 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 10019 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10020 break; 10021 case SIG_FEATDMF_TA: 10022 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10023 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10024 if (dahdi_wink(p, idx)) goto quit; 10025 dtmfbuf[0] = 0; 10026 /* Wait for the first digit (up to 5 seconds). */ 10027 res = ast_waitfordigit(chan, 5000); 10028 if (res <= 0) break; 10029 dtmfbuf[0] = res; 10030 /* fall through intentionally */ 10031 case SIG_FEATDMF: 10032 case SIG_E911: 10033 case SIG_FGC_CAMAMF: 10034 case SIG_SF_FEATDMF: 10035 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10036 /* if international caca, do it again to get real ANO */ 10037 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14)) 10038 { 10039 if (dahdi_wink(p, idx)) goto quit; 10040 dtmfbuf[0] = 0; 10041 /* Wait for the first digit (up to 5 seconds). */ 10042 res = ast_waitfordigit(chan, 5000); 10043 if (res <= 0) break; 10044 dtmfbuf[0] = res; 10045 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10046 } 10047 if (res > 0) { 10048 /* if E911, take off hook */ 10049 if (p->sig == SIG_E911) 10050 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 10051 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 10052 } 10053 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10054 break; 10055 case SIG_FEATB: 10056 case SIG_SF_FEATB: 10057 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10058 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10059 break; 10060 case SIG_EMWINK: 10061 /* if we received a '*', we are actually receiving Feature Group D 10062 dial syntax, so use that mode; otherwise, fall through to normal 10063 mode 10064 */ 10065 if (res == '*') { 10066 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 10067 if (res > 0) 10068 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 10069 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10070 break; 10071 } 10072 default: 10073 /* If we got the first digit, get the rest */ 10074 len = 1; 10075 dtmfbuf[len] = '\0'; 10076 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 10077 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 10078 timeout = matchdigittimeout; 10079 } else { 10080 timeout = gendigittimeout; 10081 } 10082 res = ast_waitfordigit(chan, timeout); 10083 if (res < 0) { 10084 ast_debug(1, "waitfordigit returned < 0...\n"); 10085 ast_hangup(chan); 10086 goto quit; 10087 } else if (res) { 10088 dtmfbuf[len++] = res; 10089 dtmfbuf[len] = '\0'; 10090 } else { 10091 break; 10092 } 10093 } 10094 break; 10095 } 10096 } 10097 if (res == -1) { 10098 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 10099 ast_hangup(chan); 10100 goto quit; 10101 } else if (res < 0) { 10102 ast_debug(1, "Got hung up before digits finished\n"); 10103 ast_hangup(chan); 10104 goto quit; 10105 } 10106 10107 if (p->sig == SIG_FGC_CAMA) { 10108 char anibuf[100]; 10109 10110 if (ast_safe_sleep(chan,1000) == -1) { 10111 ast_hangup(chan); 10112 goto quit; 10113 } 10114 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 10115 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 10116 res = my_getsigstr(chan, anibuf, "#", 10000); 10117 if ((res > 0) && (strlen(anibuf) > 2)) { 10118 if (anibuf[strlen(anibuf) - 1] == '#') 10119 anibuf[strlen(anibuf) - 1] = 0; 10120 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 10121 } 10122 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 10123 } 10124 10125 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 10126 if (ast_strlen_zero(exten)) 10127 ast_copy_string(exten, "s", sizeof(exten)); 10128 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 10129 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 10130 if (exten[0] == '*') { 10131 char *stringp=NULL; 10132 ast_copy_string(exten2, exten, sizeof(exten2)); 10133 /* Parse out extension and callerid */ 10134 stringp=exten2 +1; 10135 s1 = strsep(&stringp, "*"); 10136 s2 = strsep(&stringp, "*"); 10137 if (s2) { 10138 if (!ast_strlen_zero(p->cid_num)) 10139 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 10140 else 10141 ast_set_callerid(chan, s1, NULL, s1); 10142 ast_copy_string(exten, s2, sizeof(exten)); 10143 } else 10144 ast_copy_string(exten, s1, sizeof(exten)); 10145 } else if (p->sig == SIG_FEATD) 10146 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 10147 } 10148 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 10149 if (exten[0] == '*') { 10150 char *stringp=NULL; 10151 ast_copy_string(exten2, exten, sizeof(exten2)); 10152 /* Parse out extension and callerid */ 10153 stringp=exten2 +1; 10154 s1 = strsep(&stringp, "#"); 10155 s2 = strsep(&stringp, "#"); 10156 if (s2) { 10157 if (!ast_strlen_zero(p->cid_num)) 10158 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 10159 else 10160 if (*(s1 + 2)) 10161 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 10162 ast_copy_string(exten, s2 + 1, sizeof(exten)); 10163 } else 10164 ast_copy_string(exten, s1 + 2, sizeof(exten)); 10165 } else 10166 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 10167 } 10168 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) { 10169 if (exten[0] == '*') { 10170 char *stringp=NULL; 10171 ast_copy_string(exten2, exten, sizeof(exten2)); 10172 /* Parse out extension and callerid */ 10173 stringp=exten2 +1; 10174 s1 = strsep(&stringp, "#"); 10175 s2 = strsep(&stringp, "#"); 10176 if (s2 && (*(s2 + 1) == '0')) { 10177 if (*(s2 + 2)) 10178 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 10179 } 10180 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 10181 else ast_copy_string(exten, "911", sizeof(exten)); 10182 } else 10183 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 10184 } 10185 if (p->sig == SIG_FEATB) { 10186 if (exten[0] == '*') { 10187 char *stringp=NULL; 10188 ast_copy_string(exten2, exten, sizeof(exten2)); 10189 /* Parse out extension and callerid */ 10190 stringp=exten2 +1; 10191 s1 = strsep(&stringp, "#"); 10192 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 10193 } else 10194 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 10195 } 10196 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 10197 dahdi_wink(p, idx); 10198 /* some switches require a minimum guard time between 10199 the last FGD wink and something that answers 10200 immediately. This ensures it */ 10201 if (ast_safe_sleep(chan, 100)) { 10202 ast_hangup(chan); 10203 goto quit; 10204 } 10205 } 10206 dahdi_enable_ec(p); 10207 if (NEED_MFDETECT(p)) { 10208 if (p->dsp) { 10209 if (!p->hardwaredtmf) 10210 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 10211 else { 10212 ast_dsp_free(p->dsp); 10213 p->dsp = NULL; 10214 } 10215 } 10216 } 10217 10218 if (ast_exists_extension(chan, chan->context, exten, 1, 10219 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 10220 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 10221 if (p->dsp) ast_dsp_digitreset(p->dsp); 10222 res = ast_pbx_run(chan); 10223 if (res) { 10224 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 10225 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10226 } 10227 goto quit; 10228 } else { 10229 ast_verb(2, "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 10230 sleep(2); 10231 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_INFO); 10232 if (res < 0) 10233 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 10234 else 10235 sleep(1); 10236 res = ast_streamfile(chan, "ss-noservice", chan->language); 10237 if (res >= 0) 10238 ast_waitstream(chan, ""); 10239 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10240 ast_hangup(chan); 10241 goto quit; 10242 } 10243 break; 10244 case SIG_FXOLS: 10245 case SIG_FXOGS: 10246 case SIG_FXOKS: 10247 /* Read the first digit */ 10248 timeout = firstdigittimeout; 10249 /* If starting a threeway call, never timeout on the first digit so someone 10250 can use flash-hook as a "hold" feature */ 10251 if (p->subs[SUB_THREEWAY].owner) 10252 timeout = 999999; 10253 while (len < AST_MAX_EXTENSION-1) { 10254 /* Read digit unless it's supposed to be immediate, in which case the 10255 only answer is 's' */ 10256 if (p->immediate) 10257 res = 's'; 10258 else 10259 res = ast_waitfordigit(chan, timeout); 10260 timeout = 0; 10261 if (res < 0) { 10262 ast_debug(1, "waitfordigit returned < 0...\n"); 10263 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 10264 ast_hangup(chan); 10265 goto quit; 10266 } else if (res) { 10267 ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout); 10268 exten[len++]=res; 10269 exten[len] = '\0'; 10270 } 10271 if (!ast_ignore_pattern(chan->context, exten)) 10272 tone_zone_play_tone(p->subs[idx].dfd, -1); 10273 else 10274 tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE); 10275 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && !ast_parking_ext_valid(exten, chan, chan->context)) { 10276 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 10277 if (getforward) { 10278 /* Record this as the forwarding extension */ 10279 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 10280 ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 10281 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10282 if (res) 10283 break; 10284 usleep(500000); 10285 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 10286 sleep(1); 10287 memset(exten, 0, sizeof(exten)); 10288 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE); 10289 len = 0; 10290 getforward = 0; 10291 } else { 10292 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 10293 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 10294 if (!ast_strlen_zero(p->cid_num)) { 10295 if (!p->hidecallerid) 10296 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 10297 else 10298 ast_set_callerid(chan, NULL, NULL, p->cid_num); 10299 } 10300 if (!ast_strlen_zero(p->cid_name)) { 10301 if (!p->hidecallerid) 10302 ast_set_callerid(chan, NULL, p->cid_name, NULL); 10303 } 10304 ast_setstate(chan, AST_STATE_RING); 10305 dahdi_enable_ec(p); 10306 res = ast_pbx_run(chan); 10307 if (res) { 10308 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 10309 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10310 } 10311 goto quit; 10312 } 10313 } else { 10314 /* It's a match, but they just typed a digit, and there is an ambiguous match, 10315 so just set the timeout to matchdigittimeout and wait some more */ 10316 timeout = matchdigittimeout; 10317 } 10318 } else if (res == 0) { 10319 ast_debug(1, "not enough digits (and no ambiguous match)...\n"); 10320 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10321 dahdi_wait_event(p->subs[idx].dfd); 10322 ast_hangup(chan); 10323 goto quit; 10324 } else if (p->callwaiting && !strcmp(exten, "*70")) { 10325 ast_verb(3, "Disabling call waiting on %s\n", chan->name); 10326 /* Disable call waiting if enabled */ 10327 p->callwaiting = 0; 10328 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10329 if (res) { 10330 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 10331 chan->name, strerror(errno)); 10332 } 10333 len = 0; 10334 ioctl(p->subs[idx].dfd,DAHDI_CONFDIAG,&len); 10335 memset(exten, 0, sizeof(exten)); 10336 timeout = firstdigittimeout; 10337 10338 } else if (!strcmp(exten,ast_pickup_ext())) { 10339 /* Scan all channels and see if there are any 10340 * ringing channels that have call groups 10341 * that equal this channels pickup group 10342 */ 10343 if (idx == SUB_REAL) { 10344 /* Switch us from Third call to Call Wait */ 10345 if (p->subs[SUB_THREEWAY].owner) { 10346 /* If you make a threeway call and the *8# a call, it should actually 10347 look like a callwait */ 10348 alloc_sub(p, SUB_CALLWAIT); 10349 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 10350 unalloc_sub(p, SUB_THREEWAY); 10351 } 10352 dahdi_enable_ec(p); 10353 if (ast_pickup_call(chan)) { 10354 ast_debug(1, "No call pickup possible...\n"); 10355 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10356 dahdi_wait_event(p->subs[idx].dfd); 10357 } 10358 ast_hangup(chan); 10359 goto quit; 10360 } else { 10361 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 10362 ast_hangup(chan); 10363 goto quit; 10364 } 10365 10366 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 10367 ast_verb(3, "Disabling Caller*ID on %s\n", chan->name); 10368 /* Disable Caller*ID if enabled */ 10369 p->hidecallerid = 1; 10370 ast_party_number_free(&chan->caller.id.number); 10371 ast_party_number_init(&chan->caller.id.number); 10372 ast_party_name_free(&chan->caller.id.name); 10373 ast_party_name_init(&chan->caller.id.name); 10374 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10375 if (res) { 10376 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 10377 chan->name, strerror(errno)); 10378 } 10379 len = 0; 10380 memset(exten, 0, sizeof(exten)); 10381 timeout = firstdigittimeout; 10382 } else if (p->callreturn && !strcmp(exten, "*69")) { 10383 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10384 break; 10385 } else if (!strcmp(exten, "*78")) { 10386 dahdi_dnd(p, 1); 10387 /* Do not disturb */ 10388 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10389 getforward = 0; 10390 memset(exten, 0, sizeof(exten)); 10391 len = 0; 10392 } else if (!strcmp(exten, "*79")) { 10393 dahdi_dnd(p, 0); 10394 /* Do not disturb */ 10395 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10396 getforward = 0; 10397 memset(exten, 0, sizeof(exten)); 10398 len = 0; 10399 } else if (p->cancallforward && !strcmp(exten, "*72")) { 10400 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10401 getforward = 1; 10402 memset(exten, 0, sizeof(exten)); 10403 len = 0; 10404 } else if (p->cancallforward && !strcmp(exten, "*73")) { 10405 ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel); 10406 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10407 memset(p->call_forward, 0, sizeof(p->call_forward)); 10408 getforward = 0; 10409 memset(exten, 0, sizeof(exten)); 10410 len = 0; 10411 } else if ((p->transfer || p->canpark) && ast_parking_ext_valid(exten, chan, chan->context) && 10412 p->subs[SUB_THREEWAY].owner && 10413 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 10414 /* This is a three way call, the main call being a real channel, 10415 and we're parking the first call. */ 10416 ast_masq_park_call_exten(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), 10417 chan, exten, chan->context, 0, NULL); 10418 ast_verb(3, "Parking call to '%s'\n", chan->name); 10419 break; 10420 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 10421 ast_verb(3, "Enabling Caller*ID on %s\n", chan->name); 10422 /* Enable Caller*ID if enabled */ 10423 p->hidecallerid = 0; 10424 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 10425 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10426 if (res) { 10427 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 10428 chan->name, strerror(errno)); 10429 } 10430 len = 0; 10431 memset(exten, 0, sizeof(exten)); 10432 timeout = firstdigittimeout; 10433 } else if (!strcmp(exten, "*0")) { 10434 struct ast_channel *nbridge = 10435 p->subs[SUB_THREEWAY].owner; 10436 struct dahdi_pvt *pbridge = NULL; 10437 /* set up the private struct of the bridged one, if any */ 10438 if (nbridge && ast_bridged_channel(nbridge)) 10439 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 10440 if (nbridge && pbridge && 10441 (nbridge->tech == &dahdi_tech) && 10442 (ast_bridged_channel(nbridge)->tech == &dahdi_tech) && 10443 ISTRUNK(pbridge)) { 10444 int func = DAHDI_FLASH; 10445 /* Clear out the dial buffer */ 10446 p->dop.dialstr[0] = '\0'; 10447 /* flash hookswitch */ 10448 if ((ioctl(pbridge->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 10449 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 10450 nbridge->name, strerror(errno)); 10451 } 10452 swap_subs(p, SUB_REAL, SUB_THREEWAY); 10453 unalloc_sub(p, SUB_THREEWAY); 10454 p->owner = p->subs[SUB_REAL].owner; 10455 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 10456 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 10457 ast_hangup(chan); 10458 goto quit; 10459 } else { 10460 tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10461 dahdi_wait_event(p->subs[idx].dfd); 10462 tone_zone_play_tone(p->subs[idx].dfd, -1); 10463 swap_subs(p, SUB_REAL, SUB_THREEWAY); 10464 unalloc_sub(p, SUB_THREEWAY); 10465 p->owner = p->subs[SUB_REAL].owner; 10466 ast_hangup(chan); 10467 goto quit; 10468 } 10469 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, 10470 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)) 10471 && !canmatch_featurecode(exten)) { 10472 ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, 10473 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<Unknown Caller>"), 10474 chan->context); 10475 break; 10476 } 10477 if (!timeout) 10478 timeout = gendigittimeout; 10479 if (len && !ast_ignore_pattern(chan->context, exten)) 10480 tone_zone_play_tone(p->subs[idx].dfd, -1); 10481 } 10482 break; 10483 case SIG_FXSLS: 10484 case SIG_FXSGS: 10485 case SIG_FXSKS: 10486 /* check for SMDI messages */ 10487 if (p->use_smdi && p->smdi_iface) { 10488 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT); 10489 10490 if (smdi_msg != NULL) { 10491 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 10492 10493 if (smdi_msg->type == 'B') 10494 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 10495 else if (smdi_msg->type == 'N') 10496 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 10497 10498 ast_debug(1, "Received SMDI message on %s\n", chan->name); 10499 } else { 10500 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 10501 } 10502 } 10503 10504 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 10505 number = smdi_msg->calling_st; 10506 10507 /* If we want caller id, we're in a prering state due to a polarity reversal 10508 * and we're set to use a polarity reversal to trigger the start of caller id, 10509 * grab the caller id and wait for ringing to start... */ 10510 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && 10511 (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_POLARITY_IN || p->cid_start == CID_START_DTMF_NOALERT))) { 10512 /* If set to use DTMF CID signalling, listen for DTMF */ 10513 if (p->cid_signalling == CID_SIG_DTMF) { 10514 int k = 0; 10515 cs = NULL; 10516 ast_debug(1, "Receiving DTMF cid on channel %s\n", chan->name); 10517 dahdi_setlinear(p->subs[idx].dfd, 0); 10518 /* 10519 * We are the only party interested in the Rx stream since 10520 * we have not answered yet. We don't need or even want DTMF 10521 * emulation. The DTMF digits can come so fast that emulation 10522 * can drop some of them. 10523 */ 10524 ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); 10525 res = 4000;/* This is a typical OFF time between rings. */ 10526 for (;;) { 10527 struct ast_frame *f; 10528 res = ast_waitfor(chan, res); 10529 if (res <= 0) { 10530 /* 10531 * We do not need to restore the dahdi_setlinear() 10532 * or AST_FLAG_END_DTMF_ONLY flag settings since we 10533 * are hanging up the channel. 10534 */ 10535 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 10536 "Exiting simple switch\n"); 10537 ast_hangup(chan); 10538 goto quit; 10539 } 10540 f = ast_read(chan); 10541 if (!f) 10542 break; 10543 if (f->frametype == AST_FRAME_DTMF) { 10544 if (k < ARRAY_LEN(dtmfbuf) - 1) { 10545 dtmfbuf[k++] = f->subclass.integer; 10546 } 10547 ast_debug(1, "CID got digit '%c'\n", f->subclass.integer); 10548 res = 4000;/* This is a typical OFF time between rings. */ 10549 } 10550 ast_frfree(f); 10551 if (chan->_state == AST_STATE_RING || 10552 chan->_state == AST_STATE_RINGING) 10553 break; /* Got ring */ 10554 } 10555 ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); 10556 dtmfbuf[k] = '\0'; 10557 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10558 /* Got cid and ring. */ 10559 ast_debug(1, "CID got string '%s'\n", dtmfbuf); 10560 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 10561 ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags); 10562 /* If first byte is NULL, we have no cid */ 10563 if (!ast_strlen_zero(dtmfcid)) 10564 number = dtmfcid; 10565 else 10566 number = NULL; 10567 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 10568 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 10569 cs = callerid_new(p->cid_signalling); 10570 if (cs) { 10571 samples = 0; 10572 #if 1 10573 bump_gains(p); 10574 #endif 10575 /* Take out of linear mode for Caller*ID processing */ 10576 dahdi_setlinear(p->subs[idx].dfd, 0); 10577 10578 /* First we wait and listen for the Caller*ID */ 10579 for (;;) { 10580 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10581 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10582 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10583 callerid_free(cs); 10584 ast_hangup(chan); 10585 goto quit; 10586 } 10587 if (i & DAHDI_IOMUX_SIGEVENT) { 10588 res = dahdi_get_event(p->subs[idx].dfd); 10589 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10590 if (res == DAHDI_EVENT_NOALARM) { 10591 p->inalarm = 0; 10592 } 10593 10594 if (p->cid_signalling == CID_SIG_V23_JP) { 10595 if (res == DAHDI_EVENT_RINGBEGIN) { 10596 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 10597 usleep(1); 10598 } 10599 } else { 10600 res = 0; 10601 break; 10602 } 10603 } else if (i & DAHDI_IOMUX_READ) { 10604 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10605 if (res < 0) { 10606 if (errno != ELAST) { 10607 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10608 callerid_free(cs); 10609 ast_hangup(chan); 10610 goto quit; 10611 } 10612 break; 10613 } 10614 samples += res; 10615 10616 if (p->cid_signalling == CID_SIG_V23_JP) { 10617 res = callerid_feed_jp(cs, buf, res, AST_LAW(p)); 10618 } else { 10619 res = callerid_feed(cs, buf, res, AST_LAW(p)); 10620 } 10621 if (res < 0) { 10622 /* 10623 * The previous diagnostic message output likely 10624 * explains why it failed. 10625 */ 10626 ast_log(LOG_WARNING, 10627 "Failed to decode CallerID on channel '%s'\n", 10628 chan->name); 10629 break; 10630 } else if (res) 10631 break; 10632 else if (samples > (8000 * 10)) 10633 break; 10634 } 10635 } 10636 if (res == 1) { 10637 callerid_get(cs, &name, &number, &flags); 10638 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 10639 } 10640 10641 if (p->cid_signalling == CID_SIG_V23_JP) { 10642 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 10643 usleep(1); 10644 } 10645 10646 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 10647 res = 4000;/* This is a typical OFF time between rings. */ 10648 for (;;) { 10649 struct ast_frame *f; 10650 res = ast_waitfor(chan, res); 10651 if (res <= 0) { 10652 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 10653 "Exiting simple switch\n"); 10654 ast_hangup(chan); 10655 goto quit; 10656 } 10657 if (!(f = ast_read(chan))) { 10658 ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n"); 10659 ast_hangup(chan); 10660 goto quit; 10661 } 10662 ast_frfree(f); 10663 if (chan->_state == AST_STATE_RING || 10664 chan->_state == AST_STATE_RINGING) 10665 break; /* Got ring */ 10666 } 10667 10668 /* We must have a ring by now, so, if configured, lets try to listen for 10669 * distinctive ringing */ 10670 if (p->usedistinctiveringdetection) { 10671 len = 0; 10672 distMatches = 0; 10673 /* Clear the current ring data array so we don't have old data in it. */ 10674 for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++) 10675 curRingData[receivedRingT] = 0; 10676 receivedRingT = 0; 10677 counter = 0; 10678 counter1 = 0; 10679 /* Check to see if context is what it should be, if not set to be. */ 10680 if (strcmp(p->context,p->defcontext) != 0) { 10681 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 10682 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 10683 } 10684 10685 for (;;) { 10686 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10687 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10688 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10689 callerid_free(cs); 10690 ast_hangup(chan); 10691 goto quit; 10692 } 10693 if (i & DAHDI_IOMUX_SIGEVENT) { 10694 res = dahdi_get_event(p->subs[idx].dfd); 10695 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10696 if (res == DAHDI_EVENT_NOALARM) { 10697 p->inalarm = 0; 10698 } 10699 res = 0; 10700 /* Let us detect distinctive ring */ 10701 10702 curRingData[receivedRingT] = p->ringt; 10703 10704 if (p->ringt < p->ringt_base/2) 10705 break; 10706 /* Increment the ringT counter so we can match it against 10707 values in chan_dahdi.conf for distinctive ring */ 10708 if (++receivedRingT == ARRAY_LEN(curRingData)) 10709 break; 10710 } else if (i & DAHDI_IOMUX_READ) { 10711 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10712 if (res < 0) { 10713 if (errno != ELAST) { 10714 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10715 callerid_free(cs); 10716 ast_hangup(chan); 10717 goto quit; 10718 } 10719 break; 10720 } 10721 if (p->ringt > 0) { 10722 if (!(--p->ringt)) { 10723 res = -1; 10724 break; 10725 } 10726 } 10727 } 10728 } 10729 /* this only shows up if you have n of the dring patterns filled in */ 10730 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 10731 for (counter = 0; counter < 3; counter++) { 10732 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this 10733 channel */ 10734 distMatches = 0; 10735 for (counter1 = 0; counter1 < 3; counter1++) { 10736 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 10737 if (p->drings.ringnum[counter].ring[counter1] == -1) { 10738 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 10739 curRingData[counter1]); 10740 distMatches++; 10741 } else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 10742 curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 10743 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 10744 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 10745 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 10746 distMatches++; 10747 } 10748 } 10749 10750 if (distMatches == 3) { 10751 /* The ring matches, set the context to whatever is for distinctive ring.. */ 10752 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 10753 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 10754 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 10755 break; 10756 } 10757 } 10758 } 10759 /* Restore linear mode (if appropriate) for Caller*ID processing */ 10760 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10761 #if 1 10762 restore_gains(p); 10763 #endif 10764 } else 10765 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 10766 } else { 10767 ast_log(LOG_WARNING, "Channel %s in prering " 10768 "state, but I have nothing to do. " 10769 "Terminating simple switch, should be " 10770 "restarted by the actual ring.\n", 10771 chan->name); 10772 ast_hangup(chan); 10773 goto quit; 10774 } 10775 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 10776 if (p->cid_signalling == CID_SIG_DTMF) { 10777 int k = 0; 10778 cs = NULL; 10779 dahdi_setlinear(p->subs[idx].dfd, 0); 10780 res = 2000; 10781 for (;;) { 10782 struct ast_frame *f; 10783 res = ast_waitfor(chan, res); 10784 if (res <= 0) { 10785 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 10786 "Exiting simple switch\n"); 10787 ast_hangup(chan); 10788 goto quit; 10789 } 10790 f = ast_read(chan); 10791 if (!f) { 10792 /* Hangup received waiting for DTMFCID. Exiting simple switch. */ 10793 ast_hangup(chan); 10794 goto quit; 10795 } 10796 if (f->frametype == AST_FRAME_DTMF) { 10797 dtmfbuf[k++] = f->subclass.integer; 10798 ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass.integer); 10799 res = 2000; 10800 } 10801 ast_frfree(f); 10802 10803 if (p->ringt_base == p->ringt) 10804 break; 10805 } 10806 dtmfbuf[k] = '\0'; 10807 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10808 /* Got cid and ring. */ 10809 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 10810 ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 10811 dtmfcid, flags); 10812 /* If first byte is NULL, we have no cid */ 10813 if (!ast_strlen_zero(dtmfcid)) 10814 number = dtmfcid; 10815 else 10816 number = NULL; 10817 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 10818 } else { 10819 /* FSK Bell202 callerID */ 10820 cs = callerid_new(p->cid_signalling); 10821 if (cs) { 10822 #if 1 10823 bump_gains(p); 10824 #endif 10825 samples = 0; 10826 len = 0; 10827 distMatches = 0; 10828 /* Clear the current ring data array so we don't have old data in it. */ 10829 for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++) 10830 curRingData[receivedRingT] = 0; 10831 receivedRingT = 0; 10832 counter = 0; 10833 counter1 = 0; 10834 /* Check to see if context is what it should be, if not set to be. */ 10835 if (strcmp(p->context,p->defcontext) != 0) { 10836 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 10837 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 10838 } 10839 10840 /* Take out of linear mode for Caller*ID processing */ 10841 dahdi_setlinear(p->subs[idx].dfd, 0); 10842 for (;;) { 10843 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10844 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10845 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10846 callerid_free(cs); 10847 ast_hangup(chan); 10848 goto quit; 10849 } 10850 if (i & DAHDI_IOMUX_SIGEVENT) { 10851 res = dahdi_get_event(p->subs[idx].dfd); 10852 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10853 if (res == DAHDI_EVENT_NOALARM) { 10854 p->inalarm = 0; 10855 } 10856 /* If we get a PR event, they hung up while processing calerid */ 10857 if ( res == DAHDI_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) { 10858 ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel); 10859 p->polarity = POLARITY_IDLE; 10860 callerid_free(cs); 10861 ast_hangup(chan); 10862 goto quit; 10863 } 10864 res = 0; 10865 /* Let us detect callerid when the telco uses distinctive ring */ 10866 10867 curRingData[receivedRingT] = p->ringt; 10868 10869 if (p->ringt < p->ringt_base/2) 10870 break; 10871 /* Increment the ringT counter so we can match it against 10872 values in chan_dahdi.conf for distinctive ring */ 10873 if (++receivedRingT == ARRAY_LEN(curRingData)) 10874 break; 10875 } else if (i & DAHDI_IOMUX_READ) { 10876 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10877 if (res < 0) { 10878 if (errno != ELAST) { 10879 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10880 callerid_free(cs); 10881 ast_hangup(chan); 10882 goto quit; 10883 } 10884 break; 10885 } 10886 if (p->ringt > 0) { 10887 if (!(--p->ringt)) { 10888 res = -1; 10889 break; 10890 } 10891 } 10892 samples += res; 10893 res = callerid_feed(cs, buf, res, AST_LAW(p)); 10894 if (res < 0) { 10895 /* 10896 * The previous diagnostic message output likely 10897 * explains why it failed. 10898 */ 10899 ast_log(LOG_WARNING, 10900 "Failed to decode CallerID on channel '%s'\n", 10901 chan->name); 10902 break; 10903 } else if (res) 10904 break; 10905 else if (samples > (8000 * 10)) 10906 break; 10907 } 10908 } 10909 if (res == 1) { 10910 callerid_get(cs, &name, &number, &flags); 10911 ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 10912 } 10913 if (distinctiveringaftercid == 1) { 10914 /* Clear the current ring data array so we don't have old data in it. */ 10915 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) { 10916 curRingData[receivedRingT] = 0; 10917 } 10918 receivedRingT = 0; 10919 ast_verb(3, "Detecting post-CID distinctive ring\n"); 10920 for (;;) { 10921 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10922 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10923 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10924 callerid_free(cs); 10925 ast_hangup(chan); 10926 goto quit; 10927 } 10928 if (i & DAHDI_IOMUX_SIGEVENT) { 10929 res = dahdi_get_event(p->subs[idx].dfd); 10930 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10931 if (res == DAHDI_EVENT_NOALARM) { 10932 p->inalarm = 0; 10933 } 10934 res = 0; 10935 /* Let us detect callerid when the telco uses distinctive ring */ 10936 10937 curRingData[receivedRingT] = p->ringt; 10938 10939 if (p->ringt < p->ringt_base/2) 10940 break; 10941 /* Increment the ringT counter so we can match it against 10942 values in chan_dahdi.conf for distinctive ring */ 10943 if (++receivedRingT == ARRAY_LEN(curRingData)) 10944 break; 10945 } else if (i & DAHDI_IOMUX_READ) { 10946 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10947 if (res < 0) { 10948 if (errno != ELAST) { 10949 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10950 callerid_free(cs); 10951 ast_hangup(chan); 10952 goto quit; 10953 } 10954 break; 10955 } 10956 if (p->ringt > 0) { 10957 if (!(--p->ringt)) { 10958 res = -1; 10959 break; 10960 } 10961 } 10962 } 10963 } 10964 } 10965 if (p->usedistinctiveringdetection) { 10966 /* this only shows up if you have n of the dring patterns filled in */ 10967 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 10968 10969 for (counter = 0; counter < 3; counter++) { 10970 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this 10971 channel */ 10972 /* this only shows up if you have n of the dring patterns filled in */ 10973 ast_verb(3, "Checking %d,%d,%d\n", 10974 p->drings.ringnum[counter].ring[0], 10975 p->drings.ringnum[counter].ring[1], 10976 p->drings.ringnum[counter].ring[2]); 10977 distMatches = 0; 10978 for (counter1 = 0; counter1 < 3; counter1++) { 10979 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 10980 if (p->drings.ringnum[counter].ring[counter1] == -1) { 10981 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 10982 curRingData[counter1]); 10983 distMatches++; 10984 } 10985 else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 10986 curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 10987 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 10988 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 10989 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 10990 distMatches++; 10991 } 10992 } 10993 if (distMatches == 3) { 10994 /* The ring matches, set the context to whatever is for distinctive ring.. */ 10995 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 10996 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 10997 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 10998 break; 10999 } 11000 } 11001 } 11002 /* Restore linear mode (if appropriate) for Caller*ID processing */ 11003 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 11004 #if 1 11005 restore_gains(p); 11006 #endif 11007 if (res < 0) { 11008 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 11009 } 11010 } else 11011 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 11012 } 11013 } else 11014 cs = NULL; 11015 11016 if (number) 11017 ast_shrink_phone_number(number); 11018 ast_set_callerid(chan, number, name, number); 11019 11020 if (smdi_msg) 11021 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 11022 11023 if (cs) 11024 callerid_free(cs); 11025 11026 my_handle_notify_message(chan, p, flags, -1); 11027 11028 ast_setstate(chan, AST_STATE_RING); 11029 chan->rings = 1; 11030 p->ringt = p->ringt_base; 11031 res = ast_pbx_run(chan); 11032 if (res) { 11033 ast_hangup(chan); 11034 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 11035 } 11036 goto quit; 11037 default: 11038 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 11039 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 11040 if (res < 0) 11041 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 11042 } 11043 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 11044 if (res < 0) 11045 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 11046 ast_hangup(chan); 11047 quit: 11048 ast_mutex_lock(&ss_thread_lock); 11049 ss_thread_count--; 11050 ast_cond_signal(&ss_thread_complete); 11051 ast_mutex_unlock(&ss_thread_lock); 11052 return NULL; 11053 }
static int analog_tone_to_dahditone | ( | enum analog_tone | tone | ) | [static] |
Definition at line 1620 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().
01621 { 01622 switch (tone) { 01623 case ANALOG_TONE_RINGTONE: 01624 return DAHDI_TONE_RINGTONE; 01625 case ANALOG_TONE_STUTTER: 01626 return DAHDI_TONE_STUTTER; 01627 case ANALOG_TONE_CONGESTION: 01628 return DAHDI_TONE_CONGESTION; 01629 case ANALOG_TONE_DIALTONE: 01630 return DAHDI_TONE_DIALTONE; 01631 case ANALOG_TONE_DIALRECALL: 01632 return DAHDI_TONE_DIALRECALL; 01633 case ANALOG_TONE_INFO: 01634 return DAHDI_TONE_INFO; 01635 default: 01636 return -1; 01637 } 01638 }
static int analogsub_to_dahdisub | ( | enum analog_sub | analogsub | ) | [static] |
Definition at line 1640 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().
01641 { 01642 int index; 01643 01644 switch (analogsub) { 01645 case ANALOG_SUB_REAL: 01646 index = SUB_REAL; 01647 break; 01648 case ANALOG_SUB_CALLWAIT: 01649 index = SUB_CALLWAIT; 01650 break; 01651 case ANALOG_SUB_THREEWAY: 01652 index = SUB_THREEWAY; 01653 break; 01654 default: 01655 ast_log(LOG_ERROR, "Unidentified sub!\n"); 01656 index = SUB_REAL; 01657 } 01658 01659 return index; 01660 }
AST_DATA_STRUCTURE | ( | dahdi_pvt | , | |
DATA_EXPORT_DAHDI_PVT | ||||
) |
static int attempt_transfer | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7652 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().
07653 { 07654 /* In order to transfer, we need at least one of the channels to 07655 actually be in a call bridge. We can't conference two applications 07656 together (but then, why would we want to?) */ 07657 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 07658 /* The three-way person we're about to transfer to could still be in MOH, so 07659 stop if now if appropriate */ 07660 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 07661 ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 07662 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 07663 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 07664 } 07665 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) { 07666 tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, DAHDI_TONE_RINGTONE); 07667 } 07668 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 07669 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 07670 ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name); 07671 return -1; 07672 } 07673 /* Orphan the channel after releasing the lock */ 07674 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 07675 unalloc_sub(p, SUB_THREEWAY); 07676 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 07677 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 07678 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 07679 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 07680 } 07681 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) { 07682 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 07683 } 07684 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 07685 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 07686 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name); 07687 return -1; 07688 } 07689 /* Three-way is now the REAL */ 07690 swap_subs(p, SUB_THREEWAY, SUB_REAL); 07691 ast_channel_unlock(p->subs[SUB_REAL].owner); 07692 unalloc_sub(p, SUB_THREEWAY); 07693 /* Tell the caller not to hangup */ 07694 return 1; 07695 } else { 07696 ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n", 07697 p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name); 07698 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 07699 return -1; 07700 } 07701 return 0; 07702 }
static int available | ( | struct dahdi_pvt ** | pvt, | |
int | is_specific_channel | |||
) | [static] |
Definition at line 13214 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().
13215 { 13216 struct dahdi_pvt *p = *pvt; 13217 13218 if (p->inalarm) 13219 return 0; 13220 13221 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) 13222 return analog_available(p->sig_pvt); 13223 13224 switch (p->sig) { 13225 #if defined(HAVE_PRI) 13226 case SIG_PRI_LIB_HANDLE_CASES: 13227 { 13228 struct sig_pri_chan *pvt_chan; 13229 int res; 13230 13231 pvt_chan = p->sig_pvt; 13232 res = sig_pri_available(&pvt_chan, is_specific_channel); 13233 *pvt = pvt_chan->chan_pvt; 13234 return res; 13235 } 13236 #endif /* defined(HAVE_PRI) */ 13237 #if defined(HAVE_SS7) 13238 case SIG_SS7: 13239 return sig_ss7_available(p->sig_pvt); 13240 #endif /* defined(HAVE_SS7) */ 13241 default: 13242 break; 13243 } 13244 13245 if (p->locallyblocked || p->remotelyblocked) { 13246 return 0; 13247 } 13248 13249 /* If no owner definitely available */ 13250 if (!p->owner) { 13251 #ifdef HAVE_OPENR2 13252 /* Trust MFC/R2 */ 13253 if (p->mfcr2) { 13254 if (p->mfcr2call) { 13255 return 0; 13256 } else { 13257 return 1; 13258 } 13259 } 13260 #endif 13261 return 1; 13262 } 13263 13264 return 0; 13265 }
static int build_channels | ( | struct dahdi_chan_conf * | conf, | |
const char * | value, | |||
int | reload, | |||
int | lineno, | |||
int * | found_pseudo | |||
) | [static] |
Definition at line 16830 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().
16831 { 16832 char *c, *chan; 16833 char *subdir; 16834 int x, start, finish; 16835 struct dahdi_pvt *tmp; 16836 16837 if ((reload == 0) && (conf->chan.sig < 0) && !conf->is_sig_auto) { 16838 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 16839 return -1; 16840 } 16841 16842 c = ast_strdupa(value); 16843 c = parse_spanchan(c, &subdir); 16844 16845 while ((chan = strsep(&c, ","))) { 16846 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) { 16847 /* Range */ 16848 } else if (sscanf(chan, "%30d", &start)) { 16849 /* Just one */ 16850 finish = start; 16851 } else if (!strcasecmp(chan, "pseudo")) { 16852 finish = start = CHAN_PSEUDO; 16853 if (found_pseudo) 16854 *found_pseudo = 1; 16855 } else { 16856 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan); 16857 return -1; 16858 } 16859 if (finish < start) { 16860 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 16861 x = finish; 16862 finish = start; 16863 start = x; 16864 } 16865 16866 for (x = start; x <= finish; x++) { 16867 char fn[PATH_MAX]; 16868 int real_channel = x; 16869 16870 if (!ast_strlen_zero(subdir)) { 16871 real_channel = device2chan(subdir, x, fn, sizeof(fn)); 16872 if (real_channel < 0) { 16873 if (conf->ignore_failed_channels) { 16874 ast_log(LOG_WARNING, "Failed configuring %s!%d, (got %d). But moving on to others.\n", 16875 subdir, x, real_channel); 16876 continue; 16877 } else { 16878 ast_log(LOG_ERROR, "Failed configuring %s!%d, (got %d).\n", 16879 subdir, x, real_channel); 16880 return -1; 16881 } 16882 } 16883 } 16884 tmp = mkintf(real_channel, conf, reload); 16885 16886 if (tmp) { 16887 ast_verb(3, "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", real_channel, sig2str(tmp->sig)); 16888 } else { 16889 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n", 16890 (reload == 1) ? "reconfigure" : "register", value); 16891 return -1; 16892 } 16893 } 16894 } 16895 16896 return 0; 16897 }
static int bump_gains | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5134 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().
05135 { 05136 int res; 05137 05138 /* Bump receive gain by value stored in cid_rxgain */ 05139 res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain + p->cid_rxgain, p->txgain, p->rxdrc, p->txdrc, p->law); 05140 if (res) { 05141 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno)); 05142 return -1; 05143 } 05144 05145 return 0; 05146 }
static int calc_energy | ( | const unsigned char * | buf, | |
int | len, | |||
format_t | law | |||
) | [static] |
Definition at line 11061 of file chan_dahdi.c.
References AST_ALAW, AST_FORMAT_ULAW, and AST_MULAW.
Referenced by mwi_thread().
11062 { 11063 int x; 11064 int sum = 0; 11065 11066 if (!len) 11067 return 0; 11068 11069 for (x = 0; x < len; x++) 11070 sum += abs(law == AST_FORMAT_ULAW ? AST_MULAW(buf[x]) : AST_ALAW(buf[x])); 11071 11072 return sum / len; 11073 }
static int canmatch_featurecode | ( | const char * | exten | ) | [static] |
Definition at line 9900 of file chan_dahdi.c.
References ast_pickup_ext(), and pickup_ext.
Referenced by analog_ss_thread().
09901 { 09902 int extlen = strlen(exten); 09903 const char *pickup_ext; 09904 if (!extlen) { 09905 return 1; 09906 } 09907 pickup_ext = ast_pickup_ext(); 09908 if (extlen < strlen(pickup_ext) && !strncmp(pickup_ext, exten, extlen)) { 09909 return 1; 09910 } 09911 /* hardcoded features are *60, *67, *69, *70, *72, *73, *78, *79, *82, *0 */ 09912 if (exten[0] == '*' && extlen < 3) { 09913 if (extlen == 1) { 09914 return 1; 09915 } 09916 /* "*0" should be processed before it gets here */ 09917 switch (exten[1]) { 09918 case '6': 09919 case '7': 09920 case '8': 09921 return 1; 09922 } 09923 } 09924 return 0; 09925 }
static int check_for_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7704 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().
07705 { 07706 struct dahdi_confinfo ci; 07707 /* Fine if we already have a master, etc */ 07708 if (p->master || (p->confno > -1)) 07709 return 0; 07710 memset(&ci, 0, sizeof(ci)); 07711 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) { 07712 ast_log(LOG_WARNING, "Failed to get conference info on channel %d: %s\n", p->channel, strerror(errno)); 07713 return 0; 07714 } 07715 /* If we have no master and don't have a confno, then 07716 if we're in a conference, it's probably a MeetMe room or 07717 some such, so don't let us 3-way out! */ 07718 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 07719 ast_verb(3, "Avoiding 3-way call when in an external conference\n"); 07720 return 1; 07721 } 07722 return 0; 07723 }
static char* complete_span_4 | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 14266 of file chan_dahdi.c.
References complete_span_helper().
Referenced by handle_pri_debug(), and handle_pri_show_span().
14267 { 14268 return complete_span_helper(line,word,pos,state,3); 14269 }
static char* complete_span_helper | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
int | rpos | |||
) | [static] |
Definition at line 14245 of file chan_dahdi.c.
References asprintf, ast_log(), errno, dahdi_pri::pri, and pris.
Referenced by complete_span_4().
14246 { 14247 int which, span; 14248 char *ret = NULL; 14249 14250 if (pos != rpos) 14251 return ret; 14252 14253 for (which = span = 0; span < NUM_SPANS; span++) { 14254 if (pris[span].pri.pri && ++which > state) { 14255 if (asprintf(&ret, "%d", span + 1) < 0) { /* user indexes start from 1 */ 14256 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 14257 } 14258 break; 14259 } 14260 } 14261 return ret; 14262 }
static int conf_add | ( | struct dahdi_pvt * | p, | |
struct dahdi_subchannel * | c, | |||
int | index, | |||
int | slavechannel | |||
) | [static] |
Definition at line 4716 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().
04717 { 04718 /* If the conference already exists, and we're already in it 04719 don't bother doing anything */ 04720 struct dahdi_confinfo zi; 04721 04722 memset(&zi, 0, sizeof(zi)); 04723 zi.chan = 0; 04724 04725 if (slavechannel > 0) { 04726 /* If we have only one slave, do a digital mon */ 04727 zi.confmode = DAHDI_CONF_DIGITALMON; 04728 zi.confno = slavechannel; 04729 } else { 04730 if (!idx) { 04731 /* Real-side and pseudo-side both participate in conference */ 04732 zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER | 04733 DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER; 04734 } else 04735 zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER; 04736 zi.confno = p->confno; 04737 } 04738 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode)) 04739 return 0; 04740 if (c->dfd < 0) 04741 return 0; 04742 if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) { 04743 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno)); 04744 return -1; 04745 } 04746 if (slavechannel < 1) { 04747 p->confno = zi.confno; 04748 } 04749 c->curconf = zi; 04750 ast_debug(1, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno); 04751 return 0; 04752 }
static int conf_del | ( | struct dahdi_pvt * | p, | |
struct dahdi_subchannel * | c, | |||
int | index | |||
) | [static] |
Definition at line 4765 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().
04766 { 04767 struct dahdi_confinfo zi; 04768 if (/* Can't delete if there's no dfd */ 04769 (c->dfd < 0) || 04770 /* Don't delete from the conference if it's not our conference */ 04771 !isourconf(p, c) 04772 /* Don't delete if we don't think it's conferenced at all (implied) */ 04773 ) return 0; 04774 memset(&zi, 0, sizeof(zi)); 04775 if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) { 04776 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno)); 04777 return -1; 04778 } 04779 ast_debug(1, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno); 04780 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 04781 return 0; 04782 }
static struct ast_str* create_channel_name | ( | struct dahdi_pvt * | i, | |
int | is_outgoing, | |||
char * | address | |||
) | [static] |
Definition at line 9559 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().
09563 { 09564 struct ast_str *chan_name; 09565 int x, y; 09566 09567 /* Create the new channel name tail. */ 09568 if (!(chan_name = ast_str_create(32))) { 09569 return NULL; 09570 } 09571 if (i->channel == CHAN_PSEUDO) { 09572 ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random()); 09573 #if defined(HAVE_PRI) 09574 } else if (i->pri) { 09575 ast_mutex_lock(&i->pri->lock); 09576 y = ++i->pri->new_chan_seq; 09577 if (is_outgoing) { 09578 ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, address, y); 09579 address[0] = '\0'; 09580 } else if (ast_strlen_zero(i->cid_subaddr)) { 09581 /* Put in caller-id number only since there is no subaddress. */ 09582 ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, i->cid_num, y); 09583 } else { 09584 /* Put in caller-id number and subaddress. */ 09585 ast_str_set(&chan_name, 0, "i%d/%s:%s-%x", i->pri->span, i->cid_num, 09586 i->cid_subaddr, y); 09587 } 09588 ast_mutex_unlock(&i->pri->lock); 09589 #endif /* defined(HAVE_PRI) */ 09590 } else { 09591 y = 1; 09592 do { 09593 ast_str_set(&chan_name, 0, "%d-%d", i->channel, y); 09594 for (x = 0; x < 3; ++x) { 09595 if (i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name), 09596 i->subs[x].owner->name + 6)) { 09597 break; 09598 } 09599 } 09600 ++y; 09601 } while (x < 3); 09602 } 09603 return chan_name; 09604 }
static int dahdi_accept_r2_call_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 5998 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().
05999 { 06000 /* data is whether to accept with charge or no charge */ 06001 openr2_call_mode_t accept_mode; 06002 int res, timeout, maxloops; 06003 struct ast_frame *f; 06004 struct dahdi_pvt *p; 06005 char *parse; 06006 AST_DECLARE_APP_ARGS(args, 06007 AST_APP_ARG(charge); 06008 ); 06009 06010 if (ast_strlen_zero(data)) { 06011 ast_log(LOG_DEBUG, "No data sent to application!\n"); 06012 return -1; 06013 } 06014 06015 if (chan->tech != &dahdi_tech) { 06016 ast_log(LOG_DEBUG, "Only DAHDI technology accepted!\n"); 06017 return -1; 06018 } 06019 06020 p = (struct dahdi_pvt *)chan->tech_pvt; 06021 if (!p) { 06022 ast_log(LOG_DEBUG, "Unable to find technology private!\n"); 06023 return -1; 06024 } 06025 06026 parse = ast_strdupa(data); 06027 AST_STANDARD_APP_ARGS(args, parse); 06028 06029 if (ast_strlen_zero(args.charge)) { 06030 ast_log(LOG_WARNING, "DAHDIAcceptR2Call requires 'yes' or 'no' for the charge parameter\n"); 06031 return -1; 06032 } 06033 06034 ast_mutex_lock(&p->lock); 06035 if (!p->mfcr2 || !p->mfcr2call) { 06036 ast_mutex_unlock(&p->lock); 06037 ast_log(LOG_DEBUG, "Channel %s does not seems to be an R2 active channel!\n", chan->name); 06038 return -1; 06039 } 06040 06041 if (p->mfcr2_call_accepted) { 06042 ast_mutex_unlock(&p->lock); 06043 ast_log(LOG_DEBUG, "MFC/R2 call already accepted on channel %s!\n", chan->name); 06044 return 0; 06045 } 06046 accept_mode = ast_true(args.charge) ? OR2_CALL_WITH_CHARGE : OR2_CALL_NO_CHARGE; 06047 if (openr2_chan_accept_call(p->r2chan, accept_mode)) { 06048 ast_mutex_unlock(&p->lock); 06049 ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n"); 06050 return -1; 06051 } 06052 ast_mutex_unlock(&p->lock); 06053 06054 res = 0; 06055 timeout = 100; 06056 maxloops = 50; /* wait up to 5 seconds */ 06057 /* we need to read() until the call is accepted */ 06058 while (maxloops > 0) { 06059 maxloops--; 06060 if (ast_check_hangup(chan)) { 06061 break; 06062 } 06063 res = ast_waitfor(chan, timeout); 06064 if (res < 0) { 06065 ast_log(LOG_DEBUG, "ast_waitfor failed on channel %s, going out ...\n", chan->name); 06066 res = -1; 06067 break; 06068 } 06069 if (res == 0) { 06070 continue; 06071 } 06072 f = ast_read(chan); 06073 if (!f) { 06074 ast_log(LOG_DEBUG, "No frame read on channel %s, going out ...\n", chan->name); 06075 res = -1; 06076 break; 06077 } 06078 if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_HANGUP) { 06079 ast_log(LOG_DEBUG, "Got HANGUP frame on channel %s, going out ...\n", chan->name); 06080 ast_frfree(f); 06081 res = -1; 06082 break; 06083 } 06084 ast_frfree(f); 06085 ast_mutex_lock(&p->lock); 06086 if (p->mfcr2_call_accepted) { 06087 ast_mutex_unlock(&p->lock); 06088 ast_log(LOG_DEBUG, "Accepted MFC/R2 call!\n"); 06089 break; 06090 } 06091 ast_mutex_unlock(&p->lock); 06092 } 06093 if (res == -1) { 06094 ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n"); 06095 } 06096 return res; 06097 }
static void dahdi_ami_channel_event | ( | struct dahdi_pvt * | p, | |
struct ast_channel * | chan | |||
) | [static] |
Definition at line 2139 of file chan_dahdi.c.
References ast_manager_event, CHAN_PSEUDO, dahdi_pvt::channel, EVENT_FLAG_CALL, ast_channel::name, dahdi_pvt::span, and ast_channel::uniqueid.
Referenced by dahdi_new(), and my_ami_channel_event().
02140 { 02141 char ch_name[20]; 02142 02143 if (p->channel < CHAN_PSEUDO) { 02144 /* No B channel */ 02145 snprintf(ch_name, sizeof(ch_name), "no-media (%d)", p->channel); 02146 } else if (p->channel == CHAN_PSEUDO) { 02147 /* Pseudo channel */ 02148 strcpy(ch_name, "pseudo"); 02149 } else { 02150 /* Real channel */ 02151 snprintf(ch_name, sizeof(ch_name), "%d", p->channel); 02152 } 02153 ast_manager_event(chan, EVENT_FLAG_CALL, "DAHDIChannel", 02154 "Channel: %s\r\n" 02155 "Uniqueid: %s\r\n" 02156 "DAHDISpan: %d\r\n" 02157 "DAHDIChannel: %s\r\n", 02158 chan->name, 02159 chan->uniqueid, 02160 p->span, 02161 ch_name); 02162 }
static int dahdi_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 6582 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.
06583 { 06584 struct dahdi_pvt *p = ast->tech_pvt; 06585 int res = 0; 06586 int idx; 06587 ast_setstate(ast, AST_STATE_UP);/*! \todo XXX this is redundantly set by the analog and PRI submodules! */ 06588 ast_mutex_lock(&p->lock); 06589 idx = dahdi_get_index(ast, p, 0); 06590 if (idx < 0) 06591 idx = SUB_REAL; 06592 /* nothing to do if a radio channel */ 06593 if ((p->radio || (p->oprmode < 0))) { 06594 ast_mutex_unlock(&p->lock); 06595 return 0; 06596 } 06597 06598 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 06599 res = analog_answer(p->sig_pvt, ast); 06600 ast_mutex_unlock(&p->lock); 06601 return res; 06602 } 06603 06604 switch (p->sig) { 06605 #if defined(HAVE_PRI) 06606 case SIG_PRI_LIB_HANDLE_CASES: 06607 res = sig_pri_answer(p->sig_pvt, ast); 06608 break; 06609 #endif /* defined(HAVE_PRI) */ 06610 #if defined(HAVE_SS7) 06611 case SIG_SS7: 06612 res = sig_ss7_answer(p->sig_pvt, ast); 06613 break; 06614 #endif /* defined(HAVE_SS7) */ 06615 #ifdef HAVE_OPENR2 06616 case SIG_MFCR2: 06617 if (!p->mfcr2_call_accepted) { 06618 /* The call was not accepted on offer nor the user, so it must be accepted now before answering, 06619 openr2_chan_answer_call will be called when the callback on_call_accepted is executed */ 06620 p->mfcr2_answer_pending = 1; 06621 if (p->mfcr2_charge_calls) { 06622 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with charge before answering on chan %d\n", p->channel); 06623 openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE); 06624 } else { 06625 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with no charge before answering on chan %d\n", p->channel); 06626 openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE); 06627 } 06628 } else { 06629 ast_log(LOG_DEBUG, "Answering MFC/R2 call on chan %d\n", p->channel); 06630 dahdi_r2_answer(p); 06631 } 06632 break; 06633 #endif 06634 case 0: 06635 ast_mutex_unlock(&p->lock); 06636 return 0; 06637 default: 06638 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 06639 res = -1; 06640 break; 06641 } 06642 ast_mutex_unlock(&p->lock); 06643 return res; 06644 }
static openr2_call_disconnect_cause_t dahdi_ast_cause_to_r2_cause | ( | int | cause | ) | [static] |
Definition at line 6099 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().
06100 { 06101 openr2_call_disconnect_cause_t r2cause = OR2_CAUSE_NORMAL_CLEARING; 06102 switch (cause) { 06103 case AST_CAUSE_USER_BUSY: 06104 case AST_CAUSE_CALL_REJECTED: 06105 case AST_CAUSE_INTERWORKING: /* I don't know wtf is this but is used sometimes when ekiga rejects a call */ 06106 r2cause = OR2_CAUSE_BUSY_NUMBER; 06107 break; 06108 06109 case AST_CAUSE_NORMAL_CIRCUIT_CONGESTION: 06110 case AST_CAUSE_SWITCH_CONGESTION: 06111 r2cause = OR2_CAUSE_NETWORK_CONGESTION; 06112 break; 06113 06114 case AST_CAUSE_UNALLOCATED: 06115 r2cause = OR2_CAUSE_UNALLOCATED_NUMBER; 06116 break; 06117 06118 case AST_CAUSE_NETWORK_OUT_OF_ORDER: 06119 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 06120 r2cause = OR2_CAUSE_OUT_OF_ORDER; 06121 break; 06122 06123 case AST_CAUSE_NO_ANSWER: 06124 case AST_CAUSE_NO_USER_RESPONSE: 06125 r2cause = OR2_CAUSE_NO_ANSWER; 06126 break; 06127 06128 default: 06129 r2cause = OR2_CAUSE_NORMAL_CLEARING; 06130 break; 06131 } 06132 ast_log(LOG_DEBUG, "ast cause %d resulted in openr2 cause %d/%s\n", 06133 cause, r2cause, openr2_proto_get_disconnect_string(r2cause)); 06134 return r2cause; 06135 }
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 7229 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().
07230 { 07231 struct ast_channel *who; 07232 struct dahdi_pvt *p0, *p1, *op0, *op1; 07233 struct dahdi_pvt *master = NULL, *slave = NULL; 07234 struct ast_frame *f; 07235 int inconf = 0; 07236 int nothingok = 1; 07237 int ofd0, ofd1; 07238 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 07239 int os0 = -1, os1 = -1; 07240 int priority = 0; 07241 struct ast_channel *oc0, *oc1; 07242 enum ast_bridge_result res; 07243 #ifdef PRI_2BCT 07244 int triedtopribridge = 0; 07245 q931_call *q931c0; 07246 q931_call *q931c1; 07247 #endif 07248 07249 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 07250 There is code below to handle it properly until DTMF is actually seen, 07251 but due to currently unresolved issues it's ignored... 07252 */ 07253 07254 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 07255 return AST_BRIDGE_FAILED_NOWARN; 07256 07257 ast_channel_lock(c0); 07258 while (ast_channel_trylock(c1)) { 07259 CHANNEL_DEADLOCK_AVOIDANCE(c0); 07260 } 07261 07262 p0 = c0->tech_pvt; 07263 p1 = c1->tech_pvt; 07264 /* cant do pseudo-channels here */ 07265 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 07266 ast_channel_unlock(c0); 07267 ast_channel_unlock(c1); 07268 return AST_BRIDGE_FAILED_NOWARN; 07269 } 07270 07271 oi0 = dahdi_get_index(c0, p0, 0); 07272 oi1 = dahdi_get_index(c1, p1, 0); 07273 if ((oi0 < 0) || (oi1 < 0)) { 07274 ast_channel_unlock(c0); 07275 ast_channel_unlock(c1); 07276 return AST_BRIDGE_FAILED; 07277 } 07278 07279 op0 = p0 = c0->tech_pvt; 07280 op1 = p1 = c1->tech_pvt; 07281 ofd0 = c0->fds[0]; 07282 ofd1 = c1->fds[0]; 07283 oc0 = p0->owner; 07284 oc1 = p1->owner; 07285 07286 if (ast_mutex_trylock(&p0->lock)) { 07287 /* Don't block, due to potential for deadlock */ 07288 ast_channel_unlock(c0); 07289 ast_channel_unlock(c1); 07290 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 07291 return AST_BRIDGE_RETRY; 07292 } 07293 if (ast_mutex_trylock(&p1->lock)) { 07294 /* Don't block, due to potential for deadlock */ 07295 ast_mutex_unlock(&p0->lock); 07296 ast_channel_unlock(c0); 07297 ast_channel_unlock(c1); 07298 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 07299 return AST_BRIDGE_RETRY; 07300 } 07301 07302 if ((p0->callwaiting && p0->callwaitingcallerid) 07303 || (p1->callwaiting && p1->callwaitingcallerid)) { 07304 /* 07305 * Call Waiting Caller ID requires DTMF detection to know if it 07306 * can send the CID spill. 07307 * 07308 * For now, don't attempt to native bridge if either channel 07309 * needs DTMF detection. There is code below to handle it 07310 * properly until DTMF is actually seen, but due to currently 07311 * unresolved issues it's ignored... 07312 */ 07313 ast_mutex_unlock(&p0->lock); 07314 ast_mutex_unlock(&p1->lock); 07315 ast_channel_unlock(c0); 07316 ast_channel_unlock(c1); 07317 return AST_BRIDGE_FAILED_NOWARN; 07318 } 07319 07320 #if defined(HAVE_PRI) 07321 if ((dahdi_sig_pri_lib_handles(p0->sig) 07322 && ((struct sig_pri_chan *) p0->sig_pvt)->no_b_channel) 07323 || (dahdi_sig_pri_lib_handles(p1->sig) 07324 && ((struct sig_pri_chan *) p1->sig_pvt)->no_b_channel)) { 07325 /* 07326 * PRI nobch channels (hold and call waiting) are equivalent to 07327 * pseudo channels and cannot be done here. 07328 */ 07329 ast_mutex_unlock(&p0->lock); 07330 ast_mutex_unlock(&p1->lock); 07331 ast_channel_unlock(c0); 07332 ast_channel_unlock(c1); 07333 return AST_BRIDGE_FAILED_NOWARN; 07334 } 07335 #endif /* defined(HAVE_PRI) */ 07336 07337 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 07338 if (p0->owner && p1->owner) { 07339 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 07340 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 07341 master = p0; 07342 slave = p1; 07343 inconf = 1; 07344 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 07345 master = p1; 07346 slave = p0; 07347 inconf = 1; 07348 } else { 07349 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 07350 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 07351 p0->channel, 07352 oi0, (p0->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0, 07353 p0->subs[SUB_REAL].inthreeway, p0->channel, 07354 oi0, (p1->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0, 07355 p1->subs[SUB_REAL].inthreeway); 07356 } 07357 nothingok = 0; 07358 } 07359 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 07360 if (p1->subs[SUB_THREEWAY].inthreeway) { 07361 master = p1; 07362 slave = p0; 07363 nothingok = 0; 07364 } 07365 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 07366 if (p0->subs[SUB_THREEWAY].inthreeway) { 07367 master = p0; 07368 slave = p1; 07369 nothingok = 0; 07370 } 07371 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 07372 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 07373 don't put us in anything */ 07374 if (p1->subs[SUB_CALLWAIT].inthreeway) { 07375 master = p1; 07376 slave = p0; 07377 nothingok = 0; 07378 } 07379 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 07380 /* Same as previous */ 07381 if (p0->subs[SUB_CALLWAIT].inthreeway) { 07382 master = p0; 07383 slave = p1; 07384 nothingok = 0; 07385 } 07386 } 07387 ast_debug(1, "master: %d, slave: %d, nothingok: %d\n", 07388 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 07389 if (master && slave) { 07390 /* Stop any tones, or play ringtone as appropriate. If they're bridged 07391 in an active threeway call with a channel that is ringing, we should 07392 indicate ringing. */ 07393 if ((oi1 == SUB_THREEWAY) && 07394 p1->subs[SUB_THREEWAY].inthreeway && 07395 p1->subs[SUB_REAL].owner && 07396 p1->subs[SUB_REAL].inthreeway && 07397 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 07398 ast_debug(1, 07399 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n", 07400 p0->channel, oi0, c0->name, p1->channel, oi1, c1->name); 07401 tone_zone_play_tone(p0->subs[oi0].dfd, DAHDI_TONE_RINGTONE); 07402 os1 = p1->subs[SUB_REAL].owner->_state; 07403 } else { 07404 ast_debug(1, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n", 07405 p0->channel, oi0, c0->name, p1->channel, oi1, c1->name); 07406 tone_zone_play_tone(p0->subs[oi0].dfd, -1); 07407 } 07408 if ((oi0 == SUB_THREEWAY) && 07409 p0->subs[SUB_THREEWAY].inthreeway && 07410 p0->subs[SUB_REAL].owner && 07411 p0->subs[SUB_REAL].inthreeway && 07412 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 07413 ast_debug(1, 07414 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n", 07415 p1->channel, oi1, c1->name, p0->channel, oi0, c0->name); 07416 tone_zone_play_tone(p1->subs[oi1].dfd, DAHDI_TONE_RINGTONE); 07417 os0 = p0->subs[SUB_REAL].owner->_state; 07418 } else { 07419 ast_debug(1, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n", 07420 p1->channel, oi1, c1->name, p0->channel, oi0, c0->name); 07421 tone_zone_play_tone(p1->subs[oi1].dfd, -1); 07422 } 07423 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 07424 if (!p0->echocanbridged || !p1->echocanbridged) { 07425 /* Disable echo cancellation if appropriate */ 07426 dahdi_disable_ec(p0); 07427 dahdi_disable_ec(p1); 07428 } 07429 } 07430 dahdi_link(slave, master); 07431 master->inconference = inconf; 07432 } else if (!nothingok) 07433 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 07434 07435 update_conf(p0); 07436 update_conf(p1); 07437 t0 = p0->subs[SUB_REAL].inthreeway; 07438 t1 = p1->subs[SUB_REAL].inthreeway; 07439 07440 ast_mutex_unlock(&p0->lock); 07441 ast_mutex_unlock(&p1->lock); 07442 07443 ast_channel_unlock(c0); 07444 ast_channel_unlock(c1); 07445 07446 /* Native bridge failed */ 07447 if ((!master || !slave) && !nothingok) { 07448 dahdi_enable_ec(p0); 07449 dahdi_enable_ec(p1); 07450 return AST_BRIDGE_FAILED; 07451 } 07452 07453 ast_verb(3, "Native bridging %s and %s\n", c0->name, c1->name); 07454 07455 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 07456 disable_dtmf_detect(op0); 07457 07458 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 07459 disable_dtmf_detect(op1); 07460 07461 for (;;) { 07462 struct ast_channel *c0_priority[2] = {c0, c1}; 07463 struct ast_channel *c1_priority[2] = {c1, c0}; 07464 07465 /* Here's our main loop... Start by locking things, looking for private parts, 07466 and then balking if anything is wrong */ 07467 07468 ast_channel_lock(c0); 07469 while (ast_channel_trylock(c1)) { 07470 CHANNEL_DEADLOCK_AVOIDANCE(c0); 07471 } 07472 07473 p0 = c0->tech_pvt; 07474 p1 = c1->tech_pvt; 07475 07476 if (op0 == p0) 07477 i0 = dahdi_get_index(c0, p0, 1); 07478 if (op1 == p1) 07479 i1 = dahdi_get_index(c1, p1, 1); 07480 07481 ast_channel_unlock(c0); 07482 ast_channel_unlock(c1); 07483 07484 if (!timeoutms || 07485 (op0 != p0) || 07486 (op1 != p1) || 07487 (ofd0 != c0->fds[0]) || 07488 (ofd1 != c1->fds[0]) || 07489 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 07490 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 07491 (oc0 != p0->owner) || 07492 (oc1 != p1->owner) || 07493 (t0 != p0->subs[SUB_REAL].inthreeway) || 07494 (t1 != p1->subs[SUB_REAL].inthreeway) || 07495 (oi0 != i0) || 07496 (oi1 != i1)) { 07497 ast_debug(1, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 07498 op0->channel, oi0, op1->channel, oi1); 07499 res = AST_BRIDGE_RETRY; 07500 goto return_from_bridge; 07501 } 07502 07503 #ifdef PRI_2BCT 07504 if (!triedtopribridge) { 07505 triedtopribridge = 1; 07506 if (p0->pri && p0->pri == p1->pri && p0->pri->transfer) { 07507 ast_mutex_lock(&p0->pri->lock); 07508 switch (p0->sig) { 07509 case SIG_PRI_LIB_HANDLE_CASES: 07510 q931c0 = ((struct sig_pri_chan *) (p0->sig_pvt))->call; 07511 break; 07512 default: 07513 q931c0 = NULL; 07514 break; 07515 } 07516 switch (p1->sig) { 07517 case SIG_PRI_LIB_HANDLE_CASES: 07518 q931c1 = ((struct sig_pri_chan *) (p1->sig_pvt))->call; 07519 break; 07520 default: 07521 q931c1 = NULL; 07522 break; 07523 } 07524 if (q931c0 && q931c1) { 07525 pri_channel_bridge(q931c0, q931c1); 07526 } 07527 ast_mutex_unlock(&p0->pri->lock); 07528 } 07529 } 07530 #endif 07531 07532 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms); 07533 if (!who) { 07534 ast_debug(1, "Ooh, empty read...\n"); 07535 continue; 07536 } 07537 f = ast_read(who); 07538 if (!f || (f->frametype == AST_FRAME_CONTROL)) { 07539 *fo = f; 07540 *rc = who; 07541 res = AST_BRIDGE_COMPLETE; 07542 goto return_from_bridge; 07543 } 07544 if (f->frametype == AST_FRAME_DTMF) { 07545 if ((who == c0) && p0->pulsedial) { 07546 ast_write(c1, f); 07547 } else if ((who == c1) && p1->pulsedial) { 07548 ast_write(c0, f); 07549 } else { 07550 *fo = f; 07551 *rc = who; 07552 res = AST_BRIDGE_COMPLETE; 07553 goto return_from_bridge; 07554 } 07555 } 07556 ast_frfree(f); 07557 07558 /* Swap who gets priority */ 07559 priority = !priority; 07560 } 07561 07562 return_from_bridge: 07563 if (op0 == p0) 07564 dahdi_enable_ec(p0); 07565 07566 if (op1 == p1) 07567 dahdi_enable_ec(p1); 07568 07569 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 07570 enable_dtmf_detect(op0); 07571 07572 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 07573 enable_dtmf_detect(op1); 07574 07575 dahdi_unlink(slave, master, 1); 07576 07577 return res; 07578 }
static int dahdi_call | ( | struct ast_channel * | ast, | |
char * | rdest, | |||
int | timeout | |||
) | [static] |
Definition at line 5368 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, dahdi_pvt::callwaitrings, dahdi_pvt::channel, ast_channel::connected, 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_connected_line::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.
05369 { 05370 struct dahdi_pvt *p = ast->tech_pvt; 05371 int x, res, mysig; 05372 char dest[256]; /* must be same length as p->dialdest */ 05373 05374 ast_mutex_lock(&p->lock); 05375 ast_copy_string(dest, rdest, sizeof(dest)); 05376 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 05377 if ((ast->_state == AST_STATE_BUSY)) { 05378 p->subs[SUB_REAL].needbusy = 1; 05379 ast_mutex_unlock(&p->lock); 05380 return 0; 05381 } 05382 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 05383 ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast->name); 05384 ast_mutex_unlock(&p->lock); 05385 return -1; 05386 } 05387 p->waitingfordt.tv_sec = 0; 05388 p->dialednone = 0; 05389 if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */ 05390 { 05391 /* Special pseudo -- automatically up */ 05392 ast_setstate(ast, AST_STATE_UP); 05393 ast_mutex_unlock(&p->lock); 05394 return 0; 05395 } 05396 x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE; 05397 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x); 05398 if (res) 05399 ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno)); 05400 p->outgoing = 1; 05401 05402 if (IS_DIGITAL(ast->transfercapability)){ 05403 set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, p->rxdrc, p->txdrc, p->law); 05404 } else { 05405 set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law); 05406 } 05407 05408 #ifdef HAVE_PRI 05409 if (dahdi_sig_pri_lib_handles(p->sig)) { 05410 res = sig_pri_call(p->sig_pvt, ast, rdest, timeout, 05411 (p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW); 05412 ast_mutex_unlock(&p->lock); 05413 return res; 05414 } 05415 #endif 05416 05417 #if defined(HAVE_SS7) 05418 if (p->sig == SIG_SS7) { 05419 res = sig_ss7_call(p->sig_pvt, ast, rdest); 05420 ast_mutex_unlock(&p->lock); 05421 return res; 05422 } 05423 #endif /* defined(HAVE_SS7) */ 05424 05425 /* If this is analog signalling we can exit here */ 05426 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 05427 p->callwaitrings = 0; 05428 res = analog_call(p->sig_pvt, ast, rdest, timeout); 05429 ast_mutex_unlock(&p->lock); 05430 return res; 05431 } 05432 05433 mysig = p->outsigmod > -1 ? p->outsigmod : p->sig; 05434 switch (mysig) { 05435 case 0: 05436 /* Special pseudo -- automatically up*/ 05437 ast_setstate(ast, AST_STATE_UP); 05438 break; 05439 case SIG_MFCR2: 05440 break; 05441 default: 05442 ast_debug(1, "not yet implemented\n"); 05443 ast_mutex_unlock(&p->lock); 05444 return -1; 05445 } 05446 05447 #ifdef HAVE_OPENR2 05448 if (p->mfcr2) { 05449 openr2_calling_party_category_t chancat; 05450 int callres = 0; 05451 char *c, *l; 05452 05453 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ 05454 p->dialdest[0] = '\0'; 05455 05456 c = strchr(dest, '/'); 05457 if (c) { 05458 c++; 05459 } else { 05460 c = ""; 05461 } 05462 if (!p->hidecallerid) { 05463 l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL; 05464 } else { 05465 l = NULL; 05466 } 05467 if (strlen(c) < p->stripmsd) { 05468 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 05469 ast_mutex_unlock(&p->lock); 05470 return -1; 05471 } 05472 p->dialing = 1; 05473 chancat = dahdi_r2_get_channel_category(ast); 05474 callres = openr2_chan_make_call(p->r2chan, l, (c + p->stripmsd), chancat); 05475 if (-1 == callres) { 05476 ast_mutex_unlock(&p->lock); 05477 ast_log(LOG_ERROR, "unable to make new MFC/R2 call!\n"); 05478 return -1; 05479 } 05480 p->mfcr2_call_accepted = 0; 05481 p->mfcr2_progress = 0; 05482 ast_setstate(ast, AST_STATE_DIALING); 05483 } 05484 #endif /* HAVE_OPENR2 */ 05485 ast_mutex_unlock(&p->lock); 05486 return 0; 05487 }
static int dahdi_callwait | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 5335 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().
05336 { 05337 struct dahdi_pvt *p = ast->tech_pvt; 05338 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 05339 if (p->cidspill) { 05340 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 05341 ast_free(p->cidspill); 05342 } 05343 05344 /* 05345 * SAS: Subscriber Alert Signal, 440Hz for 300ms 05346 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves 05347 */ 05348 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 05349 return -1; 05350 save_conference(p); 05351 /* Silence */ 05352 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 05353 if (!p->callwaitrings && p->callwaitingcallerid) { 05354 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 05355 p->callwaitcas = 1; 05356 p->cidlen = 2400 + 680 + READ_SIZE * 4; 05357 } else { 05358 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 05359 p->callwaitcas = 0; 05360 p->cidlen = 2400 + READ_SIZE * 4; 05361 } 05362 p->cidpos = 0; 05363 send_callerid(p); 05364 05365 return 0; 05366 }
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 13879 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.
13880 { 13881 struct dahdi_pvt *p; 13882 struct dahdi_pvt *exitpvt; 13883 struct dahdi_starting_point start; 13884 int groupmatched = 0; 13885 int channelmatched = 0; 13886 13887 ast_mutex_lock(&iflock); 13888 p = determine_starting_point(dest, &start); 13889 if (!p) { 13890 ast_mutex_unlock(&iflock); 13891 return -1; 13892 } 13893 exitpvt = p; 13894 for (;;) { 13895 if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)) { 13896 /* We found a potential match. call the callback */ 13897 struct ast_str *device_name; 13898 char *dash; 13899 const char *monitor_type; 13900 char dialstring[AST_CHANNEL_NAME]; 13901 char full_device_name[AST_CHANNEL_NAME]; 13902 13903 switch (ast_get_cc_monitor_policy(p->cc_params)) { 13904 case AST_CC_MONITOR_NEVER: 13905 break; 13906 case AST_CC_MONITOR_NATIVE: 13907 case AST_CC_MONITOR_ALWAYS: 13908 case AST_CC_MONITOR_GENERIC: 13909 #if defined(HAVE_PRI) 13910 if (dahdi_sig_pri_lib_handles(p->sig)) { 13911 /* 13912 * ISDN is in a trunk busy condition so we need to monitor 13913 * the span congestion device state. 13914 */ 13915 snprintf(full_device_name, sizeof(full_device_name), 13916 "DAHDI/I%d/congestion", p->pri->span); 13917 } else 13918 #endif /* defined(HAVE_PRI) */ 13919 { 13920 #if defined(HAVE_PRI) 13921 device_name = create_channel_name(p, 1, ""); 13922 #else 13923 device_name = create_channel_name(p); 13924 #endif /* defined(HAVE_PRI) */ 13925 snprintf(full_device_name, sizeof(full_device_name), "DAHDI/%s", 13926 device_name ? ast_str_buffer(device_name) : ""); 13927 ast_free(device_name); 13928 /* 13929 * The portion after the '-' in the channel name is either a random 13930 * number, a sequence number, or a subchannel number. None are 13931 * necessary so strip them off. 13932 */ 13933 dash = strrchr(full_device_name, '-'); 13934 if (dash) { 13935 *dash = '\0'; 13936 } 13937 } 13938 snprintf(dialstring, sizeof(dialstring), "DAHDI/%s", dest); 13939 13940 /* 13941 * Analog can only do generic monitoring. 13942 * ISDN is in a trunk busy condition and any "device" is going 13943 * to be busy until a B channel becomes available. The generic 13944 * monitor can do this task. 13945 */ 13946 monitor_type = AST_CC_GENERIC_MONITOR_TYPE; 13947 callback(inbound, 13948 #if defined(HAVE_PRI) 13949 p->pri ? p->pri->cc_params : p->cc_params, 13950 #else 13951 p->cc_params, 13952 #endif /* defined(HAVE_PRI) */ 13953 monitor_type, full_device_name, dialstring, NULL); 13954 break; 13955 } 13956 } 13957 p = start.backwards ? p->prev : p->next; 13958 if (!p) { 13959 p = start.backwards ? ifend : iflist; 13960 } 13961 if (p == exitpvt) { 13962 break; 13963 } 13964 } 13965 ast_mutex_unlock(&iflock); 13966 return 0; 13967 }
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 1363 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().
01364 { 01365 /* recall that if a field is not included here it is initialized 01366 * to 0 or equivalent 01367 */ 01368 struct dahdi_chan_conf conf = { 01369 #ifdef HAVE_PRI 01370 .pri.pri = { 01371 .nsf = PRI_NSF_NONE, 01372 .switchtype = PRI_SWITCH_NI2, 01373 .dialplan = PRI_UNKNOWN + 1, 01374 .localdialplan = PRI_NATIONAL_ISDN + 1, 01375 .nodetype = PRI_CPE, 01376 .qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL, 01377 01378 #if defined(HAVE_PRI_CCSS) 01379 .cc_ptmp_recall_mode = 1,/* specificRecall */ 01380 .cc_qsig_signaling_link_req = 1,/* retain */ 01381 .cc_qsig_signaling_link_rsp = 1,/* retain */ 01382 #endif /* defined(HAVE_PRI_CCSS) */ 01383 01384 .minunused = 2, 01385 .idleext = "", 01386 .idledial = "", 01387 .internationalprefix = "", 01388 .nationalprefix = "", 01389 .localprefix = "", 01390 .privateprefix = "", 01391 .unknownprefix = "", 01392 .resetinterval = -1, 01393 }, 01394 #endif 01395 #if defined(HAVE_SS7) 01396 .ss7.ss7 = { 01397 .called_nai = SS7_NAI_NATIONAL, 01398 .calling_nai = SS7_NAI_NATIONAL, 01399 .internationalprefix = "", 01400 .nationalprefix = "", 01401 .subscriberprefix = "", 01402 .unknownprefix = "" 01403 }, 01404 #endif /* defined(HAVE_SS7) */ 01405 #ifdef HAVE_OPENR2 01406 .mfcr2 = { 01407 .variant = OR2_VAR_ITU, 01408 .mfback_timeout = -1, 01409 .metering_pulse_timeout = -1, 01410 .max_ani = 10, 01411 .max_dnis = 4, 01412 .get_ani_first = -1, 01413 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 01414 .skip_category_request = -1, 01415 #endif 01416 .call_files = 0, 01417 .allow_collect_calls = 0, 01418 .charge_calls = 1, 01419 .accept_on_offer = 1, 01420 .forced_release = 0, 01421 .double_answer = 0, 01422 .immediate_accept = -1, 01423 .logdir = "", 01424 .r2proto_file = "", 01425 .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING, 01426 .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER 01427 }, 01428 #endif 01429 .chan = { 01430 .context = "default", 01431 .cid_num = "", 01432 .cid_name = "", 01433 .cid_tag = "", 01434 .mohinterpret = "default", 01435 .mohsuggest = "", 01436 .parkinglot = "", 01437 .transfertobusy = 1, 01438 01439 .cid_signalling = CID_SIG_BELL, 01440 .cid_start = CID_START_RING, 01441 .dahditrcallerid = 0, 01442 .use_callerid = 1, 01443 .sig = -1, 01444 .outsigmod = -1, 01445 01446 .cid_rxgain = +5.0, 01447 01448 .tonezone = -1, 01449 01450 .echocancel.head.tap_length = 1, 01451 01452 .busycount = 3, 01453 .busycompare = 0, 01454 .busytonelength = 0, 01455 .busyquietlength = 0, 01456 .busyfuzziness = 0, 01457 .silencethreshold = 0, 01458 01459 .accountcode = "", 01460 01461 .mailbox = "", 01462 01463 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 01464 .mwisend_fsk = 1, 01465 #endif 01466 .polarityonanswerdelay = 600, 01467 01468 .sendcalleridafter = DEFAULT_CIDRINGS, 01469 01470 .buf_policy = DAHDI_POLICY_IMMEDIATE, 01471 .buf_no = numbufs, 01472 .usefaxbuffers = 0, 01473 .cc_params = ast_cc_config_params_init(), 01474 }, 01475 .timing = { 01476 .prewinktime = -1, 01477 .preflashtime = -1, 01478 .winktime = -1, 01479 .flashtime = -1, 01480 .starttime = -1, 01481 .rxwinktime = -1, 01482 .rxflashtime = -1, 01483 .debouncetime = -1 01484 }, 01485 .is_sig_auto = 1, 01486 .smdi_port = "/dev/ttyS0", 01487 }; 01488 01489 return conf; 01490 }
static int dahdi_channels_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 18490 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.
18492 { 18493 struct dahdi_pvt *tmp; 18494 struct ast_data *data_channel; 18495 18496 ast_mutex_lock(&iflock); 18497 for (tmp = iflist; tmp; tmp = tmp->next) { 18498 data_channel = ast_data_add_node(data_root, "channel"); 18499 if (!data_channel) { 18500 continue; 18501 } 18502 18503 ast_data_add_structure(dahdi_pvt, data_channel, tmp); 18504 18505 /* if this channel doesn't match remove it. */ 18506 if (!ast_data_search_match(search, data_channel)) { 18507 ast_data_remove_node(data_root, data_channel); 18508 } 18509 } 18510 ast_mutex_unlock(&iflock); 18511 18512 return 0; 18513 }
static void dahdi_close | ( | int | fd | ) | [static] |
Definition at line 4359 of file chan_dahdi.c.
Referenced by dahdi_close_pri_fd(), and dahdi_close_sub().
static void dahdi_close_pri_fd | ( | struct dahdi_pri * | pri, | |
int | fd_num | |||
) | [static] |
Definition at line 4372 of file chan_dahdi.c.
References dahdi_close(), sig_pri_span::fds, and dahdi_pri::pri.
Referenced by __unload_module(), and prepare_pri().
04373 { 04374 dahdi_close(pri->pri.fds[fd_num]); 04375 pri->pri.fds[fd_num] = -1; 04376 }
static void dahdi_close_sub | ( | struct dahdi_pvt * | chan_pvt, | |
int | sub_num | |||
) | [static] |
Definition at line 4365 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().
04366 { 04367 dahdi_close(chan_pvt->subs[sub_num].dfd); 04368 chan_pvt->subs[sub_num].dfd = -1; 04369 }
static int dahdi_confmute | ( | struct dahdi_pvt * | p, | |
int | muted | |||
) | [inline, static] |
Definition at line 5178 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().
05179 { 05180 int x, res; 05181 05182 x = muted; 05183 #if defined(HAVE_PRI) || defined(HAVE_SS7) 05184 switch (p->sig) { 05185 #if defined(HAVE_PRI) 05186 case SIG_PRI_LIB_HANDLE_CASES: 05187 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 05188 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */ 05189 break; 05190 } 05191 /* Fall through */ 05192 #endif /* defined(HAVE_PRI) */ 05193 #if defined(HAVE_SS7) 05194 case SIG_SS7: 05195 #endif /* defined(HAVE_SS7) */ 05196 { 05197 int y = 1; 05198 05199 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y); 05200 if (res) 05201 ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n", 05202 p->channel, strerror(errno)); 05203 } 05204 break; 05205 default: 05206 break; 05207 } 05208 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 05209 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x); 05210 if (res < 0) 05211 ast_log(LOG_WARNING, "DAHDI confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno)); 05212 return res; 05213 }
static char* dahdi_destroy_channel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15030 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.
15031 { 15032 int channel; 15033 int ret; 15034 switch (cmd) { 15035 case CLI_INIT: 15036 e->command = "dahdi destroy channel"; 15037 e->usage = 15038 "Usage: dahdi destroy channel <chan num>\n" 15039 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n"; 15040 return NULL; 15041 case CLI_GENERATE: 15042 return NULL; 15043 } 15044 if (a->argc != 4) 15045 return CLI_SHOWUSAGE; 15046 15047 channel = atoi(a->argv[3]); 15048 ret = dahdi_destroy_channel_bynum(channel); 15049 return ( RESULT_SUCCESS == ret ) ? CLI_SUCCESS : CLI_FAILURE; 15050 }
static int dahdi_destroy_channel_bynum | ( | int | channel | ) | [static] |
Definition at line 11411 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().
11412 { 11413 struct dahdi_pvt *cur; 11414 11415 ast_mutex_lock(&iflock); 11416 for (cur = iflist; cur; cur = cur->next) { 11417 if (cur->channel == channel) { 11418 int x = DAHDI_FLASH; 11419 11420 /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */ 11421 ioctl(cur->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 11422 11423 destroy_channel(cur, 1); 11424 ast_mutex_unlock(&iflock); 11425 ast_module_unref(ast_module_info->self); 11426 return RESULT_SUCCESS; 11427 } 11428 } 11429 ast_mutex_unlock(&iflock); 11430 return RESULT_FAILURE; 11431 }
static int dahdi_devicestate | ( | void * | data | ) | [static] |
Definition at line 13817 of file chan_dahdi.c.
References AST_DEVICE_UNKNOWN, sig_pri_span::congestion_devstate, dahdi_pri::pri, and pris.
13818 { 13819 #if defined(HAVE_PRI) 13820 char *device; 13821 unsigned span; 13822 int res; 13823 13824 device = data; 13825 13826 if (*device != 'I') { 13827 /* The request is not for an ISDN span device. */ 13828 return AST_DEVICE_UNKNOWN; 13829 } 13830 res = sscanf(device, "I%30u", &span); 13831 if (res != 1 || !span || NUM_SPANS < span) { 13832 /* Bad format for ISDN span device name. */ 13833 return AST_DEVICE_UNKNOWN; 13834 } 13835 device = strchr(device, '/'); 13836 if (!device) { 13837 /* Bad format for ISDN span device name. */ 13838 return AST_DEVICE_UNKNOWN; 13839 } 13840 13841 /* 13842 * Since there are currently no other span devstate's defined, 13843 * it must be congestion. 13844 */ 13845 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER) 13846 ++device; 13847 if (!strcmp(device, "congestion")) 13848 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */ 13849 { 13850 return pris[span - 1].pri.congestion_devstate; 13851 } 13852 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER) 13853 else if (!strcmp(device, "threshold")) { 13854 return pris[span - 1].pri.threshold_devstate; 13855 } 13856 return AST_DEVICE_UNKNOWN; 13857 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */ 13858 #else 13859 return AST_DEVICE_UNKNOWN; 13860 #endif /* defined(HAVE_PRI) */ 13861 }
static int dahdi_digit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 4463 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, ast_channel::name, 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.
04464 { 04465 struct dahdi_pvt *pvt; 04466 int idx; 04467 int dtmf = -1; 04468 int res; 04469 04470 pvt = chan->tech_pvt; 04471 04472 ast_mutex_lock(&pvt->lock); 04473 04474 idx = dahdi_get_index(chan, pvt, 0); 04475 04476 if ((idx != SUB_REAL) || !pvt->owner) 04477 goto out; 04478 04479 #ifdef HAVE_PRI 04480 switch (pvt->sig) { 04481 case SIG_PRI_LIB_HANDLE_CASES: 04482 res = sig_pri_digit_begin(pvt->sig_pvt, chan, digit); 04483 if (!res) 04484 goto out; 04485 break; 04486 default: 04487 break; 04488 } 04489 #endif 04490 if ((dtmf = digit_to_dtmfindex(digit)) == -1) 04491 goto out; 04492 04493 if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) { 04494 struct dahdi_dialoperation zo = { 04495 .op = DAHDI_DIAL_OP_APPEND, 04496 }; 04497 04498 zo.dialstr[0] = 'T'; 04499 zo.dialstr[1] = digit; 04500 zo.dialstr[2] = '\0'; 04501 if ((res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo))) 04502 ast_log(LOG_WARNING, "Channel %s couldn't dial digit %c: %s\n", 04503 chan->name, digit, strerror(errno)); 04504 else 04505 pvt->dialing = 1; 04506 } else { 04507 ast_debug(1, "Channel %s started VLDTMF digit '%c'\n", 04508 chan->name, digit); 04509 pvt->dialing = 1; 04510 pvt->begindigit = digit; 04511 } 04512 04513 out: 04514 ast_mutex_unlock(&pvt->lock); 04515 04516 return 0; 04517 }
static int dahdi_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 4519 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, ast_channel::name, dahdi_pvt::owner, dahdi_pvt::pulse, dahdi_pvt::sig, SUB_REAL, dahdi_pvt::subs, and ast_channel::tech_pvt.
04520 { 04521 struct dahdi_pvt *pvt; 04522 int res = 0; 04523 int idx; 04524 int x; 04525 04526 pvt = chan->tech_pvt; 04527 04528 ast_mutex_lock(&pvt->lock); 04529 04530 idx = dahdi_get_index(chan, pvt, 0); 04531 04532 if ((idx != SUB_REAL) || !pvt->owner || pvt->pulse) 04533 goto out; 04534 04535 #ifdef HAVE_PRI 04536 /* This means that the digit was already sent via PRI signalling */ 04537 if (dahdi_sig_pri_lib_handles(pvt->sig) && !pvt->begindigit) { 04538 goto out; 04539 } 04540 #endif 04541 04542 if (pvt->begindigit) { 04543 x = -1; 04544 ast_debug(1, "Channel %s ending VLDTMF digit '%c'\n", 04545 chan->name, digit); 04546 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x); 04547 pvt->dialing = 0; 04548 pvt->begindigit = 0; 04549 } 04550 04551 out: 04552 ast_mutex_unlock(&pvt->lock); 04553 04554 return res; 04555 }
static void dahdi_disable_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4970 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().
04971 { 04972 int res; 04973 04974 if (p->echocanon) { 04975 struct dahdi_echocanparams ecp = { .tap_length = 0 }; 04976 04977 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &ecp); 04978 04979 if (res) 04980 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno)); 04981 else 04982 ast_debug(1, "Disabled echo cancellation on channel %d\n", p->channel); 04983 } 04984 04985 p->echocanon = 0; 04986 }
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 9877 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().
09878 { 09879 if (analog_lib_handles(dahdichan->sig, dahdichan->radio, dahdichan->oprmode)) { 09880 return analog_dnd(dahdichan->sig_pvt, flag); 09881 } 09882 09883 if (flag == -1) { 09884 return dahdichan->dnd; 09885 } 09886 09887 /* Do not disturb */ 09888 dahdichan->dnd = flag; 09889 ast_verb(3, "%s DND on channel %d\n", 09890 flag? "Enabled" : "Disabled", 09891 dahdichan->channel); 09892 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 09893 "Channel: DAHDI/%d\r\n" 09894 "Status: %s\r\n", dahdichan->channel, 09895 flag? "enabled" : "disabled"); 09896 09897 return 0; 09898 }
static void dahdi_enable_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4898 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().
04899 { 04900 int res; 04901 if (!p) 04902 return; 04903 if (p->echocanon) { 04904 ast_debug(1, "Echo cancellation already on\n"); 04905 return; 04906 } 04907 if (p->digital) { 04908 ast_debug(1, "Echo cancellation isn't required on digital connection\n"); 04909 return; 04910 } 04911 if (p->echocancel.head.tap_length) { 04912 #if defined(HAVE_PRI) || defined(HAVE_SS7) 04913 switch (p->sig) { 04914 #if defined(HAVE_PRI) 04915 case SIG_PRI_LIB_HANDLE_CASES: 04916 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 04917 /* 04918 * PRI nobch pseudo channel. Does not need ec anyway. 04919 * Does not handle ioctl(DAHDI_AUDIOMODE) 04920 */ 04921 return; 04922 } 04923 /* Fall through */ 04924 #endif /* defined(HAVE_PRI) */ 04925 #if defined(HAVE_SS7) 04926 case SIG_SS7: 04927 #endif /* defined(HAVE_SS7) */ 04928 { 04929 int x = 1; 04930 04931 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x); 04932 if (res) 04933 ast_log(LOG_WARNING, 04934 "Unable to enable audio mode on channel %d (%s)\n", 04935 p->channel, strerror(errno)); 04936 } 04937 break; 04938 default: 04939 break; 04940 } 04941 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 04942 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &p->echocancel); 04943 if (res) { 04944 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno)); 04945 } else { 04946 p->echocanon = 1; 04947 ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel); 04948 } 04949 } else 04950 ast_debug(1, "No echo cancellation requested\n"); 04951 }
static struct ast_frame * dahdi_exception | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 8908 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.
08909 { 08910 struct dahdi_pvt *p = ast->tech_pvt; 08911 struct ast_frame *f; 08912 ast_mutex_lock(&p->lock); 08913 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 08914 struct analog_pvt *analog_p = p->sig_pvt; 08915 f = analog_exception(analog_p, ast); 08916 } else { 08917 f = __dahdi_exception(ast); 08918 } 08919 ast_mutex_unlock(&p->lock); 08920 return f; 08921 }
static int dahdi_fake_event | ( | struct dahdi_pvt * | p, | |
int | mode | |||
) | [static] |
Definition at line 15881 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().
15882 { 15883 if (p) { 15884 switch (mode) { 15885 case TRANSFER: 15886 p->fake_event = DAHDI_EVENT_WINKFLASH; 15887 break; 15888 case HANGUP: 15889 p->fake_event = DAHDI_EVENT_ONHOOK; 15890 break; 15891 default: 15892 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name); 15893 } 15894 } 15895 return 0; 15896 }
static int dahdi_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 7580 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.
07581 { 07582 struct dahdi_pvt *p = newchan->tech_pvt; 07583 int x; 07584 07585 ast_mutex_lock(&p->lock); 07586 07587 ast_debug(1, "New owner for channel %d is %s\n", p->channel, newchan->name); 07588 if (p->owner == oldchan) { 07589 p->owner = newchan; 07590 } 07591 for (x = 0; x < 3; x++) { 07592 if (p->subs[x].owner == oldchan) { 07593 if (!x) { 07594 dahdi_unlink(NULL, p, 0); 07595 } 07596 p->subs[x].owner = newchan; 07597 } 07598 } 07599 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 07600 analog_fixup(oldchan, newchan, p->sig_pvt); 07601 #if defined(HAVE_PRI) 07602 } else if (dahdi_sig_pri_lib_handles(p->sig)) { 07603 sig_pri_fixup(oldchan, newchan, p->sig_pvt); 07604 #endif /* defined(HAVE_PRI) */ 07605 #if defined(HAVE_SS7) 07606 } else if (p->sig == SIG_SS7) { 07607 sig_ss7_fixup(oldchan, newchan, p->sig_pvt); 07608 #endif /* defined(HAVE_SS7) */ 07609 } 07610 update_conf(p); 07611 07612 ast_mutex_unlock(&p->lock); 07613 07614 if (newchan->_state == AST_STATE_RINGING) { 07615 dahdi_indicate(newchan, AST_CONTROL_RINGING, NULL, 0); 07616 } 07617 return 0; 07618 }
static int dahdi_func_read | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 6937 of file chan_dahdi.c.
References ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, dahdi_pvt::lock, dahdi_pvt::rxgain, dahdi_pvt::sig, SIG_MFCR2, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, dahdi_pvt::span, ast_channel::tech_pvt, and dahdi_pvt::txgain.
06938 { 06939 struct dahdi_pvt *p = chan->tech_pvt; 06940 int res = 0; 06941 06942 if (!p) { 06943 /* No private structure! */ 06944 *buf = '\0'; 06945 return -1; 06946 } 06947 06948 if (!strcasecmp(data, "rxgain")) { 06949 ast_mutex_lock(&p->lock); 06950 snprintf(buf, len, "%f", p->rxgain); 06951 ast_mutex_unlock(&p->lock); 06952 } else if (!strcasecmp(data, "txgain")) { 06953 ast_mutex_lock(&p->lock); 06954 snprintf(buf, len, "%f", p->txgain); 06955 ast_mutex_unlock(&p->lock); 06956 } else if (!strcasecmp(data, "dahdi_channel")) { 06957 ast_mutex_lock(&p->lock); 06958 snprintf(buf, len, "%d", p->channel); 06959 ast_mutex_unlock(&p->lock); 06960 } else if (!strcasecmp(data, "dahdi_span")) { 06961 ast_mutex_lock(&p->lock); 06962 snprintf(buf, len, "%d", p->span); 06963 ast_mutex_unlock(&p->lock); 06964 } else if (!strcasecmp(data, "dahdi_type")) { 06965 ast_mutex_lock(&p->lock); 06966 switch (p->sig) { 06967 #if defined(HAVE_OPENR2) 06968 case SIG_MFCR2: 06969 ast_copy_string(buf, "mfc/r2", len); 06970 break; 06971 #endif /* defined(HAVE_OPENR2) */ 06972 #if defined(HAVE_PRI) 06973 case SIG_PRI_LIB_HANDLE_CASES: 06974 ast_copy_string(buf, "pri", len); 06975 break; 06976 #endif /* defined(HAVE_PRI) */ 06977 case 0: 06978 ast_copy_string(buf, "pseudo", len); 06979 break; 06980 #if defined(HAVE_SS7) 06981 case SIG_SS7: 06982 ast_copy_string(buf, "ss7", len); 06983 break; 06984 #endif /* defined(HAVE_SS7) */ 06985 default: 06986 /* The only thing left is analog ports. */ 06987 ast_copy_string(buf, "analog", len); 06988 break; 06989 } 06990 ast_mutex_unlock(&p->lock); 06991 #if defined(HAVE_PRI) 06992 #if defined(HAVE_PRI_REVERSE_CHARGE) 06993 } else if (!strcasecmp(data, "reversecharge")) { 06994 ast_mutex_lock(&p->lock); 06995 switch (p->sig) { 06996 case SIG_PRI_LIB_HANDLE_CASES: 06997 snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->reverse_charging_indication); 06998 break; 06999 default: 07000 *buf = '\0'; 07001 res = -1; 07002 break; 07003 } 07004 ast_mutex_unlock(&p->lock); 07005 #endif 07006 #if defined(HAVE_PRI_SETUP_KEYPAD) 07007 } else if (!strcasecmp(data, "keypad_digits")) { 07008 ast_mutex_lock(&p->lock); 07009 switch (p->sig) { 07010 case SIG_PRI_LIB_HANDLE_CASES: 07011 ast_copy_string(buf, ((struct sig_pri_chan *) p->sig_pvt)->keypad_digits, 07012 len); 07013 break; 07014 default: 07015 *buf = '\0'; 07016 res = -1; 07017 break; 07018 } 07019 ast_mutex_unlock(&p->lock); 07020 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 07021 } else if (!strcasecmp(data, "no_media_path")) { 07022 ast_mutex_lock(&p->lock); 07023 switch (p->sig) { 07024 case SIG_PRI_LIB_HANDLE_CASES: 07025 /* 07026 * TRUE if the call is on hold or is call waiting because 07027 * there is no media path available. 07028 */ 07029 snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel); 07030 break; 07031 default: 07032 *buf = '\0'; 07033 res = -1; 07034 break; 07035 } 07036 ast_mutex_unlock(&p->lock); 07037 #endif /* defined(HAVE_PRI) */ 07038 } else { 07039 *buf = '\0'; 07040 res = -1; 07041 } 07042 07043 return res; 07044 }
static int dahdi_func_write | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 7076 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.
07077 { 07078 struct dahdi_pvt *p = chan->tech_pvt; 07079 int res = 0; 07080 07081 if (!p) { 07082 /* No private structure! */ 07083 return -1; 07084 } 07085 07086 if (!strcasecmp(data, "buffers")) { 07087 int num_bufs, policy; 07088 07089 if (!(parse_buffers_policy(value, &num_bufs, &policy))) { 07090 struct dahdi_bufferinfo bi = { 07091 .txbufpolicy = policy, 07092 .rxbufpolicy = policy, 07093 .bufsize = p->bufsize, 07094 .numbufs = num_bufs, 07095 }; 07096 int bpres; 07097 07098 if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 07099 ast_log(LOG_WARNING, "Channel '%d' unable to override buffer policy: %s\n", p->channel, strerror(errno)); 07100 } else { 07101 p->bufferoverrideinuse = 1; 07102 } 07103 } else { 07104 res = -1; 07105 } 07106 } else if (!strcasecmp(data, "echocan_mode")) { 07107 if (!strcasecmp(value, "on")) { 07108 ast_mutex_lock(&p->lock); 07109 dahdi_enable_ec(p); 07110 ast_mutex_unlock(&p->lock); 07111 } else if (!strcasecmp(value, "off")) { 07112 ast_mutex_lock(&p->lock); 07113 dahdi_disable_ec(p); 07114 ast_mutex_unlock(&p->lock); 07115 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 07116 } else if (!strcasecmp(value, "fax")) { 07117 int blah = 1; 07118 07119 ast_mutex_lock(&p->lock); 07120 if (!p->echocanon) { 07121 dahdi_enable_ec(p); 07122 } 07123 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) { 07124 ast_log(LOG_WARNING, "Unable to place echocan into fax mode on channel %d: %s\n", p->channel, strerror(errno)); 07125 } 07126 ast_mutex_unlock(&p->lock); 07127 } else if (!strcasecmp(value, "voice")) { 07128 int blah = 0; 07129 07130 ast_mutex_lock(&p->lock); 07131 if (!p->echocanon) { 07132 dahdi_enable_ec(p); 07133 } 07134 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) { 07135 ast_log(LOG_WARNING, "Unable to place echocan into voice mode on channel %d: %s\n", p->channel, strerror(errno)); 07136 } 07137 ast_mutex_unlock(&p->lock); 07138 #endif 07139 } else { 07140 ast_log(LOG_WARNING, "Unsupported value '%s' provided for '%s' item.\n", value, data); 07141 res = -1; 07142 } 07143 } else { 07144 res = -1; 07145 } 07146 07147 return res; 07148 }
static int dahdi_get_event | ( | int | fd | ) | [inline, static] |
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition at line 489 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().
00490 { 00491 int j; 00492 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1) 00493 return -1; 00494 return j; 00495 }
static void dahdi_handle_dtmf | ( | struct ast_channel * | ast, | |
int | idx, | |||
struct ast_frame ** | dest | |||
) | [static] |
Definition at line 7757 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().
07758 { 07759 struct dahdi_pvt *p = ast->tech_pvt; 07760 struct ast_frame *f = *dest; 07761 07762 ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n", 07763 f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End", 07764 f->subclass.integer, f->subclass.integer, ast->name); 07765 07766 if (p->confirmanswer) { 07767 if (f->frametype == AST_FRAME_DTMF_END) { 07768 ast_debug(1, "Confirm answer on %s!\n", ast->name); 07769 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 07770 of a DTMF digit */ 07771 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 07772 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 07773 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 07774 p->confirmanswer = 0; 07775 } else { 07776 p->subs[idx].f.frametype = AST_FRAME_NULL; 07777 p->subs[idx].f.subclass.integer = 0; 07778 } 07779 *dest = &p->subs[idx].f; 07780 } else if (p->callwaitcas) { 07781 if (f->frametype == AST_FRAME_DTMF_END) { 07782 if ((f->subclass.integer == 'A') || (f->subclass.integer == 'D')) { 07783 ast_debug(1, "Got some DTMF, but it's for the CAS\n"); 07784 ast_free(p->cidspill); 07785 p->cidspill = NULL; 07786 send_cwcidspill(p); 07787 } 07788 p->callwaitcas = 0; 07789 } 07790 p->subs[idx].f.frametype = AST_FRAME_NULL; 07791 p->subs[idx].f.subclass.integer = 0; 07792 *dest = &p->subs[idx].f; 07793 } else if (f->subclass.integer == 'f') { 07794 if (f->frametype == AST_FRAME_DTMF_END) { 07795 /* Fax tone -- Handle and return NULL */ 07796 if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) { 07797 /* If faxbuffers are configured, use them for the fax transmission */ 07798 if (p->usefaxbuffers && !p->bufferoverrideinuse) { 07799 struct dahdi_bufferinfo bi = { 07800 .txbufpolicy = p->faxbuf_policy, 07801 .bufsize = p->bufsize, 07802 .numbufs = p->faxbuf_no 07803 }; 07804 int res; 07805 07806 if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 07807 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast->name, strerror(errno)); 07808 } else { 07809 p->bufferoverrideinuse = 1; 07810 } 07811 } 07812 p->faxhandled = 1; 07813 if (p->dsp) { 07814 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 07815 ast_dsp_set_features(p->dsp, p->dsp_features); 07816 ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast->name); 07817 } 07818 if (strcmp(ast->exten, "fax")) { 07819 const char *target_context = S_OR(ast->macrocontext, ast->context); 07820 07821 /* We need to unlock 'ast' here because ast_exists_extension has the 07822 * potential to start autoservice on the channel. Such action is prone 07823 * to deadlock. 07824 */ 07825 ast_mutex_unlock(&p->lock); 07826 ast_channel_unlock(ast); 07827 if (ast_exists_extension(ast, target_context, "fax", 1, 07828 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 07829 ast_channel_lock(ast); 07830 ast_mutex_lock(&p->lock); 07831 ast_verb(3, "Redirecting %s to fax extension\n", ast->name); 07832 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 07833 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 07834 if (ast_async_goto(ast, target_context, "fax", 1)) 07835 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 07836 } else { 07837 ast_channel_lock(ast); 07838 ast_mutex_lock(&p->lock); 07839 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 07840 } 07841 } else { 07842 ast_debug(1, "Already in a fax extension, not redirecting\n"); 07843 } 07844 } else { 07845 ast_debug(1, "Fax already handled\n"); 07846 } 07847 dahdi_confmute(p, 0); 07848 } 07849 p->subs[idx].f.frametype = AST_FRAME_NULL; 07850 p->subs[idx].f.subclass.integer = 0; 07851 *dest = &p->subs[idx].f; 07852 } 07853 }
static struct ast_frame* dahdi_handle_event | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 7883 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_lock, 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_mutex_lock, ast_mutex_unlock, ast_null_frame, 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_CALL_LEVEL_PROCEEDING, sig_pri_chan_alarm_notify(), sig_pri_dial_complete(), 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().
07884 { 07885 int res, x; 07886 int idx, mysig; 07887 char *c; 07888 struct dahdi_pvt *p = ast->tech_pvt; 07889 pthread_t threadid; 07890 struct ast_channel *chan; 07891 struct ast_frame *f; 07892 07893 idx = dahdi_get_index(ast, p, 0); 07894 if (idx < 0) { 07895 return &ast_null_frame; 07896 } 07897 mysig = p->sig; 07898 if (p->outsigmod > -1) 07899 mysig = p->outsigmod; 07900 p->subs[idx].f.frametype = AST_FRAME_NULL; 07901 p->subs[idx].f.subclass.integer = 0; 07902 p->subs[idx].f.datalen = 0; 07903 p->subs[idx].f.samples = 0; 07904 p->subs[idx].f.mallocd = 0; 07905 p->subs[idx].f.offset = 0; 07906 p->subs[idx].f.src = "dahdi_handle_event"; 07907 p->subs[idx].f.data.ptr = NULL; 07908 f = &p->subs[idx].f; 07909 07910 if (p->fake_event) { 07911 res = p->fake_event; 07912 p->fake_event = 0; 07913 } else 07914 res = dahdi_get_event(p->subs[idx].dfd); 07915 07916 ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, idx); 07917 07918 if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) { 07919 p->pulsedial = (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0; 07920 ast_debug(1, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 07921 #if defined(HAVE_PRI) 07922 if (dahdi_sig_pri_lib_handles(p->sig) 07923 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING 07924 && p->pri 07925 && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 07926 /* absorb event */ 07927 } else 07928 #endif /* defined(HAVE_PRI) */ 07929 { 07930 /* Unmute conference */ 07931 dahdi_confmute(p, 0); 07932 p->subs[idx].f.frametype = AST_FRAME_DTMF_END; 07933 p->subs[idx].f.subclass.integer = res & 0xff; 07934 dahdi_handle_dtmf(ast, idx, &f); 07935 } 07936 return f; 07937 } 07938 07939 if (res & DAHDI_EVENT_DTMFDOWN) { 07940 ast_debug(1, "DTMF Down '%c'\n", res & 0xff); 07941 #if defined(HAVE_PRI) 07942 if (dahdi_sig_pri_lib_handles(p->sig) 07943 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING 07944 && p->pri 07945 && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 07946 /* absorb event */ 07947 } else 07948 #endif /* defined(HAVE_PRI) */ 07949 { 07950 /* Mute conference */ 07951 dahdi_confmute(p, 1); 07952 p->subs[idx].f.frametype = AST_FRAME_DTMF_BEGIN; 07953 p->subs[idx].f.subclass.integer = res & 0xff; 07954 dahdi_handle_dtmf(ast, idx, &f); 07955 } 07956 return &p->subs[idx].f; 07957 } 07958 07959 switch (res) { 07960 case DAHDI_EVENT_EC_DISABLED: 07961 ast_verb(3, "Channel %d echo canceler disabled.\n", p->channel); 07962 p->echocanon = 0; 07963 break; 07964 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 07965 case DAHDI_EVENT_TX_CED_DETECTED: 07966 ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel); 07967 break; 07968 case DAHDI_EVENT_RX_CED_DETECTED: 07969 ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel); 07970 break; 07971 case DAHDI_EVENT_EC_NLP_DISABLED: 07972 ast_verb(3, "Channel %d echo canceler disabled its NLP.\n", p->channel); 07973 break; 07974 case DAHDI_EVENT_EC_NLP_ENABLED: 07975 ast_verb(3, "Channel %d echo canceler enabled its NLP.\n", p->channel); 07976 break; 07977 #endif 07978 case DAHDI_EVENT_BITSCHANGED: 07979 #ifdef HAVE_OPENR2 07980 if (p->sig != SIG_MFCR2) { 07981 ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig)); 07982 } else { 07983 ast_log(LOG_DEBUG, "bits changed in chan %d\n", p->channel); 07984 openr2_chan_handle_cas(p->r2chan); 07985 } 07986 #else 07987 ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig)); 07988 #endif 07989 break; 07990 case DAHDI_EVENT_PULSE_START: 07991 /* Stop tone if there's a pulse start and the PBX isn't started */ 07992 if (!ast->pbx) 07993 tone_zone_play_tone(p->subs[idx].dfd, -1); 07994 break; 07995 case DAHDI_EVENT_DIALCOMPLETE: 07996 /* DAHDI has completed dialing all digits sent using DAHDI_DIAL. */ 07997 #if defined(HAVE_PRI) 07998 if (dahdi_sig_pri_lib_handles(p->sig)) { 07999 if (p->inalarm) { 08000 break; 08001 } 08002 if (ioctl(p->subs[idx].dfd, DAHDI_DIALING, &x) == -1) { 08003 ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed on %s: %s\n", ast->name, 08004 strerror(errno)); 08005 return NULL; 08006 } 08007 if (x) { 08008 /* Still dialing in DAHDI driver */ 08009 break; 08010 } 08011 /* 08012 * The ast channel is locked and the private may be locked more 08013 * than once. 08014 */ 08015 sig_pri_dial_complete(p->sig_pvt, ast); 08016 break; 08017 } 08018 #endif /* defined(HAVE_PRI) */ 08019 #ifdef HAVE_OPENR2 08020 if ((p->sig & SIG_MFCR2) && p->r2chan && ast->_state != AST_STATE_UP) { 08021 /* we don't need to do anything for this event for R2 signaling 08022 if the call is being setup */ 08023 break; 08024 } 08025 #endif 08026 if (p->inalarm) break; 08027 if ((p->radio || (p->oprmode < 0))) break; 08028 if (ioctl(p->subs[idx].dfd,DAHDI_DIALING,&x) == -1) { 08029 ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed on %s: %s\n",ast->name, strerror(errno)); 08030 return NULL; 08031 } 08032 if (!x) { /* if not still dialing in driver */ 08033 dahdi_enable_ec(p); 08034 if (p->echobreak) { 08035 dahdi_train_ec(p); 08036 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 08037 p->dop.op = DAHDI_DIAL_OP_REPLACE; 08038 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08039 p->echobreak = 0; 08040 } else { 08041 p->dialing = 0; 08042 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) { 08043 /* if thru with dialing after offhook */ 08044 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 08045 ast_setstate(ast, AST_STATE_UP); 08046 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08047 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08048 break; 08049 } else { /* if to state wait for offhook to dial rest */ 08050 /* we now wait for off hook */ 08051 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 08052 } 08053 } 08054 if (ast->_state == AST_STATE_DIALING) { 08055 if ((p->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 08056 ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n"); 08057 } else if (p->confirmanswer || (!p->dialednone 08058 && ((mysig == SIG_EM) || (mysig == SIG_EM_E1) 08059 || (mysig == SIG_EMWINK) || (mysig == SIG_FEATD) 08060 || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF) 08061 || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) 08062 || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB) 08063 || (mysig == SIG_SF) || (mysig == SIG_SFWINK) 08064 || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF) 08065 || (mysig == SIG_SF_FEATB)))) { 08066 ast_setstate(ast, AST_STATE_RINGING); 08067 } else if (!p->answeronpolarityswitch) { 08068 ast_setstate(ast, AST_STATE_UP); 08069 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08070 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08071 /* If aops=0 and hops=1, this is necessary */ 08072 p->polarity = POLARITY_REV; 08073 } else { 08074 /* Start clean, so we can catch the change to REV polarity when party answers */ 08075 p->polarity = POLARITY_IDLE; 08076 } 08077 } 08078 } 08079 } 08080 break; 08081 case DAHDI_EVENT_ALARM: 08082 switch (p->sig) { 08083 #if defined(HAVE_PRI) 08084 case SIG_PRI_LIB_HANDLE_CASES: 08085 sig_pri_chan_alarm_notify(p->sig_pvt, 0); 08086 break; 08087 #endif /* defined(HAVE_PRI) */ 08088 #if defined(HAVE_SS7) 08089 case SIG_SS7: 08090 sig_ss7_set_alarm(p->sig_pvt, 1); 08091 break; 08092 #endif /* defined(HAVE_SS7) */ 08093 default: 08094 p->inalarm = 1; 08095 break; 08096 } 08097 res = get_alarms(p); 08098 handle_alarms(p, res); 08099 #ifdef HAVE_PRI 08100 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 08101 /* fall through intentionally */ 08102 } else { 08103 break; 08104 } 08105 #endif 08106 #if defined(HAVE_SS7) 08107 if (p->sig == SIG_SS7) 08108 break; 08109 #endif /* defined(HAVE_SS7) */ 08110 #ifdef HAVE_OPENR2 08111 if (p->sig == SIG_MFCR2) 08112 break; 08113 #endif 08114 case DAHDI_EVENT_ONHOOK: 08115 if (p->radio) { 08116 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08117 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_UNKEY; 08118 break; 08119 } 08120 if (p->oprmode < 0) 08121 { 08122 if (p->oprmode != -1) break; 08123 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 08124 { 08125 /* Make sure it starts ringing */ 08126 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 08127 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RING); 08128 save_conference(p->oprpeer); 08129 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 08130 } 08131 break; 08132 } 08133 switch (p->sig) { 08134 case SIG_FXOLS: 08135 case SIG_FXOGS: 08136 case SIG_FXOKS: 08137 /* Check for some special conditions regarding call waiting */ 08138 if (idx == SUB_REAL) { 08139 /* The normal line was hung up */ 08140 if (p->subs[SUB_CALLWAIT].owner) { 08141 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 08142 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 08143 ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel); 08144 unalloc_sub(p, SUB_CALLWAIT); 08145 #if 0 08146 p->subs[idx].needanswer = 0; 08147 p->subs[idx].needringing = 0; 08148 #endif 08149 p->callwaitingrepeat = 0; 08150 p->cidcwexpire = 0; 08151 p->cid_suppress_expire = 0; 08152 p->owner = NULL; 08153 /* Don't start streaming audio yet if the incoming call isn't up yet */ 08154 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 08155 p->dialing = 1; 08156 dahdi_ring_phone(p); 08157 } else if (p->subs[SUB_THREEWAY].owner) { 08158 unsigned int mssinceflash; 08159 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 08160 the private structure -- not especially easy or clean */ 08161 while (p->subs[SUB_THREEWAY].owner && ast_channel_trylock(p->subs[SUB_THREEWAY].owner)) { 08162 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 08163 DLA_UNLOCK(&p->lock); 08164 CHANNEL_DEADLOCK_AVOIDANCE(ast); 08165 /* We can grab ast and p in that order, without worry. We should make sure 08166 nothing seriously bad has happened though like some sort of bizarre double 08167 masquerade! */ 08168 DLA_LOCK(&p->lock); 08169 if (p->owner != ast) { 08170 ast_log(LOG_WARNING, "This isn't good...\n"); 08171 return NULL; 08172 } 08173 } 08174 if (!p->subs[SUB_THREEWAY].owner) { 08175 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 08176 return NULL; 08177 } 08178 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 08179 ast_debug(1, "Last flash was %d ms ago\n", mssinceflash); 08180 if (mssinceflash < MIN_MS_SINCE_FLASH) { 08181 /* It hasn't been long enough since the last flashook. This is probably a bounce on 08182 hanging up. Hangup both channels now */ 08183 if (p->subs[SUB_THREEWAY].owner) 08184 ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY].owner, AST_CAUSE_NO_ANSWER); 08185 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08186 ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 08187 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08188 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 08189 if (p->transfer) { 08190 /* In any case this isn't a threeway call anymore */ 08191 p->subs[SUB_REAL].inthreeway = 0; 08192 p->subs[SUB_THREEWAY].inthreeway = 0; 08193 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 08194 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 08195 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08196 /* Swap subs and dis-own channel */ 08197 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08198 p->owner = NULL; 08199 /* Ring the phone */ 08200 dahdi_ring_phone(p); 08201 } else { 08202 if ((res = attempt_transfer(p)) < 0) { 08203 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08204 if (p->subs[SUB_THREEWAY].owner) 08205 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08206 } else if (res) { 08207 /* Don't actually hang up at this point */ 08208 if (p->subs[SUB_THREEWAY].owner) 08209 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08210 break; 08211 } 08212 } 08213 } else { 08214 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08215 if (p->subs[SUB_THREEWAY].owner) 08216 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08217 } 08218 } else { 08219 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08220 /* Swap subs and dis-own channel */ 08221 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08222 p->owner = NULL; 08223 /* Ring the phone */ 08224 dahdi_ring_phone(p); 08225 } 08226 } 08227 } else { 08228 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", idx); 08229 } 08230 /* Fall through */ 08231 default: 08232 dahdi_disable_ec(p); 08233 return NULL; 08234 } 08235 break; 08236 case DAHDI_EVENT_RINGOFFHOOK: 08237 if (p->inalarm) break; 08238 if (p->oprmode < 0) 08239 { 08240 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 08241 { 08242 /* Make sure it stops ringing */ 08243 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 08244 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, -1); 08245 restore_conference(p->oprpeer); 08246 } 08247 break; 08248 } 08249 if (p->radio) 08250 { 08251 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08252 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_KEY; 08253 break; 08254 } 08255 /* for E911, its supposed to wait for offhook then dial 08256 the second half of the dial string */ 08257 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 08258 c = strchr(p->dialdest, '/'); 08259 if (c) 08260 c++; 08261 else 08262 c = p->dialdest; 08263 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 08264 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 08265 if (strlen(p->dop.dialstr) > 4) { 08266 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 08267 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 08268 p->echorest[sizeof(p->echorest) - 1] = '\0'; 08269 p->echobreak = 1; 08270 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 08271 } else 08272 p->echobreak = 0; 08273 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) { 08274 int saveerr = errno; 08275 08276 x = DAHDI_ONHOOK; 08277 ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 08278 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr)); 08279 return NULL; 08280 } 08281 p->dialing = 1; 08282 return &p->subs[idx].f; 08283 } 08284 switch (p->sig) { 08285 case SIG_FXOLS: 08286 case SIG_FXOGS: 08287 case SIG_FXOKS: 08288 switch (ast->_state) { 08289 case AST_STATE_RINGING: 08290 dahdi_enable_ec(p); 08291 dahdi_train_ec(p); 08292 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08293 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08294 /* Make sure it stops ringing */ 08295 p->subs[SUB_REAL].needringing = 0; 08296 dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 08297 ast_debug(1, "channel %d answered\n", p->channel); 08298 08299 /* Cancel any running CallerID spill */ 08300 ast_free(p->cidspill); 08301 p->cidspill = NULL; 08302 restore_conference(p); 08303 08304 p->dialing = 0; 08305 p->callwaitcas = 0; 08306 if (p->confirmanswer) { 08307 /* Ignore answer if "confirm answer" is enabled */ 08308 p->subs[idx].f.frametype = AST_FRAME_NULL; 08309 p->subs[idx].f.subclass.integer = 0; 08310 } else if (!ast_strlen_zero(p->dop.dialstr)) { 08311 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 08312 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08313 if (res < 0) { 08314 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08315 p->dop.dialstr[0] = '\0'; 08316 return NULL; 08317 } else { 08318 ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 08319 p->subs[idx].f.frametype = AST_FRAME_NULL; 08320 p->subs[idx].f.subclass.integer = 0; 08321 p->dialing = 1; 08322 } 08323 p->dop.dialstr[0] = '\0'; 08324 ast_setstate(ast, AST_STATE_DIALING); 08325 } else 08326 ast_setstate(ast, AST_STATE_UP); 08327 return &p->subs[idx].f; 08328 case AST_STATE_DOWN: 08329 ast_setstate(ast, AST_STATE_RING); 08330 ast->rings = 1; 08331 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08332 p->subs[idx].f.subclass.integer = AST_CONTROL_OFFHOOK; 08333 ast_debug(1, "channel %d picked up\n", p->channel); 08334 return &p->subs[idx].f; 08335 case AST_STATE_UP: 08336 /* Make sure it stops ringing */ 08337 dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 08338 /* Okay -- probably call waiting*/ 08339 if (ast_bridged_channel(p->owner)) 08340 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08341 p->subs[idx].needunhold = 1; 08342 break; 08343 case AST_STATE_RESERVED: 08344 /* Start up dialtone */ 08345 if (has_voicemail(p)) 08346 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER); 08347 else 08348 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE); 08349 break; 08350 default: 08351 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 08352 } 08353 break; 08354 case SIG_FXSLS: 08355 case SIG_FXSGS: 08356 case SIG_FXSKS: 08357 if (ast->_state == AST_STATE_RING) { 08358 p->ringt = p->ringt_base; 08359 } 08360 08361 /* If we get a ring then we cannot be in 08362 * reversed polarity. So we reset to idle */ 08363 ast_debug(1, "Setting IDLE polarity due " 08364 "to ring. Old polarity was %d\n", 08365 p->polarity); 08366 p->polarity = POLARITY_IDLE; 08367 08368 /* Fall through */ 08369 case SIG_EM: 08370 case SIG_EM_E1: 08371 case SIG_EMWINK: 08372 case SIG_FEATD: 08373 case SIG_FEATDMF: 08374 case SIG_FEATDMF_TA: 08375 case SIG_E911: 08376 case SIG_FGC_CAMA: 08377 case SIG_FGC_CAMAMF: 08378 case SIG_FEATB: 08379 case SIG_SF: 08380 case SIG_SFWINK: 08381 case SIG_SF_FEATD: 08382 case SIG_SF_FEATDMF: 08383 case SIG_SF_FEATB: 08384 if (ast->_state == AST_STATE_PRERING) 08385 ast_setstate(ast, AST_STATE_RING); 08386 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 08387 ast_debug(1, "Ring detected\n"); 08388 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08389 p->subs[idx].f.subclass.integer = AST_CONTROL_RING; 08390 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 08391 ast_debug(1, "Line answered\n"); 08392 if (p->confirmanswer) { 08393 p->subs[idx].f.frametype = AST_FRAME_NULL; 08394 p->subs[idx].f.subclass.integer = 0; 08395 } else { 08396 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08397 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08398 ast_setstate(ast, AST_STATE_UP); 08399 } 08400 } else if (ast->_state != AST_STATE_RING) 08401 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 08402 break; 08403 default: 08404 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 08405 } 08406 break; 08407 case DAHDI_EVENT_RINGBEGIN: 08408 switch (p->sig) { 08409 case SIG_FXSLS: 08410 case SIG_FXSGS: 08411 case SIG_FXSKS: 08412 if (ast->_state == AST_STATE_RING) { 08413 p->ringt = p->ringt_base; 08414 } 08415 break; 08416 } 08417 break; 08418 case DAHDI_EVENT_RINGERON: 08419 break; 08420 case DAHDI_EVENT_NOALARM: 08421 switch (p->sig) { 08422 #if defined(HAVE_PRI) 08423 case SIG_PRI_LIB_HANDLE_CASES: 08424 sig_pri_chan_alarm_notify(p->sig_pvt, 1); 08425 break; 08426 #endif /* defined(HAVE_PRI) */ 08427 #if defined(HAVE_SS7) 08428 case SIG_SS7: 08429 sig_ss7_set_alarm(p->sig_pvt, 0); 08430 break; 08431 #endif /* defined(HAVE_SS7) */ 08432 default: 08433 p->inalarm = 0; 08434 break; 08435 } 08436 handle_clear_alarms(p); 08437 break; 08438 case DAHDI_EVENT_WINKFLASH: 08439 if (p->inalarm) break; 08440 if (p->radio) break; 08441 if (p->oprmode < 0) break; 08442 if (p->oprmode > 1) 08443 { 08444 struct dahdi_params par; 08445 08446 memset(&par, 0, sizeof(par)); 08447 if (ioctl(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par) != -1) 08448 { 08449 if (!par.rxisoffhook) 08450 { 08451 /* Make sure it stops ringing */ 08452 dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 08453 dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RING); 08454 save_conference(p); 08455 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 08456 } 08457 } 08458 break; 08459 } 08460 /* Remember last time we got a flash-hook */ 08461 p->flashtime = ast_tvnow(); 08462 switch (mysig) { 08463 case SIG_FXOLS: 08464 case SIG_FXOGS: 08465 case SIG_FXOKS: 08466 ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 08467 idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd); 08468 08469 /* Cancel any running CallerID spill */ 08470 ast_free(p->cidspill); 08471 p->cidspill = NULL; 08472 restore_conference(p); 08473 p->callwaitcas = 0; 08474 08475 if (idx != SUB_REAL) { 08476 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", idx, p->channel); 08477 goto winkflashdone; 08478 } 08479 08480 if (p->subs[SUB_CALLWAIT].owner) { 08481 /* Swap to call-wait */ 08482 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 08483 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 08484 p->owner = p->subs[SUB_REAL].owner; 08485 ast_debug(1, "Making %s the new owner\n", p->owner->name); 08486 if (p->owner->_state == AST_STATE_RINGING) { 08487 ast_setstate(p->owner, AST_STATE_UP); 08488 p->subs[SUB_REAL].needanswer = 1; 08489 } 08490 p->callwaitingrepeat = 0; 08491 p->cidcwexpire = 0; 08492 p->cid_suppress_expire = 0; 08493 /* Start music on hold if appropriate */ 08494 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 08495 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 08496 S_OR(p->mohsuggest, NULL), 08497 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08498 } 08499 p->subs[SUB_CALLWAIT].needhold = 1; 08500 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 08501 ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD, 08502 S_OR(p->mohsuggest, NULL), 08503 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08504 } 08505 p->subs[SUB_REAL].needunhold = 1; 08506 } else if (!p->subs[SUB_THREEWAY].owner) { 08507 if (!p->threewaycalling) { 08508 /* Just send a flash if no 3-way calling */ 08509 p->subs[SUB_REAL].needflash = 1; 08510 goto winkflashdone; 08511 } else if (!check_for_conference(p)) { 08512 char cid_num[256]; 08513 char cid_name[256]; 08514 08515 cid_num[0] = 0; 08516 cid_name[0] = 0; 08517 if (p->dahditrcallerid && p->owner) { 08518 if (p->owner->caller.id.number.valid 08519 && p->owner->caller.id.number.str) { 08520 ast_copy_string(cid_num, p->owner->caller.id.number.str, 08521 sizeof(cid_num)); 08522 } 08523 if (p->owner->caller.id.name.valid 08524 && p->owner->caller.id.name.str) { 08525 ast_copy_string(cid_name, p->owner->caller.id.name.str, 08526 sizeof(cid_name)); 08527 } 08528 } 08529 /* XXX This section needs much more error checking!!! XXX */ 08530 /* Start a 3-way call if feasible */ 08531 if (!((ast->pbx) || 08532 (ast->_state == AST_STATE_UP) || 08533 (ast->_state == AST_STATE_RING))) { 08534 ast_debug(1, "Flash when call not up or ringing\n"); 08535 goto winkflashdone; 08536 } 08537 if (alloc_sub(p, SUB_THREEWAY)) { 08538 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 08539 goto winkflashdone; 08540 } 08541 08542 /* 08543 * Make new channel 08544 * 08545 * We cannot hold the p or ast locks while creating a new 08546 * channel. 08547 */ 08548 ast_mutex_unlock(&p->lock); 08549 ast_channel_unlock(ast); 08550 chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, NULL); 08551 ast_channel_lock(ast); 08552 ast_mutex_lock(&p->lock); 08553 if (p->dahditrcallerid) { 08554 if (!p->origcid_num) 08555 p->origcid_num = ast_strdup(p->cid_num); 08556 if (!p->origcid_name) 08557 p->origcid_name = ast_strdup(p->cid_name); 08558 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 08559 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 08560 } 08561 /* Swap things around between the three-way and real call */ 08562 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08563 /* Disable echo canceller for better dialing */ 08564 dahdi_disable_ec(p); 08565 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALRECALL); 08566 if (res) 08567 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 08568 p->owner = chan; 08569 if (!chan) { 08570 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 08571 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 08572 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 08573 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 08574 dahdi_enable_ec(p); 08575 ast_hangup(chan); 08576 } else { 08577 ast_verb(3, "Started three way call on channel %d\n", p->channel); 08578 08579 /* Start music on hold if appropriate */ 08580 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 08581 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 08582 S_OR(p->mohsuggest, NULL), 08583 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08584 } 08585 p->subs[SUB_THREEWAY].needhold = 1; 08586 } 08587 } 08588 } else { 08589 /* Already have a 3 way call */ 08590 if (p->subs[SUB_THREEWAY].inthreeway) { 08591 /* Call is already up, drop the last person */ 08592 ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel); 08593 /* If the primary call isn't answered yet, use it */ 08594 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 08595 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 08596 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08597 p->owner = p->subs[SUB_REAL].owner; 08598 } 08599 /* Drop the last call and stop the conference */ 08600 ast_verb(3, "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name); 08601 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08602 p->subs[SUB_REAL].inthreeway = 0; 08603 p->subs[SUB_THREEWAY].inthreeway = 0; 08604 } else { 08605 /* Lets see what we're up to */ 08606 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 08607 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 08608 int otherindex = SUB_THREEWAY; 08609 08610 ast_verb(3, "Building conference call with %s and %s\n", 08611 p->subs[SUB_THREEWAY].owner->name, 08612 p->subs[SUB_REAL].owner->name); 08613 /* Put them in the threeway, and flip */ 08614 p->subs[SUB_THREEWAY].inthreeway = 1; 08615 p->subs[SUB_REAL].inthreeway = 1; 08616 if (ast->_state == AST_STATE_UP) { 08617 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08618 otherindex = SUB_REAL; 08619 } 08620 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 08621 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 08622 p->subs[otherindex].needunhold = 1; 08623 p->owner = p->subs[SUB_REAL].owner; 08624 } else { 08625 ast_verb(3, "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name); 08626 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08627 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08628 p->owner = p->subs[SUB_REAL].owner; 08629 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 08630 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 08631 p->subs[SUB_REAL].needunhold = 1; 08632 dahdi_enable_ec(p); 08633 } 08634 } 08635 } 08636 winkflashdone: 08637 update_conf(p); 08638 break; 08639 case SIG_EM: 08640 case SIG_EM_E1: 08641 case SIG_FEATD: 08642 case SIG_SF: 08643 case SIG_SFWINK: 08644 case SIG_SF_FEATD: 08645 case SIG_FXSLS: 08646 case SIG_FXSGS: 08647 if (p->dialing) 08648 ast_debug(1, "Ignoring wink on channel %d\n", p->channel); 08649 else 08650 ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 08651 break; 08652 case SIG_FEATDMF_TA: 08653 switch (p->whichwink) { 08654 case 0: 08655 ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->caller.ani2, 08656 S_COR(p->owner->caller.ani.number.valid, 08657 p->owner->caller.ani.number.str, "")); 08658 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", 08659 p->owner->caller.ani2, 08660 S_COR(p->owner->caller.ani.number.valid, 08661 p->owner->caller.ani.number.str, "")); 08662 break; 08663 case 1: 08664 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 08665 break; 08666 case 2: 08667 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 08668 return NULL; 08669 } 08670 p->whichwink++; 08671 /* Fall through */ 08672 case SIG_FEATDMF: 08673 case SIG_E911: 08674 case SIG_FGC_CAMAMF: 08675 case SIG_FGC_CAMA: 08676 case SIG_FEATB: 08677 case SIG_SF_FEATDMF: 08678 case SIG_SF_FEATB: 08679 case SIG_EMWINK: 08680 /* FGD MF and EMWINK *Must* wait for wink */ 08681 if (!ast_strlen_zero(p->dop.dialstr)) { 08682 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08683 if (res < 0) { 08684 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08685 p->dop.dialstr[0] = '\0'; 08686 return NULL; 08687 } else 08688 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr); 08689 } 08690 p->dop.dialstr[0] = '\0'; 08691 break; 08692 default: 08693 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 08694 } 08695 break; 08696 case DAHDI_EVENT_HOOKCOMPLETE: 08697 if (p->inalarm) break; 08698 if ((p->radio || (p->oprmode < 0))) break; 08699 if (p->waitingfordt.tv_sec) break; 08700 switch (mysig) { 08701 case SIG_FXSLS: /* only interesting for FXS */ 08702 case SIG_FXSGS: 08703 case SIG_FXSKS: 08704 case SIG_EM: 08705 case SIG_EM_E1: 08706 case SIG_EMWINK: 08707 case SIG_FEATD: 08708 case SIG_SF: 08709 case SIG_SFWINK: 08710 case SIG_SF_FEATD: 08711 if (!ast_strlen_zero(p->dop.dialstr)) { 08712 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08713 if (res < 0) { 08714 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08715 p->dop.dialstr[0] = '\0'; 08716 return NULL; 08717 } else 08718 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr); 08719 } 08720 p->dop.dialstr[0] = '\0'; 08721 p->dop.op = DAHDI_DIAL_OP_REPLACE; 08722 break; 08723 case SIG_FEATDMF: 08724 case SIG_FEATDMF_TA: 08725 case SIG_E911: 08726 case SIG_FGC_CAMA: 08727 case SIG_FGC_CAMAMF: 08728 case SIG_FEATB: 08729 case SIG_SF_FEATDMF: 08730 case SIG_SF_FEATB: 08731 ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 08732 break; 08733 default: 08734 break; 08735 } 08736 break; 08737 case DAHDI_EVENT_POLARITY: 08738 /* 08739 * If we get a Polarity Switch event, check to see 08740 * if we should change the polarity state and 08741 * mark the channel as UP or if this is an indication 08742 * of remote end disconnect. 08743 */ 08744 if (p->polarity == POLARITY_IDLE) { 08745 p->polarity = POLARITY_REV; 08746 if (p->answeronpolarityswitch && 08747 ((ast->_state == AST_STATE_DIALING) || 08748 (ast->_state == AST_STATE_RINGING))) { 08749 ast_debug(1, "Answering on polarity switch!\n"); 08750 ast_setstate(p->owner, AST_STATE_UP); 08751 if (p->hanguponpolarityswitch) { 08752 p->polaritydelaytv = ast_tvnow(); 08753 } 08754 } else 08755 ast_debug(1, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 08756 } 08757 /* Removed else statement from here as it was preventing hangups from ever happening*/ 08758 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 08759 if (p->hanguponpolarityswitch && 08760 (p->polarityonanswerdelay > 0) && 08761 (p->polarity == POLARITY_REV) && 08762 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 08763 /* Added log_debug information below to provide a better indication of what is going on */ 08764 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) ); 08765 08766 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 08767 ast_debug(1, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 08768 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 08769 p->polarity = POLARITY_IDLE; 08770 } else 08771 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); 08772 08773 } else { 08774 p->polarity = POLARITY_IDLE; 08775 ast_debug(1, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 08776 } 08777 /* Added more log_debug information below to provide a better indication of what is going on */ 08778 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) ); 08779 break; 08780 default: 08781 ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel); 08782 } 08783 return &p->subs[idx].f; 08784 }
static int dahdi_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 6160 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.
06161 { 06162 int res = 0; 06163 int idx,x; 06164 int law; 06165 /*static int restore_gains(struct dahdi_pvt *p);*/ 06166 struct dahdi_pvt *p = ast->tech_pvt; 06167 struct dahdi_params par; 06168 06169 ast_debug(1, "dahdi_hangup(%s)\n", ast->name); 06170 if (!ast->tech_pvt) { 06171 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 06172 return 0; 06173 } 06174 06175 ast_mutex_lock(&p->lock); 06176 p->exten[0] = '\0'; 06177 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 06178 dahdi_confmute(p, 0); 06179 restore_gains(p); 06180 p->ignoredtmf = 0; 06181 p->waitingfordt.tv_sec = 0; 06182 06183 res = analog_hangup(p->sig_pvt, ast); 06184 revert_fax_buffers(p, ast); 06185 06186 goto hangup_out; 06187 } else { 06188 p->cid_num[0] = '\0'; 06189 p->cid_name[0] = '\0'; 06190 p->cid_subaddr[0] = '\0'; 06191 } 06192 06193 #if defined(HAVE_PRI) 06194 if (dahdi_sig_pri_lib_handles(p->sig)) { 06195 x = 1; 06196 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06197 06198 dahdi_confmute(p, 0); 06199 p->muting = 0; 06200 restore_gains(p); 06201 if (p->dsp) { 06202 ast_dsp_free(p->dsp); 06203 p->dsp = NULL; 06204 } 06205 p->ignoredtmf = 0; 06206 06207 /* Real channel, do some fixup */ 06208 p->subs[SUB_REAL].owner = NULL; 06209 p->subs[SUB_REAL].needbusy = 0; 06210 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 06211 06212 p->owner = NULL; 06213 p->cid_tag[0] = '\0'; 06214 p->ringt = 0;/* Probably not used in this mode. Reset anyway. */ 06215 p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */ 06216 p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */ 06217 p->outgoing = 0; 06218 p->digital = 0; 06219 p->faxhandled = 0; 06220 p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */ 06221 06222 revert_fax_buffers(p, ast); 06223 06224 p->law = p->law_default; 06225 law = p->law_default; 06226 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06227 if (res < 0) { 06228 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", 06229 p->channel, strerror(errno)); 06230 } 06231 06232 sig_pri_hangup(p->sig_pvt, ast); 06233 06234 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06235 dahdi_disable_ec(p); 06236 06237 x = 0; 06238 ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0); 06239 p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */ 06240 06241 p->rdnis[0] = '\0'; 06242 update_conf(p); 06243 reset_conf(p); 06244 06245 /* Restore data mode */ 06246 x = 0; 06247 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06248 06249 if (num_restart_pending == 0) { 06250 restart_monitor(); 06251 } 06252 goto hangup_out; 06253 } 06254 #endif /* defined(HAVE_PRI) */ 06255 06256 #if defined(HAVE_SS7) 06257 if (p->sig == SIG_SS7) { 06258 x = 1; 06259 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06260 06261 dahdi_confmute(p, 0); 06262 p->muting = 0; 06263 restore_gains(p); 06264 if (p->dsp) { 06265 ast_dsp_free(p->dsp); 06266 p->dsp = NULL; 06267 } 06268 p->ignoredtmf = 0; 06269 06270 /* Real channel, do some fixup */ 06271 p->subs[SUB_REAL].owner = NULL; 06272 p->subs[SUB_REAL].needbusy = 0; 06273 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 06274 06275 p->owner = NULL; 06276 p->ringt = 0;/* Probably not used in this mode. Reset anyway. */ 06277 p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */ 06278 p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */ 06279 p->outgoing = 0; 06280 p->digital = 0; 06281 p->faxhandled = 0; 06282 p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */ 06283 06284 revert_fax_buffers(p, ast); 06285 06286 p->law = p->law_default; 06287 law = p->law_default; 06288 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06289 if (res < 0) { 06290 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", 06291 p->channel, strerror(errno)); 06292 } 06293 06294 sig_ss7_hangup(p->sig_pvt, ast); 06295 06296 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06297 dahdi_disable_ec(p); 06298 06299 x = 0; 06300 ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0); 06301 p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */ 06302 06303 update_conf(p); 06304 reset_conf(p); 06305 06306 /* Restore data mode */ 06307 x = 0; 06308 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06309 06310 if (num_restart_pending == 0) { 06311 restart_monitor(); 06312 } 06313 goto hangup_out; 06314 } 06315 #endif /* defined(HAVE_SS7) */ 06316 06317 idx = dahdi_get_index(ast, p, 1); 06318 06319 dahdi_confmute(p, 0); 06320 p->muting = 0; 06321 restore_gains(p); 06322 if (p->origcid_num) { 06323 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 06324 ast_free(p->origcid_num); 06325 p->origcid_num = NULL; 06326 } 06327 if (p->origcid_name) { 06328 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 06329 ast_free(p->origcid_name); 06330 p->origcid_name = NULL; 06331 } 06332 if (p->dsp) 06333 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 06334 06335 ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 06336 p->channel, idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd); 06337 p->ignoredtmf = 0; 06338 06339 if (idx > -1) { 06340 /* Real channel, do some fixup */ 06341 p->subs[idx].owner = NULL; 06342 p->subs[idx].needanswer = 0; 06343 p->subs[idx].needflash = 0; 06344 p->subs[idx].needringing = 0; 06345 p->subs[idx].needbusy = 0; 06346 p->subs[idx].needcongestion = 0; 06347 p->subs[idx].linear = 0; 06348 p->polarity = POLARITY_IDLE; 06349 dahdi_setlinear(p->subs[idx].dfd, 0); 06350 if (idx == SUB_REAL) { 06351 if ((p->subs[SUB_CALLWAIT].dfd > -1) && (p->subs[SUB_THREEWAY].dfd > -1)) { 06352 ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n"); 06353 if (p->subs[SUB_CALLWAIT].inthreeway) { 06354 /* We had flipped over to answer a callwait and now it's gone */ 06355 ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n"); 06356 /* Move to the call-wait, but un-own us until they flip back. */ 06357 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 06358 unalloc_sub(p, SUB_CALLWAIT); 06359 p->owner = NULL; 06360 } else { 06361 /* The three way hung up, but we still have a call wait */ 06362 ast_debug(1, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 06363 swap_subs(p, SUB_THREEWAY, SUB_REAL); 06364 unalloc_sub(p, SUB_THREEWAY); 06365 if (p->subs[SUB_REAL].inthreeway) { 06366 /* This was part of a three way call. Immediately make way for 06367 another call */ 06368 ast_debug(1, "Call was complete, setting owner to former third call\n"); 06369 p->owner = p->subs[SUB_REAL].owner; 06370 } else { 06371 /* This call hasn't been completed yet... Set owner to NULL */ 06372 ast_debug(1, "Call was incomplete, setting owner to NULL\n"); 06373 p->owner = NULL; 06374 } 06375 p->subs[SUB_REAL].inthreeway = 0; 06376 } 06377 } else if (p->subs[SUB_CALLWAIT].dfd > -1) { 06378 /* Move to the call-wait and switch back to them. */ 06379 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 06380 unalloc_sub(p, SUB_CALLWAIT); 06381 p->owner = p->subs[SUB_REAL].owner; 06382 if (p->owner->_state != AST_STATE_UP) 06383 p->subs[SUB_REAL].needanswer = 1; 06384 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 06385 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 06386 } else if (p->subs[SUB_THREEWAY].dfd > -1) { 06387 swap_subs(p, SUB_THREEWAY, SUB_REAL); 06388 unalloc_sub(p, SUB_THREEWAY); 06389 if (p->subs[SUB_REAL].inthreeway) { 06390 /* This was part of a three way call. Immediately make way for 06391 another call */ 06392 ast_debug(1, "Call was complete, setting owner to former third call\n"); 06393 p->owner = p->subs[SUB_REAL].owner; 06394 } else { 06395 /* This call hasn't been completed yet... Set owner to NULL */ 06396 ast_debug(1, "Call was incomplete, setting owner to NULL\n"); 06397 p->owner = NULL; 06398 } 06399 p->subs[SUB_REAL].inthreeway = 0; 06400 } 06401 } else if (idx == SUB_CALLWAIT) { 06402 /* Ditch the holding callwait call, and immediately make it availabe */ 06403 if (p->subs[SUB_CALLWAIT].inthreeway) { 06404 /* This is actually part of a three way, placed on hold. Place the third part 06405 on music on hold now */ 06406 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 06407 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 06408 S_OR(p->mohsuggest, NULL), 06409 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 06410 } 06411 p->subs[SUB_THREEWAY].inthreeway = 0; 06412 /* Make it the call wait now */ 06413 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 06414 unalloc_sub(p, SUB_THREEWAY); 06415 } else 06416 unalloc_sub(p, SUB_CALLWAIT); 06417 } else if (idx == SUB_THREEWAY) { 06418 if (p->subs[SUB_CALLWAIT].inthreeway) { 06419 /* The other party of the three way call is currently in a call-wait state. 06420 Start music on hold for them, and take the main guy out of the third call */ 06421 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 06422 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 06423 S_OR(p->mohsuggest, NULL), 06424 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 06425 } 06426 p->subs[SUB_CALLWAIT].inthreeway = 0; 06427 } 06428 p->subs[SUB_REAL].inthreeway = 0; 06429 /* If this was part of a three way call index, let us make 06430 another three way call */ 06431 unalloc_sub(p, SUB_THREEWAY); 06432 } else { 06433 /* This wasn't any sort of call, but how are we an index? */ 06434 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 06435 } 06436 } 06437 06438 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 06439 p->owner = NULL; 06440 p->ringt = 0; 06441 p->distinctivering = 0; 06442 p->confirmanswer = 0; 06443 p->outgoing = 0; 06444 p->digital = 0; 06445 p->faxhandled = 0; 06446 p->pulsedial = 0; 06447 if (p->dsp) { 06448 ast_dsp_free(p->dsp); 06449 p->dsp = NULL; 06450 } 06451 06452 revert_fax_buffers(p, ast); 06453 06454 p->law = p->law_default; 06455 law = p->law_default; 06456 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06457 if (res < 0) 06458 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno)); 06459 /* Perform low level hangup if no owner left */ 06460 #ifdef HAVE_OPENR2 06461 if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) { 06462 ast_log(LOG_DEBUG, "disconnecting MFC/R2 call on chan %d\n", p->channel); 06463 /* If it's an incoming call, check the mfcr2_forced_release setting */ 06464 if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) { 06465 dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE); 06466 } else { 06467 const char *r2causestr = pbx_builtin_getvar_helper(ast, "MFCR2_CAUSE"); 06468 int r2cause_user = r2causestr ? atoi(r2causestr) : 0; 06469 openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user) 06470 : dahdi_ast_cause_to_r2_cause(ast->hangupcause); 06471 dahdi_r2_disconnect_call(p, r2cause); 06472 } 06473 } else if (p->mfcr2call) { 06474 ast_log(LOG_DEBUG, "Clearing call request on channel %d\n", p->channel); 06475 /* since ast_request() was called but not ast_call() we have not yet dialed 06476 and the openr2 stack will not call on_call_end callback, we need to unset 06477 the mfcr2call flag and bump the monitor count so the monitor thread can take 06478 care of this channel events from now on */ 06479 p->mfcr2call = 0; 06480 } 06481 #endif 06482 switch (p->sig) { 06483 case SIG_SS7: 06484 case SIG_MFCR2: 06485 case SIG_PRI_LIB_HANDLE_CASES: 06486 case 0: 06487 break; 06488 default: 06489 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 06490 break; 06491 } 06492 if (res < 0) { 06493 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 06494 } 06495 switch (p->sig) { 06496 case SIG_FXOGS: 06497 case SIG_FXOLS: 06498 case SIG_FXOKS: 06499 memset(&par, 0, sizeof(par)); 06500 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par); 06501 if (!res) { 06502 struct analog_pvt *analog_p = p->sig_pvt; 06503 #if 0 06504 ast_debug(1, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 06505 #endif 06506 /* If they're off hook, try playing congestion */ 06507 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0)))) 06508 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 06509 else 06510 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06511 analog_p->fxsoffhookstate = par.rxisoffhook; 06512 } 06513 break; 06514 case SIG_FXSGS: 06515 case SIG_FXSLS: 06516 case SIG_FXSKS: 06517 /* Make sure we're not made available for at least two seconds assuming 06518 we were actually used for an inbound or outbound call. */ 06519 if (ast->_state != AST_STATE_RESERVED) { 06520 time(&p->guardtime); 06521 p->guardtime += 2; 06522 } 06523 break; 06524 default: 06525 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06526 break; 06527 } 06528 if (p->sig) 06529 dahdi_disable_ec(p); 06530 x = 0; 06531 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 06532 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 06533 p->didtdd = 0; 06534 p->callwaitcas = 0; 06535 p->callwaiting = p->permcallwaiting; 06536 p->hidecallerid = p->permhidecallerid; 06537 p->waitingfordt.tv_sec = 0; 06538 p->dialing = 0; 06539 p->rdnis[0] = '\0'; 06540 update_conf(p); 06541 reset_conf(p); 06542 /* Restore data mode */ 06543 switch (p->sig) { 06544 case SIG_PRI_LIB_HANDLE_CASES: 06545 case SIG_SS7: 06546 x = 0; 06547 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 06548 break; 06549 default: 06550 break; 06551 } 06552 if (num_restart_pending == 0) 06553 restart_monitor(); 06554 } 06555 06556 p->callwaitingrepeat = 0; 06557 p->cidcwexpire = 0; 06558 p->cid_suppress_expire = 0; 06559 p->oprmode = 0; 06560 hangup_out: 06561 ast->tech_pvt = NULL; 06562 ast_free(p->cidspill); 06563 p->cidspill = NULL; 06564 06565 ast_mutex_unlock(&p->lock); 06566 ast_verb(3, "Hungup '%s'\n", ast->name); 06567 06568 ast_mutex_lock(&iflock); 06569 if (p->restartpending) { 06570 num_restart_pending--; 06571 } 06572 06573 if (p->destroy) { 06574 destroy_channel(p, 0); 06575 } 06576 ast_mutex_unlock(&iflock); 06577 06578 ast_module_unref(ast_module_info->self); 06579 return 0; 06580 }
static void dahdi_iflist_extract | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5554 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().
05555 { 05556 /* Extract from the forward chain. */ 05557 if (pvt->prev) { 05558 pvt->prev->next = pvt->next; 05559 } else if (iflist == pvt) { 05560 /* Node is at the head of the list. */ 05561 iflist = pvt->next; 05562 } 05563 05564 /* Extract from the reverse chain. */ 05565 if (pvt->next) { 05566 pvt->next->prev = pvt->prev; 05567 } else if (ifend == pvt) { 05568 /* Node is at the end of the list. */ 05569 ifend = pvt->prev; 05570 } 05571 05572 /* Node is no longer in the list. */ 05573 pvt->which_iflist = DAHDI_IFLIST_NONE; 05574 pvt->prev = NULL; 05575 pvt->next = NULL; 05576 }
static void dahdi_iflist_insert | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5504 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().
05505 { 05506 struct dahdi_pvt *cur; 05507 05508 pvt->which_iflist = DAHDI_IFLIST_MAIN; 05509 05510 /* Find place in middle of list for the new interface. */ 05511 for (cur = iflist; cur; cur = cur->next) { 05512 if (pvt->channel < cur->channel) { 05513 /* New interface goes before the current interface. */ 05514 pvt->prev = cur->prev; 05515 pvt->next = cur; 05516 if (cur->prev) { 05517 /* Insert into the middle of the list. */ 05518 cur->prev->next = pvt; 05519 } else { 05520 /* Insert at head of list. */ 05521 iflist = pvt; 05522 } 05523 cur->prev = pvt; 05524 return; 05525 } 05526 } 05527 05528 /* New interface goes onto the end of the list */ 05529 pvt->prev = ifend; 05530 pvt->next = NULL; 05531 if (ifend) { 05532 ifend->next = pvt; 05533 } 05534 ifend = pvt; 05535 if (!iflist) { 05536 /* List was empty */ 05537 iflist = pvt; 05538 } 05539 }
static int dahdi_indicate | ( | struct ast_channel * | chan, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 9437 of file chan_dahdi.c.
References ast_channel::_state, AST_CAUSE_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_USER_BUSY, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, 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.
09438 { 09439 struct dahdi_pvt *p = chan->tech_pvt; 09440 int res=-1; 09441 int idx; 09442 int func = DAHDI_FLASH; 09443 09444 ast_mutex_lock(&p->lock); 09445 ast_debug(1, "Requested indication %d on channel %s\n", condition, chan->name); 09446 switch (p->sig) { 09447 #if defined(HAVE_PRI) 09448 case SIG_PRI_LIB_HANDLE_CASES: 09449 res = sig_pri_indicate(p->sig_pvt, chan, condition, data, datalen); 09450 ast_mutex_unlock(&p->lock); 09451 return res; 09452 #endif /* defined(HAVE_PRI) */ 09453 #if defined(HAVE_SS7) 09454 case SIG_SS7: 09455 res = sig_ss7_indicate(p->sig_pvt, chan, condition, data, datalen); 09456 ast_mutex_unlock(&p->lock); 09457 return res; 09458 #endif /* defined(HAVE_SS7) */ 09459 default: 09460 break; 09461 } 09462 #ifdef HAVE_OPENR2 09463 if (p->mfcr2 && !p->mfcr2_call_accepted) { 09464 ast_mutex_unlock(&p->lock); 09465 /* if this is an R2 call and the call is not yet accepted, we don't want the 09466 tone indications to mess up with the MF tones */ 09467 return 0; 09468 } 09469 #endif 09470 idx = dahdi_get_index(chan, p, 0); 09471 if (idx == SUB_REAL) { 09472 switch (condition) { 09473 case AST_CONTROL_BUSY: 09474 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_BUSY); 09475 break; 09476 case AST_CONTROL_RINGING: 09477 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_RINGTONE); 09478 09479 if (chan->_state != AST_STATE_UP) { 09480 if ((chan->_state != AST_STATE_RING) || 09481 ((p->sig != SIG_FXSKS) && 09482 (p->sig != SIG_FXSLS) && 09483 (p->sig != SIG_FXSGS))) 09484 ast_setstate(chan, AST_STATE_RINGING); 09485 } 09486 break; 09487 case AST_CONTROL_INCOMPLETE: 09488 ast_debug(1, "Received AST_CONTROL_INCOMPLETE on %s\n", chan->name); 09489 /* act as a progress or proceeding, allowing the caller to enter additional numbers */ 09490 res = 0; 09491 break; 09492 case AST_CONTROL_PROCEEDING: 09493 ast_debug(1, "Received AST_CONTROL_PROCEEDING on %s\n", chan->name); 09494 /* don't continue in ast_indicate */ 09495 res = 0; 09496 break; 09497 case AST_CONTROL_PROGRESS: 09498 ast_debug(1, "Received AST_CONTROL_PROGRESS on %s\n", chan->name); 09499 /* don't continue in ast_indicate */ 09500 res = 0; 09501 break; 09502 case AST_CONTROL_CONGESTION: 09503 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */ 09504 switch (chan->hangupcause) { 09505 case AST_CAUSE_USER_BUSY: 09506 case AST_CAUSE_NORMAL_CLEARING: 09507 case 0:/* Cause has not been set. */ 09508 /* Supply a more appropriate cause. */ 09509 chan->hangupcause = AST_CAUSE_CONGESTION; 09510 break; 09511 default: 09512 break; 09513 } 09514 break; 09515 case AST_CONTROL_HOLD: 09516 ast_moh_start(chan, data, p->mohinterpret); 09517 break; 09518 case AST_CONTROL_UNHOLD: 09519 ast_moh_stop(chan); 09520 break; 09521 case AST_CONTROL_RADIO_KEY: 09522 if (p->radio) 09523 res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 09524 res = 0; 09525 break; 09526 case AST_CONTROL_RADIO_UNKEY: 09527 if (p->radio) 09528 res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_RINGOFF); 09529 res = 0; 09530 break; 09531 case AST_CONTROL_FLASH: 09532 /* flash hookswitch */ 09533 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 09534 /* Clear out the dial buffer */ 09535 p->dop.dialstr[0] = '\0'; 09536 if ((ioctl(p->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 09537 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 09538 chan->name, strerror(errno)); 09539 } else 09540 res = 0; 09541 } else 09542 res = 0; 09543 break; 09544 case AST_CONTROL_SRCUPDATE: 09545 res = 0; 09546 break; 09547 case -1: 09548 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 09549 break; 09550 } 09551 } else { 09552 res = 0; 09553 } 09554 ast_mutex_unlock(&p->lock); 09555 return res; 09556 }
Definition at line 7206 of file chan_dahdi.c.
References ast_log(), LOG_WARNING, and dahdi_pvt::slaves.
Referenced by dahdi_bridge().
07206 { 07207 int x; 07208 if (!slave || !master) { 07209 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 07210 return; 07211 } 07212 for (x = 0; x < MAX_SLAVES; x++) { 07213 if (!master->slaves[x]) { 07214 master->slaves[x] = slave; 07215 break; 07216 } 07217 } 07218 if (x >= MAX_SLAVES) { 07219 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 07220 master->slaves[MAX_SLAVES - 1] = slave; 07221 } 07222 if (slave->master) 07223 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 07224 slave->master = master; 07225 07226 ast_debug(1, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 07227 }
static void dahdi_lock_sub_owner | ( | struct dahdi_pvt * | pvt, | |
int | sub_idx | |||
) | [static] |
Definition at line 3775 of file chan_dahdi.c.
References ast_channel_trylock, dahdi_subchannel::owner, and dahdi_pvt::subs.
Referenced by wakeup_sub().
03776 { 03777 for (;;) { 03778 if (!pvt->subs[sub_idx].owner) { 03779 /* No subchannel owner pointer */ 03780 break; 03781 } 03782 if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) { 03783 /* Got subchannel owner lock */ 03784 break; 03785 } 03786 /* We must unlock the private to avoid the possibility of a deadlock */ 03787 DEADLOCK_AVOIDANCE(&pvt->lock); 03788 } 03789 }
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 9606 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_NAME, ast_channel_set_fd(), ast_copy_string(), ast_debug, AST_DEVICE_UNKNOWN, 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_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_ami_channel_event(), 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(), and register_translator().
09607 { 09608 struct ast_channel *tmp; 09609 format_t deflaw; 09610 int x; 09611 int features; 09612 struct ast_str *chan_name; 09613 struct ast_variable *v; 09614 char *dashptr; 09615 char device_name[AST_CHANNEL_NAME]; 09616 09617 if (i->subs[idx].owner) { 09618 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[idx]); 09619 return NULL; 09620 } 09621 09622 #if defined(HAVE_PRI) 09623 /* 09624 * The dnid has been stuffed with the called-number[:subaddress] 09625 * by dahdi_request() for outgoing calls. 09626 */ 09627 chan_name = create_channel_name(i, i->outgoing, i->dnid); 09628 #else 09629 chan_name = create_channel_name(i); 09630 #endif /* defined(HAVE_PRI) */ 09631 if (!chan_name) { 09632 return NULL; 09633 } 09634 09635 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)); 09636 ast_free(chan_name); 09637 if (!tmp) 09638 return NULL; 09639 tmp->tech = &dahdi_tech; 09640 #if defined(HAVE_PRI) 09641 if (i->pri) { 09642 ast_cc_copy_config_params(i->cc_params, i->pri->cc_params); 09643 } 09644 #endif /* defined(HAVE_PRI) */ 09645 ast_channel_cc_params_init(tmp, i->cc_params); 09646 if (law) { 09647 i->law = law; 09648 if (law == DAHDI_LAW_ALAW) { 09649 deflaw = AST_FORMAT_ALAW; 09650 } else { 09651 deflaw = AST_FORMAT_ULAW; 09652 } 09653 } else { 09654 switch (i->sig) { 09655 case SIG_PRI_LIB_HANDLE_CASES: 09656 /* Make sure companding law is known. */ 09657 i->law = (i->law_default == DAHDI_LAW_ALAW) 09658 ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW; 09659 break; 09660 default: 09661 i->law = i->law_default; 09662 break; 09663 } 09664 if (i->law_default == DAHDI_LAW_ALAW) { 09665 deflaw = AST_FORMAT_ALAW; 09666 } else { 09667 deflaw = AST_FORMAT_ULAW; 09668 } 09669 } 09670 ast_channel_set_fd(tmp, 0, i->subs[idx].dfd); 09671 tmp->nativeformats = deflaw; 09672 /* Start out assuming ulaw since it's smaller :) */ 09673 tmp->rawreadformat = deflaw; 09674 tmp->readformat = deflaw; 09675 tmp->rawwriteformat = deflaw; 09676 tmp->writeformat = deflaw; 09677 i->subs[idx].linear = 0; 09678 dahdi_setlinear(i->subs[idx].dfd, i->subs[idx].linear); 09679 features = 0; 09680 if (idx == SUB_REAL) { 09681 if (i->busydetect && CANBUSYDETECT(i)) 09682 features |= DSP_FEATURE_BUSY_DETECT; 09683 if ((i->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(i)) 09684 features |= DSP_FEATURE_CALL_PROGRESS; 09685 if ((i->waitfordialtone) && CANPROGRESSDETECT(i)) 09686 features |= DSP_FEATURE_WAITDIALTONE; 09687 if ((!i->outgoing && (i->callprogress & CALLPROGRESS_FAX_INCOMING)) || 09688 (i->outgoing && (i->callprogress & CALLPROGRESS_FAX_OUTGOING))) { 09689 features |= DSP_FEATURE_FAX_DETECT; 09690 } 09691 x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE; 09692 if (ioctl(i->subs[idx].dfd, DAHDI_TONEDETECT, &x)) { 09693 i->hardwaredtmf = 0; 09694 features |= DSP_FEATURE_DIGIT_DETECT; 09695 } else if (NEED_MFDETECT(i)) { 09696 i->hardwaredtmf = 1; 09697 features |= DSP_FEATURE_DIGIT_DETECT; 09698 } 09699 } 09700 if (features) { 09701 if (i->dsp) { 09702 ast_debug(1, "Already have a dsp on %s?\n", tmp->name); 09703 } else { 09704 if (i->channel != CHAN_PSEUDO) 09705 i->dsp = ast_dsp_new(); 09706 else 09707 i->dsp = NULL; 09708 if (i->dsp) { 09709 i->dsp_features = features; 09710 #if defined(HAVE_PRI) || defined(HAVE_SS7) 09711 /* We cannot do progress detection until receive PROGRESS message */ 09712 if (i->outgoing && (dahdi_sig_pri_lib_handles(i->sig) || (i->sig == SIG_SS7))) { 09713 /* Remember requested DSP features, don't treat 09714 talking as ANSWER */ 09715 i->dsp_features = features & ~DSP_PROGRESS_TALK; 09716 features = 0; 09717 } 09718 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 09719 ast_dsp_set_features(i->dsp, features); 09720 ast_dsp_set_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 09721 if (!ast_strlen_zero(progzone)) 09722 ast_dsp_set_call_progress_zone(i->dsp, progzone); 09723 if (i->busydetect && CANBUSYDETECT(i)) { 09724 if(i->silencethreshold > 0) 09725 ast_dsp_set_threshold(i->dsp, i->silencethreshold); 09726 ast_dsp_set_busy_count(i->dsp, i->busycount); 09727 if(i->busytonelength > 0) 09728 ast_dsp_set_busy_pattern(i->dsp, i->busytonelength, i->busyquietlength, i->busyfuzziness); 09729 if((i->busytonelength == i->busyquietlength) && i->busycompare) 09730 ast_dsp_set_busy_compare(i->dsp, i->busycompare); 09731 } 09732 } 09733 } 09734 } 09735 09736 if (state == AST_STATE_RING) 09737 tmp->rings = 1; 09738 tmp->tech_pvt = i; 09739 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 09740 /* Only FXO signalled stuff can be picked up */ 09741 tmp->callgroup = i->callgroup; 09742 tmp->pickupgroup = i->pickupgroup; 09743 } 09744 if (!ast_strlen_zero(i->parkinglot)) 09745 ast_string_field_set(tmp, parkinglot, i->parkinglot); 09746 if (!ast_strlen_zero(i->language)) 09747 ast_string_field_set(tmp, language, i->language); 09748 if (!i->owner) 09749 i->owner = tmp; 09750 if (!ast_strlen_zero(i->accountcode)) 09751 ast_string_field_set(tmp, accountcode, i->accountcode); 09752 if (i->amaflags) 09753 tmp->amaflags = i->amaflags; 09754 i->subs[idx].owner = tmp; 09755 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 09756 if (!analog_lib_handles(i->sig, i->radio, i->oprmode)) { 09757 ast_string_field_set(tmp, call_forward, i->call_forward); 09758 } 09759 /* If we've been told "no ADSI" then enforce it */ 09760 if (!i->adsi) 09761 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 09762 if (!ast_strlen_zero(i->exten)) 09763 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 09764 if (!ast_strlen_zero(i->rdnis)) { 09765 tmp->redirecting.from.number.valid = 1; 09766 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 09767 } 09768 if (!ast_strlen_zero(i->dnid)) { 09769 tmp->dialed.number.str = ast_strdup(i->dnid); 09770 } 09771 09772 /* Don't use ast_set_callerid() here because it will 09773 * generate a needless NewCallerID event */ 09774 #if defined(HAVE_PRI) || defined(HAVE_SS7) 09775 if (!ast_strlen_zero(i->cid_ani)) { 09776 tmp->caller.ani.number.valid = 1; 09777 tmp->caller.ani.number.str = ast_strdup(i->cid_ani); 09778 } else if (!ast_strlen_zero(i->cid_num)) { 09779 tmp->caller.ani.number.valid = 1; 09780 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 09781 } 09782 #else 09783 if (!ast_strlen_zero(i->cid_num)) { 09784 tmp->caller.ani.number.valid = 1; 09785 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 09786 } 09787 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 09788 tmp->caller.id.name.presentation = i->callingpres; 09789 tmp->caller.id.number.presentation = i->callingpres; 09790 tmp->caller.id.number.plan = i->cid_ton; 09791 tmp->caller.ani2 = i->cid_ani2; 09792 tmp->caller.id.tag = ast_strdup(i->cid_tag); 09793 /* clear the fake event in case we posted one before we had ast_channel */ 09794 i->fake_event = 0; 09795 /* Assure there is no confmute on this channel */ 09796 dahdi_confmute(i, 0); 09797 i->muting = 0; 09798 /* Configure the new channel jb */ 09799 ast_jb_configure(tmp, &global_jbconf); 09800 09801 /* Set initial device state */ 09802 ast_copy_string(device_name, tmp->name, sizeof(device_name)); 09803 dashptr = strrchr(device_name, '-'); 09804 if (dashptr) { 09805 *dashptr = '\0'; 09806 } 09807 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name); 09808 09809 for (v = i->vars ; v ; v = v->next) 09810 pbx_builtin_setvar_helper(tmp, v->name, v->value); 09811 09812 ast_module_ref(ast_module_info->self); 09813 09814 dahdi_ami_channel_event(i, tmp); 09815 if (startpbx) { 09816 #ifdef HAVE_OPENR2 09817 if (i->mfcr2call) { 09818 pbx_builtin_setvar_helper(tmp, "MFCR2_CATEGORY", openr2_proto_get_category_string(i->mfcr2_recvd_category)); 09819 } 09820 #endif 09821 if (ast_pbx_start(tmp)) { 09822 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 09823 ast_hangup(tmp); 09824 return NULL; 09825 } 09826 } 09827 return tmp; 09828 }
static int dahdi_new_pri_nobch_channel | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 13312 of file chan_dahdi.c.
References CHAN_PSEUDO, sig_pri_span::numchans, and sig_pri_span::pvts.
13313 { 13314 int pvt_idx; 13315 int res; 13316 unsigned idx; 13317 struct dahdi_pvt *pvt; 13318 struct sig_pri_chan *chan; 13319 struct dahdi_bufferinfo bi; 13320 13321 static int nobch_channel = CHAN_PSEUDO; 13322 13323 /* Find spot in the private pointer array for new interface. */ 13324 for (pvt_idx = 0; pvt_idx < pri->numchans; ++pvt_idx) { 13325 if (!pri->pvts[pvt_idx]) { 13326 break; 13327 } 13328 } 13329 if (pri->numchans == pvt_idx) { 13330 if (ARRAY_LEN(pri->pvts) <= pvt_idx) { 13331 ast_log(LOG_ERROR, "Unable to add a no-B-channel interface!\n"); 13332 return -1; 13333 } 13334 13335 /* Add new spot to the private pointer array. */ 13336 pri->pvts[pvt_idx] = NULL; 13337 ++pri->numchans; 13338 } 13339 13340 pvt = ast_calloc(1, sizeof(*pvt)); 13341 if (!pvt) { 13342 return -1; 13343 } 13344 pvt->cc_params = ast_cc_config_params_init(); 13345 if (!pvt->cc_params) { 13346 ast_free(pvt); 13347 return -1; 13348 } 13349 ast_mutex_init(&pvt->lock); 13350 for (idx = 0; idx < ARRAY_LEN(pvt->subs); ++idx) { 13351 pvt->subs[idx].dfd = -1; 13352 } 13353 pvt->buf_no = dahdi_pseudo_parms.buf_no; 13354 pvt->buf_policy = dahdi_pseudo_parms.buf_policy; 13355 pvt->faxbuf_no = dahdi_pseudo_parms.faxbuf_no; 13356 pvt->faxbuf_policy = dahdi_pseudo_parms.faxbuf_policy; 13357 13358 chan = sig_pri_chan_new(pvt, &dahdi_pri_callbacks, pri, 0, 0, 0); 13359 if (!chan) { 13360 destroy_dahdi_pvt(pvt); 13361 return -1; 13362 } 13363 chan->no_b_channel = 1; 13364 13365 /* 13366 * Pseudo channel companding law. 13367 * Needed for outgoing call waiting calls. 13368 * XXX May need to make this determined by switchtype or user option. 13369 */ 13370 pvt->law_default = DAHDI_LAW_ALAW; 13371 13372 pvt->sig = pri->sig; 13373 pvt->outsigmod = -1; 13374 pvt->pri = pri; 13375 pvt->sig_pvt = chan; 13376 pri->pvts[pvt_idx] = chan; 13377 13378 pvt->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo"); 13379 if (pvt->subs[SUB_REAL].dfd < 0) { 13380 ast_log(LOG_ERROR, "Unable to open no B channel interface pseudo channel: %s\n", 13381 strerror(errno)); 13382 destroy_dahdi_pvt(pvt); 13383 return -1; 13384 } 13385 memset(&bi, 0, sizeof(bi)); 13386 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi); 13387 if (!res) { 13388 pvt->bufsize = bi.bufsize; 13389 bi.txbufpolicy = pvt->buf_policy; 13390 bi.rxbufpolicy = pvt->buf_policy; 13391 bi.numbufs = pvt->buf_no; 13392 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi); 13393 if (res < 0) { 13394 ast_log(LOG_WARNING, 13395 "Unable to set buffer policy on no B channel interface: %s\n", 13396 strerror(errno)); 13397 } 13398 } else 13399 ast_log(LOG_WARNING, 13400 "Unable to check buffer policy on no B channel interface: %s\n", 13401 strerror(errno)); 13402 13403 --nobch_channel; 13404 if (CHAN_PSEUDO < nobch_channel) { 13405 nobch_channel = CHAN_PSEUDO - 1; 13406 } 13407 pvt->channel = nobch_channel; 13408 pvt->span = pri->span; 13409 chan->channel = pvt->channel; 13410 13411 dahdi_nobch_insert(pri, pvt); 13412 13413 return pvt_idx; 13414 }
static void dahdi_nobch_extract | ( | struct sig_pri_span * | pri, | |
struct dahdi_pvt * | pvt | |||
) | [static] |
Definition at line 5648 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().
05649 { 05650 /* Extract from the forward chain. */ 05651 if (pvt->prev) { 05652 pvt->prev->next = pvt->next; 05653 } else if (pri->no_b_chan_iflist == pvt) { 05654 /* Node is at the head of the list. */ 05655 pri->no_b_chan_iflist = pvt->next; 05656 } 05657 05658 /* Extract from the reverse chain. */ 05659 if (pvt->next) { 05660 pvt->next->prev = pvt->prev; 05661 } else if (pri->no_b_chan_end == pvt) { 05662 /* Node is at the end of the list. */ 05663 pri->no_b_chan_end = pvt->prev; 05664 } 05665 05666 /* Node is no longer in the list. */ 05667 pvt->which_iflist = DAHDI_IFLIST_NONE; 05668 pvt->prev = NULL; 05669 pvt->next = NULL; 05670 }
static void dahdi_nobch_insert | ( | struct sig_pri_span * | pri, | |
struct dahdi_pvt * | pvt | |||
) | [static] |
Definition at line 5595 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.
05596 { 05597 struct dahdi_pvt *cur; 05598 05599 pvt->which_iflist = DAHDI_IFLIST_NO_B_CHAN; 05600 05601 /* Find place in middle of list for the new interface. */ 05602 for (cur = pri->no_b_chan_iflist; cur; cur = cur->next) { 05603 if (pvt->channel < cur->channel) { 05604 /* New interface goes before the current interface. */ 05605 pvt->prev = cur->prev; 05606 pvt->next = cur; 05607 if (cur->prev) { 05608 /* Insert into the middle of the list. */ 05609 cur->prev->next = pvt; 05610 } else { 05611 /* Insert at head of list. */ 05612 pri->no_b_chan_iflist = pvt; 05613 } 05614 cur->prev = pvt; 05615 return; 05616 } 05617 } 05618 05619 /* New interface goes onto the end of the list */ 05620 pvt->prev = pri->no_b_chan_end; 05621 pvt->next = NULL; 05622 if (pri->no_b_chan_end) { 05623 ((struct dahdi_pvt *) pri->no_b_chan_end)->next = pvt; 05624 } 05625 pri->no_b_chan_end = pvt; 05626 if (!pri->no_b_chan_iflist) { 05627 /* List was empty */ 05628 pri->no_b_chan_iflist = pvt; 05629 } 05630 }
static int dahdi_open | ( | char * | fn | ) | [static] |
Definition at line 4312 of file chan_dahdi.c.
References ast_log(), errno, LOG_WARNING, and READ_SIZE.
Referenced by alloc_sub(), and duplicate_pseudo().
04313 { 04314 int fd; 04315 int isnum; 04316 int chan = 0; 04317 int bs; 04318 int x; 04319 isnum = 1; 04320 for (x = 0; x < strlen(fn); x++) { 04321 if (!isdigit(fn[x])) { 04322 isnum = 0; 04323 break; 04324 } 04325 } 04326 if (isnum) { 04327 chan = atoi(fn); 04328 if (chan < 1) { 04329 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn); 04330 return -1; 04331 } 04332 fn = "/dev/dahdi/channel"; 04333 } 04334 fd = open(fn, O_RDWR | O_NONBLOCK); 04335 if (fd < 0) { 04336 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno)); 04337 return -1; 04338 } 04339 if (chan) { 04340 if (ioctl(fd, DAHDI_SPECIFY, &chan)) { 04341 x = errno; 04342 close(fd); 04343 errno = x; 04344 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno)); 04345 return -1; 04346 } 04347 } 04348 bs = READ_SIZE; 04349 if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) { 04350 ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno)); 04351 x = errno; 04352 close(fd); 04353 errno = x; 04354 return -1; 04355 } 04356 return fd; 04357 }
static void dahdi_pri_cc_agent_destructor | ( | struct ast_cc_agent * | agent | ) | [static] |
Definition at line 16660 of file chan_dahdi.c.
References ast_module_unref(), and sig_pri_cc_agent_destructor().
16661 { 16662 sig_pri_cc_agent_destructor(agent); 16663 16664 ast_module_unref(ast_module_info->self); 16665 }
static int dahdi_pri_cc_agent_init | ( | struct ast_cc_agent * | agent, | |
struct ast_channel * | chan | |||
) | [static] |
Definition at line 16616 of file chan_dahdi.c.
References ast_assert, ast_module_ref(), ast_module_unref(), dahdi_sig_pri_lib_handles(), dahdi_pvt::sig, sig_pri_cc_agent_init(), dahdi_pvt::sig_pvt, ast_channel::tech, ast_channel::tech_pvt, and ast_channel_tech::type.
16617 { 16618 struct dahdi_pvt *pvt; 16619 struct sig_pri_chan *pvt_chan; 16620 int res; 16621 16622 ast_assert(!strcmp(chan->tech->type, "DAHDI")); 16623 16624 pvt = chan->tech_pvt; 16625 if (dahdi_sig_pri_lib_handles(pvt->sig)) { 16626 pvt_chan = pvt->sig_pvt; 16627 } else { 16628 pvt_chan = NULL; 16629 } 16630 if (!pvt_chan) { 16631 return -1; 16632 } 16633 16634 ast_module_ref(ast_module_info->self); 16635 16636 res = sig_pri_cc_agent_init(agent, pvt_chan); 16637 if (res) { 16638 ast_module_unref(ast_module_info->self); 16639 } 16640 return res; 16641 }
static void dahdi_pri_error | ( | struct pri * | pri, | |
char * | s | |||
) | [static] |
Definition at line 14136 of file chan_dahdi.c.
References pris.
Referenced by load_module().
14137 { 14138 int x; 14139 int y; 14140 int dchan = -1; 14141 int span = -1; 14142 int dchancount = 0; 14143 14144 if (pri) { 14145 for (x = 0; x < NUM_SPANS; x++) { 14146 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 14147 if (pris[x].pri.dchans[y]) { 14148 dchancount++; 14149 } 14150 14151 if (pris[x].pri.dchans[y] == pri) { 14152 dchan = y; 14153 } 14154 } 14155 if (dchan >= 0) { 14156 span = x; 14157 break; 14158 } 14159 dchancount = 0; 14160 } 14161 if (-1 < span) { 14162 if (1 < dchancount) { 14163 ast_log(LOG_ERROR, "[PRI Span: %d D-Channel: %d] %s", span + 1, dchan, s); 14164 } else { 14165 ast_log(LOG_ERROR, "PRI Span: %d %s", span + 1, s); 14166 } 14167 } else { 14168 ast_log(LOG_ERROR, "PRI Span: ? %s", s); 14169 } 14170 } else { 14171 ast_log(LOG_ERROR, "PRI Span: ? %s", s); 14172 } 14173 14174 ast_mutex_lock(&pridebugfdlock); 14175 14176 if (pridebugfd >= 0) { 14177 if (write(pridebugfd, s, strlen(s)) < 0) { 14178 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 14179 } 14180 } 14181 14182 ast_mutex_unlock(&pridebugfdlock); 14183 }
static void dahdi_pri_message | ( | struct pri * | pri, | |
char * | s | |||
) | [static] |
Definition at line 14085 of file chan_dahdi.c.
References pris.
Referenced by load_module().
14086 { 14087 int x; 14088 int y; 14089 int dchan = -1; 14090 int span = -1; 14091 int dchancount = 0; 14092 14093 if (pri) { 14094 for (x = 0; x < NUM_SPANS; x++) { 14095 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 14096 if (pris[x].pri.dchans[y]) { 14097 dchancount++; 14098 } 14099 14100 if (pris[x].pri.dchans[y] == pri) { 14101 dchan = y; 14102 } 14103 } 14104 if (dchan >= 0) { 14105 span = x; 14106 break; 14107 } 14108 dchancount = 0; 14109 } 14110 if (-1 < span) { 14111 if (1 < dchancount) { 14112 ast_verbose("[PRI Span: %d D-Channel: %d] %s", span + 1, dchan, s); 14113 } else { 14114 ast_verbose("PRI Span: %d %s", span + 1, s); 14115 } 14116 } else { 14117 ast_verbose("PRI Span: ? %s", s); 14118 } 14119 } else { 14120 ast_verbose("PRI Span: ? %s", s); 14121 } 14122 14123 ast_mutex_lock(&pridebugfdlock); 14124 14125 if (pridebugfd >= 0) { 14126 if (write(pridebugfd, s, strlen(s)) < 0) { 14127 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 14128 } 14129 } 14130 14131 ast_mutex_unlock(&pridebugfdlock); 14132 }
static void dahdi_pri_update_span_devstate | ( | struct sig_pri_span * | pri | ) | [static] |
Definition at line 3301 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, sig_pri_chan::inalarm, sig_pri_chan::no_b_channel, sig_pri_span::numchans, dahdi_pvt::pri, sig_pri_span::pvts, sig_pri_is_chan_available(), and sig_pri_span::span.
03302 { 03303 unsigned idx; 03304 unsigned num_b_chans; /* Number of B channels provisioned on the span. */ 03305 unsigned in_use; /* Number of B channels in use on the span. */ 03306 unsigned in_alarm; /* TRUE if the span is in alarm condition. */ 03307 enum ast_device_state new_state; 03308 03309 /* Count the number of B channels and the number of B channels in use. */ 03310 num_b_chans = 0; 03311 in_use = 0; 03312 in_alarm = 1; 03313 for (idx = pri->numchans; idx--;) { 03314 if (pri->pvts[idx] && !pri->pvts[idx]->no_b_channel) { 03315 /* This is a B channel interface. */ 03316 ++num_b_chans; 03317 if (!sig_pri_is_chan_available(pri->pvts[idx])) { 03318 ++in_use; 03319 } 03320 if (!pri->pvts[idx]->inalarm) { 03321 /* There is a channel that is not in alarm. */ 03322 in_alarm = 0; 03323 } 03324 } 03325 } 03326 03327 /* Update the span congestion device state and report any change. */ 03328 if (in_alarm) { 03329 new_state = AST_DEVICE_UNAVAILABLE; 03330 } else { 03331 new_state = num_b_chans == in_use ? AST_DEVICE_BUSY : AST_DEVICE_NOT_INUSE; 03332 } 03333 if (pri->congestion_devstate != new_state) { 03334 pri->congestion_devstate = new_state; 03335 ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/congestion", pri->span); 03336 } 03337 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER) 03338 /* Update the span threshold device state and report any change. */ 03339 if (in_alarm) { 03340 new_state = AST_DEVICE_UNAVAILABLE; 03341 } else if (!in_use) { 03342 new_state = AST_DEVICE_NOT_INUSE; 03343 } else if (!pri->user_busy_threshold) { 03344 new_state = in_use < num_b_chans ? AST_DEVICE_INUSE : AST_DEVICE_BUSY; 03345 } else { 03346 new_state = in_use < pri->user_busy_threshold ? AST_DEVICE_INUSE 03347 : AST_DEVICE_BUSY; 03348 } 03349 if (pri->threshold_devstate != new_state) { 03350 pri->threshold_devstate = new_state; 03351 ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/threshold", pri->span); 03352 } 03353 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */ 03354 }
static int dahdi_queryoption | ( | struct ast_channel * | chan, | |
int | option, | |||
void * | data, | |||
int * | datalen | |||
) | [static] |
Definition at line 6677 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_pri_cc_type, 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.
06678 { 06679 char *cp; 06680 struct dahdi_pvt *p = chan->tech_pvt; 06681 06682 /* all supported options require data */ 06683 if (!p || !data || (*datalen < 1)) { 06684 errno = EINVAL; 06685 return -1; 06686 } 06687 06688 switch (option) { 06689 case AST_OPTION_DIGIT_DETECT: 06690 cp = (char *) data; 06691 *cp = p->ignoredtmf ? 0 : 1; 06692 ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name); 06693 break; 06694 case AST_OPTION_FAX_DETECT: 06695 cp = (char *) data; 06696 *cp = (p->dsp_features & DSP_FEATURE_FAX_DETECT) ? 0 : 1; 06697 ast_debug(1, "Reporting fax tone detection %sabled on %s\n", *cp ? "en" : "dis", chan->name); 06698 break; 06699 case AST_OPTION_CC_AGENT_TYPE: 06700 #if defined(HAVE_PRI) 06701 #if defined(HAVE_PRI_CCSS) 06702 if (dahdi_sig_pri_lib_handles(p->sig)) { 06703 ast_copy_string((char *) data, dahdi_pri_cc_type, *datalen); 06704 break; 06705 } 06706 #endif /* defined(HAVE_PRI_CCSS) */ 06707 #endif /* defined(HAVE_PRI) */ 06708 return -1; 06709 default: 06710 return -1; 06711 } 06712 06713 errno = 0; 06714 06715 return 0; 06716 }
Definition at line 3800 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().
03801 { 03802 for (;;) { 03803 if (p->owner) { 03804 if (ast_channel_trylock(p->owner)) { 03805 DEADLOCK_AVOIDANCE(&p->lock); 03806 } else { 03807 ast_queue_frame(p->owner, f); 03808 ast_channel_unlock(p->owner); 03809 break; 03810 } 03811 } else 03812 break; 03813 } 03814 }
static int16_t dahdi_r2_alaw_to_linear | ( | uint8_t | sample | ) | [inline, static] |
Definition at line 4267 of file chan_dahdi.c.
References AST_ALAW.
04268 { 04269 return AST_ALAW(sample); 04270 }
static int dahdi_r2_answer | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 3836 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().
03837 { 03838 int res = 0; 03839 /* openr2 1.1.0 and older does not even define OR2_LIB_INTERFACE 03840 * and does not has support for openr2_chan_answer_call_with_mode 03841 * */ 03842 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 03843 const char *double_answer = pbx_builtin_getvar_helper(p->owner, "MFCR2_DOUBLE_ANSWER"); 03844 int wants_double_answer = ast_true(double_answer) ? 1 : 0; 03845 if (!double_answer) { 03846 /* this still can result in double answer if the channel context 03847 * was configured that way */ 03848 res = openr2_chan_answer_call(p->r2chan); 03849 } else if (wants_double_answer) { 03850 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE); 03851 } else { 03852 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE); 03853 } 03854 #else 03855 res = openr2_chan_answer_call(p->r2chan); 03856 #endif 03857 return res; 03858 }
static int dahdi_r2_cause_to_ast_cause | ( | openr2_call_disconnect_cause_t | cause | ) | [static] |
Definition at line 4077 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().
04078 { 04079 switch (cause) { 04080 case OR2_CAUSE_BUSY_NUMBER: 04081 return AST_CAUSE_BUSY; 04082 case OR2_CAUSE_NETWORK_CONGESTION: 04083 return AST_CAUSE_CONGESTION; 04084 case OR2_CAUSE_OUT_OF_ORDER: 04085 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 04086 case OR2_CAUSE_UNALLOCATED_NUMBER: 04087 return AST_CAUSE_UNREGISTERED; 04088 case OR2_CAUSE_NO_ANSWER: 04089 return AST_CAUSE_NO_ANSWER; 04090 case OR2_CAUSE_NORMAL_CLEARING: 04091 return AST_CAUSE_NORMAL_CLEARING; 04092 case OR2_CAUSE_UNSPECIFIED: 04093 default: 04094 return AST_CAUSE_NOTDEFINED; 04095 } 04096 }
static void dahdi_r2_destroy_links | ( | void | ) | [static] |
Definition at line 12138 of file chan_dahdi.c.
References ast_free, AST_PTHREADT_NULL, r2links, and r2links_count.
Referenced by __unload_module(), and dahdi_restart().
12139 { 12140 int i = 0; 12141 if (!r2links) { 12142 return; 12143 } 12144 for (; i < r2links_count; i++) { 12145 if (r2links[i]->r2master != AST_PTHREADT_NULL) { 12146 pthread_cancel(r2links[i]->r2master); 12147 pthread_join(r2links[i]->r2master, NULL); 12148 openr2_context_delete(r2links[i]->protocol_context); 12149 } 12150 ast_free(r2links[i]); 12151 } 12152 ast_free(r2links); 12153 r2links = NULL; 12154 r2links_count = 0; 12155 }
static void dahdi_r2_disconnect_call | ( | struct dahdi_pvt * | p, | |
openr2_call_disconnect_cause_t | cause | |||
) | [static] |
Definition at line 3945 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().
03946 { 03947 if (openr2_chan_disconnect_call(p->r2chan, cause)) { 03948 ast_log(LOG_NOTICE, "Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n", 03949 p->channel, openr2_proto_get_disconnect_string(cause)); 03950 /* force the chan to idle and release the call flag now since we will not see a clean on_call_end */ 03951 openr2_chan_set_idle(p->r2chan); 03952 ast_mutex_lock(&p->lock); 03953 p->mfcr2call = 0; 03954 ast_mutex_unlock(&p->lock); 03955 } 03956 }
static openr2_calling_party_category_t dahdi_r2_get_channel_category | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3863 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().
03864 { 03865 openr2_calling_party_category_t cat; 03866 const char *catstr = pbx_builtin_getvar_helper(c, "MFCR2_CATEGORY"); 03867 struct dahdi_pvt *p = c->tech_pvt; 03868 if (ast_strlen_zero(catstr)) { 03869 ast_debug(1, "No MFC/R2 category specified for chan %s, using default %s\n", 03870 c->name, openr2_proto_get_category_string(p->mfcr2_category)); 03871 return p->mfcr2_category; 03872 } 03873 if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) { 03874 ast_log(LOG_WARNING, "Invalid category specified '%s' for chan %s, using default %s\n", 03875 catstr, c->name, openr2_proto_get_category_string(p->mfcr2_category)); 03876 return p->mfcr2_category; 03877 } 03878 ast_debug(1, "Using category %s\n", catstr); 03879 return cat; 03880 }
static struct dahdi_mfcr2* dahdi_r2_get_link | ( | void | ) | [static] |
Definition at line 12158 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.
12159 { 12160 struct dahdi_mfcr2 *new_r2link = NULL; 12161 struct dahdi_mfcr2 **new_r2links = NULL; 12162 /* this function is called just when starting up and no monitor threads have been launched, 12163 no need to lock monitored_count member */ 12164 if (!r2links_count || (r2links[r2links_count - 1]->monitored_count == R2_LINK_CAPACITY)) { 12165 new_r2link = ast_calloc(1, sizeof(**r2links)); 12166 if (!new_r2link) { 12167 ast_log(LOG_ERROR, "Cannot allocate R2 link!\n"); 12168 return NULL; 12169 } 12170 new_r2links = ast_realloc(r2links, ((r2links_count + 1) * sizeof(*r2links))); 12171 if (!new_r2links) { 12172 ast_log(LOG_ERROR, "Cannot allocate R2 link!\n"); 12173 ast_free(new_r2link); 12174 return NULL; 12175 } 12176 r2links = new_r2links; 12177 new_r2link->r2master = AST_PTHREADT_NULL; 12178 r2links[r2links_count] = new_r2link; 12179 r2links_count++; 12180 ast_log(LOG_DEBUG, "Created new R2 link!\n"); 12181 } 12182 return r2links[r2links_count - 1]; 12183 }
static uint8_t dahdi_r2_linear_to_alaw | ( | int | sample | ) | [inline, static] |
Definition at line 4272 of file chan_dahdi.c.
References AST_LIN2A.
04273 { 04274 return AST_LIN2A(sample); 04275 }
static void dahdi_r2_on_ani_digit_received | ( | openr2_chan_t * | r2chan, | |
char | digit | |||
) | [static] |
Definition at line 4231 of file chan_dahdi.c.
References dahdi_pvt::cid_name, dahdi_pvt::cid_num, and dahdi_pvt::mfcr2_ani_index.
04232 { 04233 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 04234 p->cid_num[p->mfcr2_ani_index] = digit; 04235 p->cid_name[p->mfcr2_ani_index] = digit; 04236 p->mfcr2_ani_index++; 04237 p->cid_num[p->mfcr2_ani_index] = 0; 04238 p->cid_name[p->mfcr2_ani_index] = 0; 04239 }
static void dahdi_r2_on_billing_pulse_received | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 4241 of file chan_dahdi.c.
References ast_verbose.
04242 { 04243 ast_verbose("MFC/R2 billing pulse received on channel %d\n", openr2_chan_get_number(r2chan)); 04244 }
static void dahdi_r2_on_call_accepted | ( | openr2_chan_t * | r2chan, | |
openr2_call_mode_t | mode | |||
) | [static] |
Definition at line 4023 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.
04024 { 04025 struct dahdi_pvt *p = NULL; 04026 struct ast_channel *c = NULL; 04027 p = openr2_chan_get_client_data(r2chan); 04028 dahdi_enable_ec(p); 04029 p->mfcr2_call_accepted = 1; 04030 /* if it's an incoming call ... */ 04031 if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) { 04032 ast_verbose("MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan)); 04033 /* If accept on offer is not set, it means at this point the PBX thread is already 04034 launched (was launched in the 'on call offered' handler) and therefore this callback 04035 is being executed already in the PBX thread rather than the monitor thread, don't launch 04036 any other thread, just disable the openr2 reading and answer the call if needed */ 04037 if (!p->mfcr2_accept_on_offer) { 04038 openr2_chan_disable_read(r2chan); 04039 if (p->mfcr2_answer_pending) { 04040 ast_log(LOG_DEBUG, "Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan)); 04041 dahdi_r2_answer(p); 04042 } 04043 return; 04044 } 04045 c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL); 04046 if (c) { 04047 /* chan_dahdi will take care of reading from now on in the PBX thread, tell the 04048 library to forget about it */ 04049 openr2_chan_disable_read(r2chan); 04050 return; 04051 } 04052 ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel); 04053 /* failed to create the channel, bail out and report it as an out of order line */ 04054 dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER); 04055 return; 04056 } 04057 /* this is an outgoing call, no need to launch the PBX thread, most likely we're in one already */ 04058 ast_verbose("MFC/R2 call has been accepted on forward channel %d\n", p->channel); 04059 p->subs[SUB_REAL].needringing = 1; 04060 p->dialing = 0; 04061 /* chan_dahdi will take care of reading from now on in the PBX thread, tell the library to forget about it */ 04062 openr2_chan_disable_read(r2chan); 04063 }
static void dahdi_r2_on_call_answered | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 4065 of file chan_dahdi.c.
References ast_verbose, dahdi_subchannel::needanswer, SUB_REAL, and dahdi_pvt::subs.
04066 { 04067 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 04068 ast_verbose("MFC/R2 call has been answered on channel %d\n", openr2_chan_get_number(r2chan)); 04069 p->subs[SUB_REAL].needanswer = 1; 04070 }
static void dahdi_r2_on_call_disconnect | ( | openr2_chan_t * | r2chan, | |
openr2_call_disconnect_cause_t | cause | |||
) | [static] |
Definition at line 4098 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.
04099 { 04100 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 04101 ast_verbose("MFC/R2 call disconnected on channel %d\n", openr2_chan_get_number(r2chan)); 04102 ast_mutex_lock(&p->lock); 04103 if (!p->owner) { 04104 ast_mutex_unlock(&p->lock); 04105 /* no owner, therefore we can't use dahdi_hangup to disconnect, do it right now */ 04106 dahdi_r2_disconnect_call(p, OR2_CAUSE_NORMAL_CLEARING); 04107 return; 04108 } 04109 /* when we have an owner we don't call dahdi_r2_disconnect_call here, that will 04110 be done in dahdi_hangup */ 04111 if (p->owner->_state == AST_STATE_UP) { 04112 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04113 ast_mutex_unlock(&p->lock); 04114 } else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) { 04115 /* being the forward side we must report what happened to the call to whoever requested it */ 04116 switch (cause) { 04117 case OR2_CAUSE_BUSY_NUMBER: 04118 p->subs[SUB_REAL].needbusy = 1; 04119 break; 04120 case OR2_CAUSE_NETWORK_CONGESTION: 04121 case OR2_CAUSE_OUT_OF_ORDER: 04122 case OR2_CAUSE_UNALLOCATED_NUMBER: 04123 case OR2_CAUSE_NO_ANSWER: 04124 case OR2_CAUSE_UNSPECIFIED: 04125 case OR2_CAUSE_NORMAL_CLEARING: 04126 p->subs[SUB_REAL].needcongestion = 1; 04127 break; 04128 default: 04129 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 04130 } 04131 ast_mutex_unlock(&p->lock); 04132 } else { 04133 ast_mutex_unlock(&p->lock); 04134 /* being the backward side and not UP yet, we only need to request hangup */ 04135 /* TODO: what about doing this same thing when were AST_STATE_UP? */ 04136 ast_queue_hangup_with_cause(p->owner, dahdi_r2_cause_to_ast_cause(cause)); 04137 } 04138 }
static void dahdi_r2_on_call_end | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 4013 of file chan_dahdi.c.
References ast_mutex_lock, ast_mutex_unlock, ast_verbose, dahdi_pvt::channel, dahdi_pvt::lock, and dahdi_pvt::mfcr2call.
04014 { 04015 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 04016 ast_verbose("MFC/R2 call end on channel %d\n", p->channel); 04017 ast_mutex_lock(&p->lock); 04018 p->mfcr2call = 0; 04019 ast_mutex_unlock(&p->lock); 04020 }
static void dahdi_r2_on_call_init | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 3882 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.
03883 { 03884 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 03885 ast_mutex_lock(&p->lock); 03886 if (p->mfcr2call) { 03887 ast_mutex_unlock(&p->lock); 03888 /* TODO: This can happen when some other thread just finished dahdi_request requesting this very same 03889 interface but has not yet seized the line (dahdi_call), and the far end wins and seize the line, 03890 can we avoid this somehow?, at this point when dahdi_call send the seize, it is likely that since 03891 the other end will see our seize as a forced release and drop the call, we will see an invalid 03892 pattern that will be seen and treated as protocol error. */ 03893 ast_log(LOG_ERROR, "Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan)); 03894 return; 03895 } 03896 p->mfcr2call = 1; 03897 /* better safe than sorry ... */ 03898 p->cid_name[0] = '\0'; 03899 p->cid_num[0] = '\0'; 03900 p->cid_subaddr[0] = '\0'; 03901 p->rdnis[0] = '\0'; 03902 p->exten[0] = '\0'; 03903 p->mfcr2_ani_index = '\0'; 03904 p->mfcr2_dnis_index = '\0'; 03905 p->mfcr2_dnis_matched = 0; 03906 p->mfcr2_answer_pending = 0; 03907 p->mfcr2_call_accepted = 0; 03908 ast_mutex_unlock(&p->lock); 03909 ast_verbose("New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan)); 03910 }
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 3958 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.
03959 { 03960 struct dahdi_pvt *p; 03961 struct ast_channel *c; 03962 ast_verbose("MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n", 03963 openr2_chan_get_number(r2chan), ani ? ani : "(restricted)", dnis, 03964 openr2_proto_get_category_string(category)); 03965 p = openr2_chan_get_client_data(r2chan); 03966 /* if collect calls are not allowed and this is a collect call, reject it! */ 03967 if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) { 03968 ast_log(LOG_NOTICE, "Rejecting MFC/R2 collect call\n"); 03969 dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED); 03970 return; 03971 } 03972 ast_mutex_lock(&p->lock); 03973 p->mfcr2_recvd_category = category; 03974 /* if we're not supposed to use CID, clear whatever we have */ 03975 if (!p->use_callerid) { 03976 ast_log(LOG_DEBUG, "No CID allowed in configuration, CID is being cleared!\n"); 03977 p->cid_num[0] = 0; 03978 p->cid_name[0] = 0; 03979 } 03980 /* if we're supposed to answer immediately, clear DNIS and set 's' exten */ 03981 if (p->immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) { 03982 ast_log(LOG_DEBUG, "Setting exten => s because of immediate or 0 DNIS configured\n"); 03983 p->exten[0] = 's'; 03984 p->exten[1] = 0; 03985 } 03986 ast_mutex_unlock(&p->lock); 03987 if (!ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) { 03988 ast_log(LOG_NOTICE, "MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n", 03989 p->channel, p->exten, p->context); 03990 dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER); 03991 return; 03992 } 03993 if (!p->mfcr2_accept_on_offer) { 03994 /* The user wants us to start the PBX thread right away without accepting the call first */ 03995 c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL); 03996 if (c) { 03997 /* Done here, don't disable reading now since we still need to generate MF tones to accept 03998 the call or reject it and detect the tone off condition of the other end, all of this 03999 will be done in the PBX thread now */ 04000 return; 04001 } 04002 ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel); 04003 dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER); 04004 } else if (p->mfcr2_charge_calls) { 04005 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with charge on chan %d\n", p->channel); 04006 openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE); 04007 } else { 04008 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with no charge on chan %d\n", p->channel); 04009 openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE); 04010 } 04011 }
static void dahdi_r2_on_call_read | ( | openr2_chan_t * | r2chan, | |
const unsigned char * | buf, | |||
int | buflen | |||
) | [static] |
Definition at line 4072 of file chan_dahdi.c.
04073 { 04074 /*ast_log(LOG_DEBUG, "Read data from dahdi channel %d\n", openr2_chan_get_number(r2chan));*/ 04075 }
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 4199 of file chan_dahdi.c.
References CHAN_TAG, and dahdi_r2_write_log().
04200 { 04201 #define CHAN_TAG "Chan " 04202 char logmsg[256]; 04203 char completemsg[sizeof(logmsg) + sizeof(CHAN_TAG) - 1]; 04204 vsnprintf(logmsg, sizeof(logmsg), fmt, ap); 04205 snprintf(completemsg, sizeof(completemsg), CHAN_TAG "%d - %s", openr2_chan_get_number(r2chan), logmsg); 04206 dahdi_r2_write_log(level, completemsg); 04207 }
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 4186 of file chan_dahdi.c.
References CONTEXT_TAG, and dahdi_r2_write_log().
04187 { 04188 #define CONTEXT_TAG "Context - " 04189 char logmsg[256]; 04190 char completemsg[sizeof(logmsg) + sizeof(CONTEXT_TAG) - 1]; 04191 vsnprintf(logmsg, sizeof(logmsg), fmt, ap); 04192 snprintf(completemsg, sizeof(completemsg), CONTEXT_TAG "%s", logmsg); 04193 dahdi_r2_write_log(level, completemsg); 04194 #undef CONTEXT_TAG 04195 }
static int dahdi_r2_on_dnis_digit_received | ( | openr2_chan_t * | r2chan, | |
char | digit | |||
) | [static] |
Definition at line 4209 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.
04210 { 04211 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 04212 /* if 'immediate' is set, let's stop requesting DNIS */ 04213 if (p->immediate) { 04214 return 0; 04215 } 04216 p->exten[p->mfcr2_dnis_index] = digit; 04217 p->rdnis[p->mfcr2_dnis_index] = digit; 04218 p->mfcr2_dnis_index++; 04219 p->exten[p->mfcr2_dnis_index] = 0; 04220 p->rdnis[p->mfcr2_dnis_index] = 0; 04221 /* if the DNIS is a match and cannot match more, stop requesting DNIS */ 04222 if ((p->mfcr2_dnis_matched || 04223 (ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num) && (p->mfcr2_dnis_matched = 1))) && 04224 !ast_matchmore_extension(NULL, p->context, p->exten, 1, p->cid_num)) { 04225 return 0; 04226 } 04227 /* otherwise keep going */ 04228 return 1; 04229 }
static void dahdi_r2_on_hardware_alarm | ( | openr2_chan_t * | r2chan, | |
int | alarm | |||
) | [static] |
Definition at line 3912 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.
03913 { 03914 int res; 03915 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 03916 ast_mutex_lock(&p->lock); 03917 p->inalarm = alarm ? 1 : 0; 03918 if (p->inalarm) { 03919 res = get_alarms(p); 03920 handle_alarms(p, res); 03921 } else { 03922 handle_clear_alarms(p); 03923 } 03924 ast_mutex_unlock(&p->lock); 03925 }
static void dahdi_r2_on_line_blocked | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 4166 of file chan_dahdi.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::lock, LOG_NOTICE, and dahdi_pvt::remotelyblocked.
04167 { 04168 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 04169 ast_mutex_lock(&p->lock); 04170 p->remotelyblocked = 1; 04171 ast_mutex_unlock(&p->lock); 04172 ast_log(LOG_NOTICE, "Far end blocked on chan %d\n", openr2_chan_get_number(r2chan)); 04173 }
static void dahdi_r2_on_line_idle | ( | openr2_chan_t * | r2chan | ) | [static] |
Definition at line 4175 of file chan_dahdi.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::lock, LOG_NOTICE, and dahdi_pvt::remotelyblocked.
04176 { 04177 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 04178 ast_mutex_lock(&p->lock); 04179 p->remotelyblocked = 0; 04180 ast_mutex_unlock(&p->lock); 04181 ast_log(LOG_NOTICE, "Far end unblocked on chan %d\n", openr2_chan_get_number(r2chan)); 04182 }
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 3932 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.
03933 { 03934 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan); 03935 ast_log(LOG_ERROR, "MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason)); 03936 if (p->owner) { 03937 p->owner->hangupcause = AST_CAUSE_PROTOCOL_ERROR; 03938 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03939 } 03940 ast_mutex_lock(&p->lock); 03941 p->mfcr2call = 0; 03942 ast_mutex_unlock(&p->lock); 03943 }
static int dahdi_r2_set_context | ( | struct dahdi_mfcr2 * | r2_link, | |
const struct dahdi_chan_conf * | conf | |||
) | [static] |
Definition at line 12185 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.
12186 { 12187 char tmplogdir[] = "/tmp"; 12188 char logdir[OR2_MAX_PATH]; 12189 int threshold = 0; 12190 int snres = 0; 12191 r2_link->protocol_context = openr2_context_new(NULL, &dahdi_r2_event_iface, 12192 &dahdi_r2_transcode_iface, conf->mfcr2.variant, conf->mfcr2.max_ani, 12193 conf->mfcr2.max_dnis); 12194 if (!r2_link->protocol_context) { 12195 return -1; 12196 } 12197 openr2_context_set_log_level(r2_link->protocol_context, conf->mfcr2.loglevel); 12198 openr2_context_set_ani_first(r2_link->protocol_context, conf->mfcr2.get_ani_first); 12199 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 12200 openr2_context_set_skip_category_request(r2_link->protocol_context, conf->mfcr2.skip_category_request); 12201 #endif 12202 openr2_context_set_mf_threshold(r2_link->protocol_context, threshold); 12203 openr2_context_set_mf_back_timeout(r2_link->protocol_context, conf->mfcr2.mfback_timeout); 12204 openr2_context_set_metering_pulse_timeout(r2_link->protocol_context, conf->mfcr2.metering_pulse_timeout); 12205 openr2_context_set_double_answer(r2_link->protocol_context, conf->mfcr2.double_answer); 12206 openr2_context_set_immediate_accept(r2_link->protocol_context, conf->mfcr2.immediate_accept); 12207 if (ast_strlen_zero(conf->mfcr2.logdir)) { 12208 if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) { 12209 ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir); 12210 } 12211 } else { 12212 snres = snprintf(logdir, sizeof(logdir), "%s/%s/%s", ast_config_AST_LOG_DIR, "mfcr2", conf->mfcr2.logdir); 12213 if (snres >= sizeof(logdir)) { 12214 ast_log(LOG_ERROR, "MFC/R2 logging directory truncated, using %s\n", tmplogdir); 12215 if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) { 12216 ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir); 12217 } 12218 } else { 12219 if (openr2_context_set_log_directory(r2_link->protocol_context, logdir)) { 12220 ast_log(LOG_ERROR, "Failed setting MFC/R2 log directory %s\n", logdir); 12221 } 12222 } 12223 } 12224 if (!ast_strlen_zero(conf->mfcr2.r2proto_file)) { 12225 if (openr2_context_configure_from_advanced_file(r2_link->protocol_context, conf->mfcr2.r2proto_file)) { 12226 ast_log(LOG_ERROR, "Failed to configure r2context from advanced configuration file %s\n", conf->mfcr2.r2proto_file); 12227 } 12228 } 12229 r2_link->monitored_count = 0; 12230 return 0; 12231 }
static void dahdi_r2_write_log | ( | openr2_log_level_t | level, | |
char * | logmessage | |||
) | [static] |
Definition at line 4140 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().
04141 { 04142 switch (level) { 04143 case OR2_LOG_NOTICE: 04144 ast_verbose("%s", logmessage); 04145 break; 04146 case OR2_LOG_WARNING: 04147 ast_log(LOG_WARNING, "%s", logmessage); 04148 break; 04149 case OR2_LOG_ERROR: 04150 ast_log(LOG_ERROR, "%s", logmessage); 04151 break; 04152 case OR2_LOG_STACK_TRACE: 04153 case OR2_LOG_MF_TRACE: 04154 case OR2_LOG_CAS_TRACE: 04155 case OR2_LOG_DEBUG: 04156 case OR2_LOG_EX_DEBUG: 04157 ast_log(LOG_DEBUG, "%s", logmessage); 04158 break; 04159 default: 04160 ast_log(LOG_WARNING, "We should handle logging level %d here.\n", level); 04161 ast_log(LOG_DEBUG, "%s", logmessage); 04162 break; 04163 } 04164 }
static struct ast_frame * dahdi_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 8923 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_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_frfree, AST_FRIENDLY_OFFSET, ast_getformatname(), ast_log(), ast_mutex_trylock, ast_mutex_unlock, ast_null_frame, ast_queue_frame(), 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, SIG_PRI_CALL_LEVEL_PROCEEDING, 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.
08924 { 08925 struct dahdi_pvt *p; 08926 int res; 08927 int idx; 08928 void *readbuf; 08929 struct ast_frame *f; 08930 08931 /* 08932 * For analog channels, we must do deadlock avoidance because 08933 * analog ports can have more than one Asterisk channel using 08934 * the same private structure. 08935 */ 08936 p = ast->tech_pvt; 08937 while (ast_mutex_trylock(&p->lock)) { 08938 CHANNEL_DEADLOCK_AVOIDANCE(ast); 08939 08940 /* 08941 * For PRI channels, we must refresh the private pointer because 08942 * the call could move to another B channel while the Asterisk 08943 * channel is unlocked. 08944 */ 08945 p = ast->tech_pvt; 08946 } 08947 08948 idx = dahdi_get_index(ast, p, 0); 08949 08950 /* Hang up if we don't really exist */ 08951 if (idx < 0) { 08952 ast_log(LOG_WARNING, "We don't exist?\n"); 08953 ast_mutex_unlock(&p->lock); 08954 return NULL; 08955 } 08956 08957 if ((p->radio || (p->oprmode < 0)) && p->inalarm) { 08958 ast_mutex_unlock(&p->lock); 08959 return NULL; 08960 } 08961 08962 p->subs[idx].f.frametype = AST_FRAME_NULL; 08963 p->subs[idx].f.datalen = 0; 08964 p->subs[idx].f.samples = 0; 08965 p->subs[idx].f.mallocd = 0; 08966 p->subs[idx].f.offset = 0; 08967 p->subs[idx].f.subclass.integer = 0; 08968 p->subs[idx].f.delivery = ast_tv(0,0); 08969 p->subs[idx].f.src = "dahdi_read"; 08970 p->subs[idx].f.data.ptr = NULL; 08971 08972 /* make sure it sends initial key state as first frame */ 08973 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio)) 08974 { 08975 struct dahdi_params ps; 08976 08977 memset(&ps, 0, sizeof(ps)); 08978 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) { 08979 ast_mutex_unlock(&p->lock); 08980 return NULL; 08981 } 08982 p->firstradio = 1; 08983 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08984 if (ps.rxisoffhook) 08985 { 08986 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_KEY; 08987 } 08988 else 08989 { 08990 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_UNKEY; 08991 } 08992 ast_mutex_unlock(&p->lock); 08993 return &p->subs[idx].f; 08994 } 08995 if (p->ringt > 0) { 08996 if (!(--p->ringt)) { 08997 ast_mutex_unlock(&p->lock); 08998 return NULL; 08999 } 09000 } 09001 09002 #ifdef HAVE_OPENR2 09003 if (p->mfcr2) { 09004 openr2_chan_process_event(p->r2chan); 09005 if (OR2_DIR_FORWARD == openr2_chan_get_direction(p->r2chan)) { 09006 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_PROGRESS }, }; 09007 /* if the call is already accepted and we already delivered AST_CONTROL_RINGING 09008 * now enqueue a progress frame to bridge the media up */ 09009 if (p->mfcr2_call_accepted && 09010 !p->mfcr2_progress && 09011 ast->_state == AST_STATE_RINGING) { 09012 ast_log(LOG_DEBUG, "Enqueuing progress frame after R2 accept in chan %d\n", p->channel); 09013 ast_queue_frame(p->owner, &f); 09014 p->mfcr2_progress = 1; 09015 } 09016 } 09017 } 09018 #endif 09019 09020 if (p->subs[idx].needringing) { 09021 /* Send ringing frame if requested */ 09022 p->subs[idx].needringing = 0; 09023 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09024 p->subs[idx].f.subclass.integer = AST_CONTROL_RINGING; 09025 ast_setstate(ast, AST_STATE_RINGING); 09026 ast_mutex_unlock(&p->lock); 09027 return &p->subs[idx].f; 09028 } 09029 09030 if (p->subs[idx].needbusy) { 09031 /* Send busy frame if requested */ 09032 p->subs[idx].needbusy = 0; 09033 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09034 p->subs[idx].f.subclass.integer = AST_CONTROL_BUSY; 09035 ast_mutex_unlock(&p->lock); 09036 return &p->subs[idx].f; 09037 } 09038 09039 if (p->subs[idx].needcongestion) { 09040 /* Send congestion frame if requested */ 09041 p->subs[idx].needcongestion = 0; 09042 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09043 p->subs[idx].f.subclass.integer = AST_CONTROL_CONGESTION; 09044 ast_mutex_unlock(&p->lock); 09045 return &p->subs[idx].f; 09046 } 09047 09048 if (p->subs[idx].needanswer) { 09049 /* Send answer frame if requested */ 09050 p->subs[idx].needanswer = 0; 09051 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09052 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 09053 ast_mutex_unlock(&p->lock); 09054 return &p->subs[idx].f; 09055 } 09056 #ifdef HAVE_OPENR2 09057 if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) { 09058 /* openr2 took care of reading and handling any event 09059 (needanswer, needbusy etc), if we continue we will read() 09060 twice, lets just return a null frame. This should only 09061 happen when openr2 is dialing out */ 09062 ast_mutex_unlock(&p->lock); 09063 return &ast_null_frame; 09064 } 09065 #endif 09066 09067 if (p->subs[idx].needflash) { 09068 /* Send answer frame if requested */ 09069 p->subs[idx].needflash = 0; 09070 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09071 p->subs[idx].f.subclass.integer = AST_CONTROL_FLASH; 09072 ast_mutex_unlock(&p->lock); 09073 return &p->subs[idx].f; 09074 } 09075 09076 if (p->subs[idx].needhold) { 09077 /* Send answer frame if requested */ 09078 p->subs[idx].needhold = 0; 09079 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09080 p->subs[idx].f.subclass.integer = AST_CONTROL_HOLD; 09081 ast_mutex_unlock(&p->lock); 09082 ast_debug(1, "Sending hold on '%s'\n", ast->name); 09083 return &p->subs[idx].f; 09084 } 09085 09086 if (p->subs[idx].needunhold) { 09087 /* Send answer frame if requested */ 09088 p->subs[idx].needunhold = 0; 09089 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09090 p->subs[idx].f.subclass.integer = AST_CONTROL_UNHOLD; 09091 ast_mutex_unlock(&p->lock); 09092 ast_debug(1, "Sending unhold on '%s'\n", ast->name); 09093 return &p->subs[idx].f; 09094 } 09095 09096 /* 09097 * If we have a fake_event, fake an exception to handle it only 09098 * if this channel owns the private. 09099 */ 09100 if (p->fake_event && p->owner == ast) { 09101 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09102 struct analog_pvt *analog_p = p->sig_pvt; 09103 09104 f = analog_exception(analog_p, ast); 09105 } else { 09106 f = __dahdi_exception(ast); 09107 } 09108 ast_mutex_unlock(&p->lock); 09109 return f; 09110 } 09111 09112 if (ast->rawreadformat == AST_FORMAT_SLINEAR) { 09113 if (!p->subs[idx].linear) { 09114 p->subs[idx].linear = 1; 09115 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09116 if (res) 09117 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, idx); 09118 } 09119 } else if ((ast->rawreadformat == AST_FORMAT_ULAW) || 09120 (ast->rawreadformat == AST_FORMAT_ALAW)) { 09121 if (p->subs[idx].linear) { 09122 p->subs[idx].linear = 0; 09123 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09124 if (res) 09125 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, idx); 09126 } 09127 } else { 09128 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat)); 09129 ast_mutex_unlock(&p->lock); 09130 return NULL; 09131 } 09132 readbuf = ((unsigned char *)p->subs[idx].buffer) + AST_FRIENDLY_OFFSET; 09133 CHECK_BLOCKING(ast); 09134 res = read(p->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE); 09135 ast_clear_flag(ast, AST_FLAG_BLOCKING); 09136 /* Check for hangup */ 09137 if (res < 0) { 09138 f = NULL; 09139 if (res == -1) { 09140 if (errno == EAGAIN) { 09141 /* Return "NULL" frame if there is nobody there */ 09142 ast_mutex_unlock(&p->lock); 09143 return &p->subs[idx].f; 09144 } else if (errno == ELAST) { 09145 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09146 struct analog_pvt *analog_p = p->sig_pvt; 09147 f = analog_exception(analog_p, ast); 09148 } else { 09149 f = __dahdi_exception(ast); 09150 } 09151 } else 09152 ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno)); 09153 } 09154 ast_mutex_unlock(&p->lock); 09155 return f; 09156 } 09157 if (res != (p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE)) { 09158 ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE); 09159 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09160 struct analog_pvt *analog_p = p->sig_pvt; 09161 f = analog_exception(analog_p, ast); 09162 } else { 09163 f = __dahdi_exception(ast); 09164 } 09165 ast_mutex_unlock(&p->lock); 09166 return f; 09167 } 09168 if (p->tdd) { /* if in TDD mode, see if we receive that */ 09169 int c; 09170 09171 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 09172 if (c < 0) { 09173 ast_debug(1,"tdd_feed failed\n"); 09174 ast_mutex_unlock(&p->lock); 09175 return NULL; 09176 } 09177 if (c) { /* if a char to return */ 09178 p->subs[idx].f.subclass.integer = 0; 09179 p->subs[idx].f.frametype = AST_FRAME_TEXT; 09180 p->subs[idx].f.mallocd = 0; 09181 p->subs[idx].f.offset = AST_FRIENDLY_OFFSET; 09182 p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET; 09183 p->subs[idx].f.datalen = 1; 09184 *((char *) p->subs[idx].f.data.ptr) = c; 09185 ast_mutex_unlock(&p->lock); 09186 return &p->subs[idx].f; 09187 } 09188 } 09189 if (idx == SUB_REAL) { 09190 /* Ensure the CW timers decrement only on a single subchannel */ 09191 if (p->cidcwexpire) { 09192 if (!--p->cidcwexpire) { 09193 /* Expired CID/CW */ 09194 ast_verb(3, "CPE does not support Call Waiting Caller*ID.\n"); 09195 restore_conference(p); 09196 } 09197 } 09198 if (p->cid_suppress_expire) { 09199 --p->cid_suppress_expire; 09200 } 09201 if (p->callwaitingrepeat) { 09202 if (!--p->callwaitingrepeat) { 09203 /* Expired, Repeat callwaiting tone */ 09204 ++p->callwaitrings; 09205 dahdi_callwait(ast); 09206 } 09207 } 09208 } 09209 if (p->subs[idx].linear) { 09210 p->subs[idx].f.datalen = READ_SIZE * 2; 09211 } else 09212 p->subs[idx].f.datalen = READ_SIZE; 09213 09214 /* Handle CallerID Transmission */ 09215 if ((p->owner == ast) && p->cidspill) { 09216 send_callerid(p); 09217 } 09218 09219 p->subs[idx].f.frametype = AST_FRAME_VOICE; 09220 p->subs[idx].f.subclass.codec = ast->rawreadformat; 09221 p->subs[idx].f.samples = READ_SIZE; 09222 p->subs[idx].f.mallocd = 0; 09223 p->subs[idx].f.offset = AST_FRIENDLY_OFFSET; 09224 p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[idx].buffer[0]); 09225 #if 0 09226 ast_debug(1, "Read %d of voice on %s\n", p->subs[idx].f.datalen, ast->name); 09227 #endif 09228 if (p->dialing || p->radio || /* Transmitting something */ 09229 (idx && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 09230 ((idx == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 09231 ) { 09232 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 09233 don't send anything */ 09234 p->subs[idx].f.frametype = AST_FRAME_NULL; 09235 p->subs[idx].f.subclass.integer = 0; 09236 p->subs[idx].f.samples = 0; 09237 p->subs[idx].f.mallocd = 0; 09238 p->subs[idx].f.offset = 0; 09239 p->subs[idx].f.data.ptr = NULL; 09240 p->subs[idx].f.datalen= 0; 09241 } 09242 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress || p->waitingfordt.tv_sec) && !idx) { 09243 /* Perform busy detection etc on the dahdi line */ 09244 int mute; 09245 09246 f = ast_dsp_process(ast, p->dsp, &p->subs[idx].f); 09247 09248 /* Check if DSP code thinks we should be muting this frame and mute the conference if so */ 09249 mute = ast_dsp_was_muted(p->dsp); 09250 if (p->muting != mute) { 09251 p->muting = mute; 09252 dahdi_confmute(p, mute); 09253 } 09254 09255 if (f) { 09256 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_BUSY)) { 09257 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 09258 /* Treat this as a "hangup" instead of a "busy" on the assumption that 09259 a busy */ 09260 ast_frfree(f); 09261 f = NULL; 09262 } 09263 } else if (f->frametype == AST_FRAME_DTMF_BEGIN 09264 || f->frametype == AST_FRAME_DTMF_END) { 09265 #ifdef HAVE_PRI 09266 if (dahdi_sig_pri_lib_handles(p->sig) 09267 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING 09268 && p->pri 09269 && ((!p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) 09270 || (p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)))) { 09271 /* Don't accept in-band DTMF when in overlap dial mode */ 09272 ast_debug(1, "Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n", 09273 f->frametype == AST_FRAME_DTMF_BEGIN ? "begin" : "end", 09274 f->subclass.integer, f->subclass.integer, ast->name); 09275 09276 f->frametype = AST_FRAME_NULL; 09277 f->subclass.integer = 0; 09278 } 09279 #endif 09280 /* DSP clears us of being pulse */ 09281 p->pulsedial = 0; 09282 } else if (p->waitingfordt.tv_sec) { 09283 if (ast_tvdiff_ms(ast_tvnow(), p->waitingfordt) >= p->waitfordialtone ) { 09284 p->waitingfordt.tv_sec = 0; 09285 ast_log(LOG_WARNING, "Never saw dialtone on channel %d\n", p->channel); 09286 ast_frfree(f); 09287 f = NULL; 09288 } else if (f->frametype == AST_FRAME_VOICE) { 09289 f->frametype = AST_FRAME_NULL; 09290 f->subclass.integer = 0; 09291 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) { 09292 p->waitingfordt.tv_sec = 0; 09293 p->dsp_features &= ~DSP_FEATURE_WAITDIALTONE; 09294 ast_dsp_set_features(p->dsp, p->dsp_features); 09295 ast_log(LOG_DEBUG, "Got 10 samples of dialtone!\n"); 09296 if (!ast_strlen_zero(p->dop.dialstr)) { /* Dial deferred digits */ 09297 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 09298 if (res < 0) { 09299 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 09300 p->dop.dialstr[0] = '\0'; 09301 ast_mutex_unlock(&p->lock); 09302 ast_frfree(f); 09303 return NULL; 09304 } else { 09305 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 09306 p->dialing = 1; 09307 p->dop.dialstr[0] = '\0'; 09308 p->dop.op = DAHDI_DIAL_OP_REPLACE; 09309 ast_setstate(ast, AST_STATE_DIALING); 09310 } 09311 } 09312 } 09313 } 09314 } 09315 } 09316 } else 09317 f = &p->subs[idx].f; 09318 09319 if (f) { 09320 switch (f->frametype) { 09321 case AST_FRAME_DTMF_BEGIN: 09322 case AST_FRAME_DTMF_END: 09323 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09324 analog_handle_dtmf(p->sig_pvt, ast, idx, &f); 09325 } else { 09326 dahdi_handle_dtmf(ast, idx, &f); 09327 } 09328 break; 09329 case AST_FRAME_VOICE: 09330 if (p->cidspill || p->cid_suppress_expire) { 09331 /* We are/were sending a caller id spill. Suppress any echo. */ 09332 p->subs[idx].f.frametype = AST_FRAME_NULL; 09333 p->subs[idx].f.subclass.integer = 0; 09334 p->subs[idx].f.samples = 0; 09335 p->subs[idx].f.mallocd = 0; 09336 p->subs[idx].f.offset = 0; 09337 p->subs[idx].f.data.ptr = NULL; 09338 p->subs[idx].f.datalen= 0; 09339 } 09340 break; 09341 default: 09342 break; 09343 } 09344 } 09345 09346 ast_mutex_unlock(&p->lock); 09347 return f; 09348 }
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 13647 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, sig_pri_span::num_call_waiting_calls, 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.
13648 { 13649 int callwait = 0; 13650 struct dahdi_pvt *p; 13651 struct ast_channel *tmp = NULL; 13652 struct dahdi_pvt *exitpvt; 13653 int channelmatched = 0; 13654 int groupmatched = 0; 13655 #if defined(HAVE_PRI) || defined(HAVE_SS7) 13656 int transcapdigital = 0; 13657 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 13658 struct dahdi_starting_point start; 13659 13660 ast_mutex_lock(&iflock); 13661 p = determine_starting_point(data, &start); 13662 if (!p) { 13663 /* We couldn't determine a starting point, which likely means badly-formatted channel name. Abort! */ 13664 ast_mutex_unlock(&iflock); 13665 return NULL; 13666 } 13667 13668 /* Search for an unowned channel */ 13669 exitpvt = p; 13670 while (p && !tmp) { 13671 if (start.roundrobin) 13672 round_robin[start.rr_starting_point] = p; 13673 13674 if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched) 13675 && available(&p, channelmatched)) { 13676 ast_debug(1, "Using channel %d\n", p->channel); 13677 13678 callwait = (p->owner != NULL); 13679 #ifdef HAVE_OPENR2 13680 if (p->mfcr2) { 13681 ast_mutex_lock(&p->lock); 13682 if (p->mfcr2call) { 13683 ast_mutex_unlock(&p->lock); 13684 ast_log(LOG_DEBUG, "Yay!, someone just beat us in the race for channel %d.\n", p->channel); 13685 goto next; 13686 } 13687 p->mfcr2call = 1; 13688 ast_mutex_unlock(&p->lock); 13689 } 13690 #endif 13691 if (p->channel == CHAN_PSEUDO) { 13692 p = duplicate_pseudo(p); 13693 if (!p) { 13694 break; 13695 } 13696 } 13697 13698 p->distinctivering = 0; 13699 /* Make special notes */ 13700 switch (start.opt) { 13701 case '\0': 13702 /* No option present. */ 13703 break; 13704 case 'c': 13705 /* Confirm answer */ 13706 p->confirmanswer = 1; 13707 break; 13708 case 'r': 13709 /* Distinctive ring */ 13710 p->distinctivering = start.cadance; 13711 break; 13712 case 'd': 13713 #if defined(HAVE_PRI) || defined(HAVE_SS7) 13714 /* If this is an ISDN call, make it digital */ 13715 transcapdigital = AST_TRANS_CAP_DIGITAL; 13716 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 13717 break; 13718 default: 13719 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", start.opt, (char *)data); 13720 break; 13721 } 13722 13723 p->outgoing = 1; 13724 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 13725 tmp = analog_request(p->sig_pvt, &callwait, requestor); 13726 #ifdef HAVE_PRI 13727 } else if (dahdi_sig_pri_lib_handles(p->sig)) { 13728 /* 13729 * We already have the B channel reserved for this call. We 13730 * just need to make sure that dahdi_hangup() has completed 13731 * cleaning up before continuing. 13732 */ 13733 ast_mutex_lock(&p->lock); 13734 ast_mutex_unlock(&p->lock); 13735 13736 sig_pri_extract_called_num_subaddr(p->sig_pvt, data, p->dnid, 13737 sizeof(p->dnid)); 13738 tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW, requestor, transcapdigital); 13739 #endif 13740 #if defined(HAVE_SS7) 13741 } else if (p->sig == SIG_SS7) { 13742 tmp = sig_ss7_request(p->sig_pvt, SIG_SS7_DEFLAW, requestor, transcapdigital); 13743 #endif /* defined(HAVE_SS7) */ 13744 } else { 13745 tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, requestor ? requestor->linkedid : ""); 13746 } 13747 if (!tmp) { 13748 p->outgoing = 0; 13749 #if defined(HAVE_PRI) 13750 switch (p->sig) { 13751 case SIG_PRI_LIB_HANDLE_CASES: 13752 #if defined(HAVE_PRI_CALL_WAITING) 13753 if (((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting) { 13754 ((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting = 0; 13755 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1); 13756 } 13757 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 13758 /* 13759 * This should be the last thing to clear when we are done with 13760 * the channel. 13761 */ 13762 ((struct sig_pri_chan *) p->sig_pvt)->allocated = 0; 13763 break; 13764 default: 13765 break; 13766 } 13767 #endif /* defined(HAVE_PRI) */ 13768 } else { 13769 snprintf(p->dialstring, sizeof(p->dialstring), "DAHDI/%s", (char *) data); 13770 } 13771 break; 13772 } 13773 #ifdef HAVE_OPENR2 13774 next: 13775 #endif 13776 if (start.backwards) { 13777 p = p->prev; 13778 if (!p) 13779 p = ifend; 13780 } else { 13781 p = p->next; 13782 if (!p) 13783 p = iflist; 13784 } 13785 /* stop when you roll to the one that we started from */ 13786 if (p == exitpvt) 13787 break; 13788 } 13789 ast_mutex_unlock(&iflock); 13790 restart_monitor(); 13791 if (cause && !tmp) { 13792 if (callwait || channelmatched) { 13793 *cause = AST_CAUSE_BUSY; 13794 } else if (groupmatched) { 13795 *cause = AST_CAUSE_CONGESTION; 13796 } else { 13797 /* 13798 * We did not match any channel requested. 13799 * Dialplan error requesting non-existant channel? 13800 */ 13801 } 13802 } 13803 13804 return tmp; 13805 }
static int dahdi_restart | ( | void | ) | [static] |
Definition at line 15081 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().
15082 { 15083 #if defined(HAVE_PRI) || defined(HAVE_SS7) 15084 int i, j; 15085 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 15086 int cancel_code; 15087 struct dahdi_pvt *p; 15088 15089 ast_mutex_lock(&restart_lock); 15090 ast_verb(1, "Destroying channels and reloading DAHDI configuration.\n"); 15091 dahdi_softhangup_all(); 15092 ast_verb(4, "Initial softhangup of all DAHDI channels complete.\n"); 15093 #ifdef HAVE_OPENR2 15094 dahdi_r2_destroy_links(); 15095 #endif 15096 15097 #if defined(HAVE_PRI) 15098 for (i = 0; i < NUM_SPANS; i++) { 15099 if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) { 15100 cancel_code = pthread_cancel(pris[i].pri.master); 15101 pthread_kill(pris[i].pri.master, SIGURG); 15102 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); 15103 pthread_join(pris[i].pri.master, NULL); 15104 ast_debug(4, "Joined thread of span %d\n", i); 15105 } 15106 } 15107 #endif 15108 15109 #if defined(HAVE_SS7) 15110 for (i = 0; i < NUM_SPANS; i++) { 15111 if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) { 15112 cancel_code = pthread_cancel(linksets[i].ss7.master); 15113 pthread_kill(linksets[i].ss7.master, SIGURG); 15114 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); 15115 pthread_join(linksets[i].ss7.master, NULL); 15116 ast_debug(4, "Joined thread of span %d\n", i); 15117 } 15118 } 15119 #endif /* defined(HAVE_SS7) */ 15120 15121 ast_mutex_lock(&monlock); 15122 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 15123 cancel_code = pthread_cancel(monitor_thread); 15124 pthread_kill(monitor_thread, SIGURG); 15125 ast_debug(4, "Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (void *) monitor_thread, cancel_code); 15126 pthread_join(monitor_thread, NULL); 15127 ast_debug(4, "Joined monitor thread\n"); 15128 } 15129 monitor_thread = AST_PTHREADT_NULL; /* prepare to restart thread in setup_dahdi once channels are reconfigured */ 15130 15131 ast_mutex_lock(&ss_thread_lock); 15132 while (ss_thread_count > 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */ 15133 int x = DAHDI_FLASH; 15134 ast_debug(3, "Waiting on %d analog_ss_thread(s) to finish\n", ss_thread_count); 15135 15136 ast_mutex_lock(&iflock); 15137 for (p = iflist; p; p = p->next) { 15138 if (p->owner) { 15139 /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */ 15140 ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 15141 } 15142 } 15143 ast_mutex_unlock(&iflock); 15144 ast_cond_wait(&ss_thread_complete, &ss_thread_lock); 15145 } 15146 15147 /* ensure any created channels before monitor threads were stopped are hungup */ 15148 dahdi_softhangup_all(); 15149 ast_verb(4, "Final softhangup of all DAHDI channels complete.\n"); 15150 destroy_all_channels(); 15151 ast_debug(1, "Channels destroyed. Now re-reading config. %d active channels remaining.\n", ast_active_channels()); 15152 15153 ast_mutex_unlock(&monlock); 15154 15155 #ifdef HAVE_PRI 15156 for (i = 0; i < NUM_SPANS; i++) { 15157 for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) 15158 dahdi_close_pri_fd(&(pris[i]), j); 15159 } 15160 15161 memset(pris, 0, sizeof(pris)); 15162 for (i = 0; i < NUM_SPANS; i++) { 15163 sig_pri_init_pri(&pris[i].pri); 15164 } 15165 pri_set_error(dahdi_pri_error); 15166 pri_set_message(dahdi_pri_message); 15167 #endif 15168 #if defined(HAVE_SS7) 15169 for (i = 0; i < NUM_SPANS; i++) { 15170 for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) 15171 dahdi_close_ss7_fd(&(linksets[i]), j); 15172 } 15173 15174 memset(linksets, 0, sizeof(linksets)); 15175 for (i = 0; i < NUM_SPANS; i++) { 15176 sig_ss7_init_linkset(&linksets[i].ss7); 15177 } 15178 ss7_set_error(dahdi_ss7_error); 15179 ss7_set_message(dahdi_ss7_message); 15180 #endif /* defined(HAVE_SS7) */ 15181 15182 if (setup_dahdi(2) != 0) { 15183 ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n"); 15184 ast_mutex_unlock(&ss_thread_lock); 15185 return 1; 15186 } 15187 ast_mutex_unlock(&ss_thread_lock); 15188 ast_mutex_unlock(&restart_lock); 15189 return 0; 15190 }
static char* dahdi_restart_cmd | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15192 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.
15193 { 15194 switch (cmd) { 15195 case CLI_INIT: 15196 e->command = "dahdi restart"; 15197 e->usage = 15198 "Usage: dahdi restart\n" 15199 " Restarts the DAHDI channels: destroys them all and then\n" 15200 " re-reads them from chan_dahdi.conf.\n" 15201 " Note that this will STOP any running CALL on DAHDI channels.\n" 15202 ""; 15203 return NULL; 15204 case CLI_GENERATE: 15205 return NULL; 15206 } 15207 if (a->argc != 2) 15208 return CLI_SHOWUSAGE; 15209 15210 if (dahdi_restart() != 0) 15211 return CLI_FAILURE; 15212 return CLI_SUCCESS; 15213 }
static int dahdi_ring_phone | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7620 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().
07621 { 07622 int x; 07623 int res; 07624 /* Make sure our transmit state is on hook */ 07625 x = 0; 07626 x = DAHDI_ONHOOK; 07627 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 07628 do { 07629 x = DAHDI_RING; 07630 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 07631 if (res) { 07632 switch (errno) { 07633 case EBUSY: 07634 case EINTR: 07635 /* Wait just in case */ 07636 usleep(10000); 07637 continue; 07638 case EINPROGRESS: 07639 res = 0; 07640 break; 07641 default: 07642 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 07643 res = 0; 07644 } 07645 } 07646 } while (res); 07647 return res; 07648 }
static int dahdi_send_callrerouting_facility_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 5928 of file chan_dahdi.c.
References ast_channel::_state, args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_safe_sleep(), 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().
05929 { 05930 /* Data will be our digit string */ 05931 struct dahdi_pvt *pvt; 05932 char *parse; 05933 int res; 05934 AST_DECLARE_APP_ARGS(args, 05935 AST_APP_ARG(destination); 05936 AST_APP_ARG(original); 05937 AST_APP_ARG(reason); 05938 ); 05939 05940 if (ast_strlen_zero(data)) { 05941 ast_log(LOG_DEBUG, "No data sent to application!\n"); 05942 return -1; 05943 } 05944 if (chan->tech != &dahdi_tech) { 05945 ast_log(LOG_DEBUG, "Only DAHDI technology accepted!\n"); 05946 return -1; 05947 } 05948 pvt = (struct dahdi_pvt *) chan->tech_pvt; 05949 if (!pvt) { 05950 ast_log(LOG_DEBUG, "Unable to find technology private\n"); 05951 return -1; 05952 } 05953 switch (pvt->sig) { 05954 case SIG_PRI_LIB_HANDLE_CASES: 05955 break; 05956 default: 05957 ast_log(LOG_DEBUG, "callrerouting attempted on non-ISDN channel %s\n", 05958 chan->name); 05959 return -1; 05960 } 05961 05962 parse = ast_strdupa(data); 05963 AST_STANDARD_APP_ARGS(args, parse); 05964 05965 if (ast_strlen_zero(args.destination)) { 05966 ast_log(LOG_WARNING, "callrerouting facility requires at least destination number argument\n"); 05967 return -1; 05968 } 05969 05970 if (ast_strlen_zero(args.original)) { 05971 ast_log(LOG_WARNING, "Callrerouting Facility without original called number argument\n"); 05972 args.original = NULL; 05973 } 05974 05975 if (ast_strlen_zero(args.reason)) { 05976 ast_log(LOG_NOTICE, "Callrerouting Facility without diversion reason argument, defaulting to unknown\n"); 05977 args.reason = NULL; 05978 } 05979 05980 res = pri_send_callrerouting_facility_exec(pvt->sig_pvt, chan->_state, 05981 args.destination, args.original, args.reason); 05982 if (!res) { 05983 /* 05984 * Wait up to 5 seconds for a reply before hanging up this call 05985 * leg if the peer does not disconnect first. 05986 */ 05987 ast_safe_sleep(chan, 5000); 05988 } 05989 05990 return -1; 05991 }
static int dahdi_send_keypad_facility_exec | ( | struct ast_channel * | chan, | |
const char * | digits | |||
) | [static] |
Definition at line 5901 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().
05902 { 05903 /* Data will be our digit string */ 05904 struct dahdi_pvt *p; 05905 05906 if (ast_strlen_zero(digits)) { 05907 ast_debug(1, "No digit string sent to application!\n"); 05908 return -1; 05909 } 05910 05911 p = (struct dahdi_pvt *)chan->tech_pvt; 05912 05913 if (!p) { 05914 ast_debug(1, "Unable to find technology private\n"); 05915 return -1; 05916 } 05917 05918 pri_send_keypad_facility_exec(p->sig_pvt, digits); 05919 05920 return 0; 05921 }
static int dahdi_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 18650 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.
18651 { 18652 #define END_SILENCE_LEN 400 18653 #define HEADER_MS 50 18654 #define TRAILER_MS 5 18655 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 18656 #define ASCII_BYTES_PER_CHAR 80 18657 18658 unsigned char *buf,*mybuf; 18659 struct dahdi_pvt *p = c->tech_pvt; 18660 struct pollfd fds[1]; 18661 int size,res,fd,len,x; 18662 int bytes=0; 18663 /* Initial carrier (imaginary) */ 18664 float cr = 1.0; 18665 float ci = 0.0; 18666 float scont = 0.0; 18667 int idx; 18668 18669 idx = dahdi_get_index(c, p, 0); 18670 if (idx < 0) { 18671 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 18672 return -1; 18673 } 18674 if (!text[0]) return(0); /* if nothing to send, don't */ 18675 if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ 18676 if (p->mate) 18677 buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 18678 else 18679 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 18680 if (!buf) 18681 return -1; 18682 mybuf = buf; 18683 if (p->mate) { 18684 int codec = AST_LAW(p); 18685 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */ 18686 PUT_CLID_MARKMS; 18687 } 18688 /* Put actual message */ 18689 for (x = 0; text[x]; x++) { 18690 PUT_CLID(text[x]); 18691 } 18692 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */ 18693 PUT_CLID_MARKMS; 18694 } 18695 len = bytes; 18696 buf = mybuf; 18697 } else { 18698 len = tdd_generate(p->tdd, buf, text); 18699 if (len < 1) { 18700 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text)); 18701 ast_free(mybuf); 18702 return -1; 18703 } 18704 } 18705 memset(buf + len, 0x7f, END_SILENCE_LEN); 18706 len += END_SILENCE_LEN; 18707 fd = p->subs[idx].dfd; 18708 while (len) { 18709 if (ast_check_hangup(c)) { 18710 ast_free(mybuf); 18711 return -1; 18712 } 18713 size = len; 18714 if (size > READ_SIZE) 18715 size = READ_SIZE; 18716 fds[0].fd = fd; 18717 fds[0].events = POLLOUT | POLLPRI; 18718 fds[0].revents = 0; 18719 res = poll(fds, 1, -1); 18720 if (!res) { 18721 ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel); 18722 continue; 18723 } 18724 /* if got exception */ 18725 if (fds[0].revents & POLLPRI) { 18726 ast_free(mybuf); 18727 return -1; 18728 } 18729 if (!(fds[0].revents & POLLOUT)) { 18730 ast_debug(1, "write fd not ready on channel %d\n", p->channel); 18731 continue; 18732 } 18733 res = write(fd, buf, size); 18734 if (res != size) { 18735 if (res == -1) { 18736 ast_free(mybuf); 18737 return -1; 18738 } 18739 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 18740 break; 18741 } 18742 len -= size; 18743 buf += size; 18744 } 18745 ast_free(mybuf); 18746 return(0); 18747 }
static char* dahdi_set_dnd | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15808 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.
15809 { 15810 int channel; 15811 int on; 15812 struct dahdi_pvt *dahdi_chan = NULL; 15813 15814 switch (cmd) { 15815 case CLI_INIT: 15816 e->command = "dahdi set dnd"; 15817 e->usage = 15818 "Usage: dahdi set dnd <chan#> <on|off>\n" 15819 " Sets/resets DND (Do Not Disturb) mode on a channel.\n" 15820 " Changes take effect immediately.\n" 15821 " <chan num> is the channel number\n" 15822 " <on|off> Enable or disable DND mode?\n" 15823 ; 15824 return NULL; 15825 case CLI_GENERATE: 15826 return NULL; 15827 } 15828 15829 if (a->argc != 5) 15830 return CLI_SHOWUSAGE; 15831 15832 if ((channel = atoi(a->argv[3])) <= 0) { 15833 ast_cli(a->fd, "Expected channel number, got '%s'\n", a->argv[3]); 15834 return CLI_SHOWUSAGE; 15835 } 15836 15837 if (ast_true(a->argv[4])) 15838 on = 1; 15839 else if (ast_false(a->argv[4])) 15840 on = 0; 15841 else { 15842 ast_cli(a->fd, "Expected 'on' or 'off', got '%s'\n", a->argv[4]); 15843 return CLI_SHOWUSAGE; 15844 } 15845 15846 ast_mutex_lock(&iflock); 15847 for (dahdi_chan = iflist; dahdi_chan; dahdi_chan = dahdi_chan->next) { 15848 if (dahdi_chan->channel != channel) 15849 continue; 15850 15851 /* Found the channel. Actually set it */ 15852 dahdi_dnd(dahdi_chan, on); 15853 break; 15854 } 15855 ast_mutex_unlock(&iflock); 15856 15857 if (!dahdi_chan) { 15858 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15859 return CLI_FAILURE; 15860 } 15861 15862 return CLI_SUCCESS; 15863 }
static int dahdi_set_hook | ( | int | fd, | |
int | hs | |||
) | [inline, static] |
Definition at line 5161 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().
05162 { 05163 int x, res; 05164 05165 x = hs; 05166 res = ioctl(fd, DAHDI_HOOK, &x); 05167 05168 if (res < 0) { 05169 if (errno == EINPROGRESS) 05170 return 0; 05171 ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno)); 05172 /* will expectedly fail if phone is off hook during operation, such as during a restart */ 05173 } 05174 05175 return res; 05176 }
static char* dahdi_set_hwgain | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15668 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.
15669 { 15670 int channel; 15671 int gain; 15672 int tx; 15673 struct dahdi_hwgain hwgain; 15674 struct dahdi_pvt *tmp = NULL; 15675 15676 switch (cmd) { 15677 case CLI_INIT: 15678 e->command = "dahdi set hwgain"; 15679 e->usage = 15680 "Usage: dahdi set hwgain <rx|tx> <chan#> <gain>\n" 15681 " Sets the hardware gain on a a given channel, overriding the\n" 15682 " value provided at module loadtime, whether the channel is in\n" 15683 " use or not. Changes take effect immediately.\n" 15684 " <rx|tx> which direction do you want to change (relative to our module)\n" 15685 " <chan num> is the channel number relative to the device\n" 15686 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"; 15687 return NULL; 15688 case CLI_GENERATE: 15689 return NULL; 15690 } 15691 15692 if (a->argc != 6) 15693 return CLI_SHOWUSAGE; 15694 15695 if (!strcasecmp("rx", a->argv[3])) 15696 tx = 0; /* rx */ 15697 else if (!strcasecmp("tx", a->argv[3])) 15698 tx = 1; /* tx */ 15699 else 15700 return CLI_SHOWUSAGE; 15701 15702 channel = atoi(a->argv[4]); 15703 gain = atof(a->argv[5])*10.0; 15704 15705 ast_mutex_lock(&iflock); 15706 15707 for (tmp = iflist; tmp; tmp = tmp->next) { 15708 15709 if (tmp->channel != channel) 15710 continue; 15711 15712 if (tmp->subs[SUB_REAL].dfd == -1) 15713 break; 15714 15715 hwgain.newgain = gain; 15716 hwgain.tx = tx; 15717 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_HWGAIN, &hwgain) < 0) { 15718 ast_cli(a->fd, "Unable to set the hardware gain for channel %d: %s\n", channel, strerror(errno)); 15719 ast_mutex_unlock(&iflock); 15720 return CLI_FAILURE; 15721 } 15722 ast_cli(a->fd, "hardware %s gain set to %d (%.1f dB) on channel %d\n", 15723 tx ? "tx" : "rx", gain, (float)gain/10.0, channel); 15724 break; 15725 } 15726 15727 ast_mutex_unlock(&iflock); 15728 15729 if (tmp) 15730 return CLI_SUCCESS; 15731 15732 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15733 return CLI_FAILURE; 15734 15735 }
static char* dahdi_set_swgain | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15737 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.
15738 { 15739 int channel; 15740 float gain; 15741 int tx; 15742 int res; 15743 struct dahdi_pvt *tmp = NULL; 15744 15745 switch (cmd) { 15746 case CLI_INIT: 15747 e->command = "dahdi set swgain"; 15748 e->usage = 15749 "Usage: dahdi set swgain <rx|tx> <chan#> <gain>\n" 15750 " Sets the software gain on a a given channel, overriding the\n" 15751 " value provided at module loadtime, whether the channel is in\n" 15752 " use or not. Changes take effect immediately.\n" 15753 " <rx|tx> which direction do you want to change (relative to our module)\n" 15754 " <chan num> is the channel number relative to the device\n" 15755 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"; 15756 return NULL; 15757 case CLI_GENERATE: 15758 return NULL; 15759 } 15760 15761 if (a->argc != 6) 15762 return CLI_SHOWUSAGE; 15763 15764 if (!strcasecmp("rx", a->argv[3])) 15765 tx = 0; /* rx */ 15766 else if (!strcasecmp("tx", a->argv[3])) 15767 tx = 1; /* tx */ 15768 else 15769 return CLI_SHOWUSAGE; 15770 15771 channel = atoi(a->argv[4]); 15772 gain = atof(a->argv[5]); 15773 15774 ast_mutex_lock(&iflock); 15775 for (tmp = iflist; tmp; tmp = tmp->next) { 15776 15777 if (tmp->channel != channel) 15778 continue; 15779 15780 if (tmp->subs[SUB_REAL].dfd == -1) 15781 break; 15782 15783 if (tx) 15784 res = set_actual_txgain(tmp->subs[SUB_REAL].dfd, gain, tmp->txdrc, tmp->law); 15785 else 15786 res = set_actual_rxgain(tmp->subs[SUB_REAL].dfd, gain, tmp->rxdrc, tmp->law); 15787 15788 if (res) { 15789 ast_cli(a->fd, "Unable to set the software gain for channel %d\n", channel); 15790 ast_mutex_unlock(&iflock); 15791 return CLI_FAILURE; 15792 } 15793 15794 ast_cli(a->fd, "software %s gain set to %.1f on channel %d\n", 15795 tx ? "tx" : "rx", gain, channel); 15796 break; 15797 } 15798 ast_mutex_unlock(&iflock); 15799 15800 if (tmp) 15801 return CLI_SUCCESS; 15802 15803 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15804 return CLI_FAILURE; 15805 15806 }
static int dahdi_setlaw | ( | int | dfd, | |
int | law | |||
) | [static] |
Definition at line 2566 of file chan_dahdi.c.
Referenced by my_new_pri_ast_channel(), and my_pri_ss7_open_media().
02567 { 02568 int res; 02569 res = ioctl(dfd, DAHDI_SETLAW, &law); 02570 if (res) 02571 return res; 02572 return 0; 02573 }
static int dahdi_setlinear | ( | int | dfd, | |
int | linear | |||
) | [static] |
Definition at line 4387 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 6718 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, 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.
06719 { 06720 char *cp; 06721 signed char *scp; 06722 int x; 06723 int idx; 06724 struct dahdi_pvt *p = chan->tech_pvt, *pp; 06725 struct oprmode *oprmode; 06726 06727 06728 /* all supported options require data */ 06729 if (!p || !data || (datalen < 1)) { 06730 errno = EINVAL; 06731 return -1; 06732 } 06733 06734 switch (option) { 06735 case AST_OPTION_TXGAIN: 06736 scp = (signed char *) data; 06737 idx = dahdi_get_index(chan, p, 0); 06738 if (idx < 0) { 06739 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 06740 return -1; 06741 } 06742 ast_debug(1, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp); 06743 return set_actual_txgain(p->subs[idx].dfd, p->txgain + (float) *scp, p->txdrc, p->law); 06744 case AST_OPTION_RXGAIN: 06745 scp = (signed char *) data; 06746 idx = dahdi_get_index(chan, p, 0); 06747 if (idx < 0) { 06748 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 06749 return -1; 06750 } 06751 ast_debug(1, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp); 06752 return set_actual_rxgain(p->subs[idx].dfd, p->rxgain + (float) *scp, p->rxdrc, p->law); 06753 case AST_OPTION_TONE_VERIFY: 06754 if (!p->dsp) 06755 break; 06756 cp = (char *) data; 06757 switch (*cp) { 06758 case 1: 06759 ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name); 06760 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 06761 break; 06762 case 2: 06763 ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name); 06764 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 06765 break; 06766 default: 06767 ast_debug(1, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name); 06768 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 06769 break; 06770 } 06771 break; 06772 case AST_OPTION_TDD: 06773 /* turn on or off TDD */ 06774 cp = (char *) data; 06775 p->mate = 0; 06776 if (!*cp) { /* turn it off */ 06777 ast_debug(1, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name); 06778 if (p->tdd) 06779 tdd_free(p->tdd); 06780 p->tdd = 0; 06781 break; 06782 } 06783 ast_debug(1, "Set option TDD MODE, value: %s(%d) on %s\n", 06784 (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name); 06785 dahdi_disable_ec(p); 06786 /* otherwise, turn it on */ 06787 if (!p->didtdd) { /* if havent done it yet */ 06788 unsigned char mybuf[41000];/*! \todo XXX This is an abuse of the stack!! */ 06789 unsigned char *buf; 06790 int size, res, fd, len; 06791 struct pollfd fds[1]; 06792 06793 buf = mybuf; 06794 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 06795 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 06796 len = 40000; 06797 idx = dahdi_get_index(chan, p, 0); 06798 if (idx < 0) { 06799 ast_log(LOG_WARNING, "No index in TDD?\n"); 06800 return -1; 06801 } 06802 fd = p->subs[idx].dfd; 06803 while (len) { 06804 if (ast_check_hangup(chan)) 06805 return -1; 06806 size = len; 06807 if (size > READ_SIZE) 06808 size = READ_SIZE; 06809 fds[0].fd = fd; 06810 fds[0].events = POLLPRI | POLLOUT; 06811 fds[0].revents = 0; 06812 res = poll(fds, 1, -1); 06813 if (!res) { 06814 ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel); 06815 continue; 06816 } 06817 /* if got exception */ 06818 if (fds[0].revents & POLLPRI) 06819 return -1; 06820 if (!(fds[0].revents & POLLOUT)) { 06821 ast_debug(1, "write fd not ready on channel %d\n", p->channel); 06822 continue; 06823 } 06824 res = write(fd, buf, size); 06825 if (res != size) { 06826 if (res == -1) return -1; 06827 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 06828 break; 06829 } 06830 len -= size; 06831 buf += size; 06832 } 06833 p->didtdd = 1; /* set to have done it now */ 06834 } 06835 if (*cp == 2) { /* Mate mode */ 06836 if (p->tdd) 06837 tdd_free(p->tdd); 06838 p->tdd = 0; 06839 p->mate = 1; 06840 break; 06841 } 06842 if (!p->tdd) { /* if we don't have one yet */ 06843 p->tdd = tdd_new(); /* allocate one */ 06844 } 06845 break; 06846 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 06847 if (!p->dsp) 06848 break; 06849 cp = (char *) data; 06850 ast_debug(1, "Set option RELAX DTMF, value: %s(%d) on %s\n", 06851 *cp ? "ON" : "OFF", (int) *cp, chan->name); 06852 ast_dsp_set_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax); 06853 break; 06854 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 06855 #if defined(HAVE_PRI) 06856 if (dahdi_sig_pri_lib_handles(p->sig) 06857 && ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 06858 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */ 06859 break; 06860 } 06861 #endif /* defined(HAVE_PRI) */ 06862 06863 cp = (char *) data; 06864 if (!*cp) { 06865 ast_debug(1, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name); 06866 x = 0; 06867 dahdi_disable_ec(p); 06868 } else { 06869 ast_debug(1, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name); 06870 x = 1; 06871 } 06872 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x) == -1) 06873 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, x, strerror(errno)); 06874 break; 06875 case AST_OPTION_OPRMODE: /* Operator services mode */ 06876 oprmode = (struct oprmode *) data; 06877 /* We don't support operator mode across technologies */ 06878 if (strcasecmp(chan->tech->type, oprmode->peer->tech->type)) { 06879 ast_log(LOG_NOTICE, "Operator mode not supported on %s to %s calls.\n", 06880 chan->tech->type, oprmode->peer->tech->type); 06881 errno = EINVAL; 06882 return -1; 06883 } 06884 pp = oprmode->peer->tech_pvt; 06885 p->oprmode = pp->oprmode = 0; 06886 /* setup peers */ 06887 p->oprpeer = pp; 06888 pp->oprpeer = p; 06889 /* setup modes, if any */ 06890 if (oprmode->mode) 06891 { 06892 pp->oprmode = oprmode->mode; 06893 p->oprmode = -oprmode->mode; 06894 } 06895 ast_debug(1, "Set Operator Services mode, value: %d on %s/%s\n", 06896 oprmode->mode, chan->name,oprmode->peer->name); 06897 break; 06898 case AST_OPTION_ECHOCAN: 06899 cp = (char *) data; 06900 if (*cp) { 06901 ast_debug(1, "Enabling echo cancellation on %s\n", chan->name); 06902 dahdi_enable_ec(p); 06903 } else { 06904 ast_debug(1, "Disabling echo cancellation on %s\n", chan->name); 06905 dahdi_disable_ec(p); 06906 } 06907 break; 06908 case AST_OPTION_DIGIT_DETECT: 06909 cp = (char *) data; 06910 ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name); 06911 if (*cp) { 06912 enable_dtmf_detect(p); 06913 } else { 06914 disable_dtmf_detect(p); 06915 } 06916 break; 06917 case AST_OPTION_FAX_DETECT: 06918 cp = (char *) data; 06919 if (p->dsp) { 06920 ast_debug(1, "%sabling fax tone detection on %s\n", *cp ? "En" : "Dis", chan->name); 06921 if (*cp) { 06922 p->dsp_features |= DSP_FEATURE_FAX_DETECT; 06923 } else { 06924 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 06925 } 06926 ast_dsp_set_features(p->dsp, p->dsp_features); 06927 } 06928 break; 06929 default: 06930 return -1; 06931 } 06932 errno = 0; 06933 06934 return 0; 06935 }
static char* dahdi_show_channel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15311 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.
15312 { 15313 int channel; 15314 struct dahdi_pvt *tmp = NULL; 15315 struct dahdi_confinfo ci; 15316 struct dahdi_params ps; 15317 int x; 15318 15319 switch (cmd) { 15320 case CLI_INIT: 15321 e->command = "dahdi show channel"; 15322 e->usage = 15323 "Usage: dahdi show channel <chan num>\n" 15324 " Detailed information about a given channel\n"; 15325 return NULL; 15326 case CLI_GENERATE: 15327 return NULL; 15328 } 15329 15330 if (a->argc != 4) 15331 return CLI_SHOWUSAGE; 15332 15333 channel = atoi(a->argv[3]); 15334 15335 ast_mutex_lock(&iflock); 15336 for (tmp = iflist; tmp; tmp = tmp->next) { 15337 if (tmp->channel == channel) { 15338 ast_cli(a->fd, "Channel: %d\n", tmp->channel); 15339 ast_cli(a->fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].dfd); 15340 ast_cli(a->fd, "Span: %d\n", tmp->span); 15341 ast_cli(a->fd, "Extension: %s\n", tmp->exten); 15342 ast_cli(a->fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 15343 ast_cli(a->fd, "Context: %s\n", tmp->context); 15344 ast_cli(a->fd, "Caller ID: %s\n", tmp->cid_num); 15345 ast_cli(a->fd, "Calling TON: %d\n", tmp->cid_ton); 15346 #if defined(HAVE_PRI) 15347 #if defined(HAVE_PRI_SUBADDR) 15348 ast_cli(a->fd, "Caller ID subaddress: %s\n", tmp->cid_subaddr); 15349 #endif /* defined(HAVE_PRI_SUBADDR) */ 15350 #endif /* defined(HAVE_PRI) */ 15351 ast_cli(a->fd, "Caller ID name: %s\n", tmp->cid_name); 15352 ast_cli(a->fd, "Mailbox: %s\n", S_OR(tmp->mailbox, "none")); 15353 if (tmp->vars) { 15354 struct ast_variable *v; 15355 ast_cli(a->fd, "Variables:\n"); 15356 for (v = tmp->vars ; v ; v = v->next) 15357 ast_cli(a->fd, " %s = %s\n", v->name, v->value); 15358 } 15359 ast_cli(a->fd, "Destroy: %d\n", tmp->destroy); 15360 ast_cli(a->fd, "InAlarm: %d\n", tmp->inalarm); 15361 ast_cli(a->fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 15362 ast_cli(a->fd, "Radio: %d\n", tmp->radio); 15363 ast_cli(a->fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>"); 15364 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)" : ""); 15365 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)" : ""); 15366 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)" : ""); 15367 ast_cli(a->fd, "Confno: %d\n", tmp->confno); 15368 ast_cli(a->fd, "Propagated Conference: %d\n", tmp->propconfno); 15369 ast_cli(a->fd, "Real in conference: %d\n", tmp->inconference); 15370 ast_cli(a->fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 15371 ast_cli(a->fd, "Busy Detection: %s\n", tmp->busydetect ? "yes" : "no"); 15372 if (tmp->busydetect) { 15373 #if defined(BUSYDETECT_TONEONLY) 15374 ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_TONEONLY\n"); 15375 #elif defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE) 15376 ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_COMPARE_TONE_AND_SILENCE\n"); 15377 #endif 15378 #ifdef BUSYDETECT_DEBUG 15379 ast_cli(a->fd, " Busy Detector Debug: Enabled\n"); 15380 #endif 15381 ast_cli(a->fd, " Busy Count: %d\n", tmp->busycount); 15382 ast_cli(a->fd, " Busy Pattern: %d,%d\n", tmp->busytonelength, tmp->busyquietlength); 15383 } 15384 ast_cli(a->fd, "TDD: %s\n", tmp->tdd ? "yes" : "no"); 15385 ast_cli(a->fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 15386 ast_cli(a->fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 15387 ast_cli(a->fd, "Default law: %s\n", tmp->law_default == DAHDI_LAW_MULAW ? "ulaw" : tmp->law_default == DAHDI_LAW_ALAW ? "alaw" : "unknown"); 15388 ast_cli(a->fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 15389 ast_cli(a->fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 15390 ast_cli(a->fd, "Gains (RX/TX): %.2f/%.2f\n", tmp->rxgain, tmp->txgain); 15391 ast_cli(a->fd, "Dynamic Range Compression (RX/TX): %.2f/%.2f\n", tmp->rxdrc, tmp->txdrc); 15392 ast_cli(a->fd, "DND: %s\n", dahdi_dnd(tmp, -1) ? "yes" : "no"); 15393 ast_cli(a->fd, "Echo Cancellation:\n"); 15394 15395 if (tmp->echocancel.head.tap_length) { 15396 ast_cli(a->fd, "\t%d taps\n", tmp->echocancel.head.tap_length); 15397 for (x = 0; x < tmp->echocancel.head.param_count; x++) { 15398 ast_cli(a->fd, "\t\t%s: %ud\n", tmp->echocancel.params[x].name, tmp->echocancel.params[x].value); 15399 } 15400 ast_cli(a->fd, "\t%scurrently %s\n", tmp->echocanbridged ? "" : "(unless TDM bridged) ", tmp->echocanon ? "ON" : "OFF"); 15401 } else { 15402 ast_cli(a->fd, "\tnone\n"); 15403 } 15404 ast_cli(a->fd, "Wait for dialtone: %dms\n", tmp->waitfordialtone); 15405 if (tmp->master) 15406 ast_cli(a->fd, "Master Channel: %d\n", tmp->master->channel); 15407 for (x = 0; x < MAX_SLAVES; x++) { 15408 if (tmp->slaves[x]) 15409 ast_cli(a->fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 15410 } 15411 #ifdef HAVE_OPENR2 15412 if (tmp->mfcr2) { 15413 char calldir[OR2_MAX_PATH]; 15414 openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan); 15415 openr2_variant_t r2variant = openr2_context_get_variant(r2context); 15416 ast_cli(a->fd, "MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan)); 15417 ast_cli(a->fd, "MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan)); 15418 ast_cli(a->fd, "MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan)); 15419 ast_cli(a->fd, "MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan)); 15420 ast_cli(a->fd, "MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ? "Yes" : "No"); 15421 ast_cli(a->fd, "MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant)); 15422 ast_cli(a->fd, "MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context)); 15423 ast_cli(a->fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context)); 15424 ast_cli(a->fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No"); 15425 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 15426 ast_cli(a->fd, "MFC/R2 Skip Category Request: %s\n", openr2_context_get_skip_category_request(r2context) ? "Yes" : "No"); 15427 #endif 15428 ast_cli(a->fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No"); 15429 ast_cli(a->fd, "MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No"); 15430 ast_cli(a->fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No"); 15431 ast_cli(a->fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No"); 15432 ast_cli(a->fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No"); 15433 ast_cli(a->fd, "MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context)); 15434 ast_cli(a->fd, "MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context)); 15435 ast_cli(a->fd, "MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan)); 15436 ast_cli(a->fd, "MFC/R2 Tx CAS: %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan)); 15437 ast_cli(a->fd, "MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan)); 15438 ast_cli(a->fd, "MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan)); 15439 ast_cli(a->fd, "MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir, sizeof(calldir))); 15440 } 15441 #endif 15442 #if defined(HAVE_SS7) 15443 if (tmp->ss7) { 15444 struct sig_ss7_chan *chan = tmp->sig_pvt; 15445 15446 ast_cli(a->fd, "CIC: %d\n", chan->cic); 15447 } 15448 #endif /* defined(HAVE_SS7) */ 15449 #ifdef HAVE_PRI 15450 if (tmp->pri) { 15451 struct sig_pri_chan *chan = tmp->sig_pvt; 15452 15453 ast_cli(a->fd, "PRI Flags: "); 15454 if (chan->resetting != SIG_PRI_RESET_IDLE) { 15455 ast_cli(a->fd, "Resetting=%d ", chan->resetting); 15456 } 15457 if (chan->call) 15458 ast_cli(a->fd, "Call "); 15459 if (chan->allocated) { 15460 ast_cli(a->fd, "Allocated "); 15461 } 15462 ast_cli(a->fd, "\n"); 15463 if (tmp->logicalspan) 15464 ast_cli(a->fd, "PRI Logical Span: %d\n", tmp->logicalspan); 15465 else 15466 ast_cli(a->fd, "PRI Logical Span: Implicit\n"); 15467 } 15468 #endif 15469 memset(&ci, 0, sizeof(ci)); 15470 ps.channo = tmp->channel; 15471 if (tmp->subs[SUB_REAL].dfd > -1) { 15472 memset(&ci, 0, sizeof(ci)); 15473 if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) { 15474 ast_cli(a->fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 15475 } 15476 if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONFMUTE, &x)) { 15477 ast_cli(a->fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 15478 } 15479 memset(&ps, 0, sizeof(ps)); 15480 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) { 15481 ast_log(LOG_WARNING, "Failed to get parameters on channel %d: %s\n", tmp->channel, strerror(errno)); 15482 } else { 15483 ast_cli(a->fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 15484 } 15485 } 15486 if (ISTRUNK(tmp)) { 15487 ast_cli(a->fd, "Call Progress: %s\n", tmp->callprogress ? "yes" : "no"); 15488 if (!ast_strlen_zero(progzone)) 15489 ast_cli(a->fd, "Progress Zone: %s\n", progzone); 15490 ast_cli(a->fd, "Busy Detect: %s\n", tmp->busydetect ? "yes" : "no"); 15491 if(tmp->busydetect) { 15492 ast_cli(a->fd, "Busy Count: %d\n", tmp->busycount); 15493 if(tmp->busytonelength > 0) { 15494 ast_cli(a->fd, "Busy Pattern:\n"); 15495 ast_cli(a->fd, " -- Tone Length: %6d ms\n", tmp->busytonelength); 15496 if (tmp->busyquietlength > 0) 15497 ast_cli(a->fd, " -- Quiet Length: %6d ms\n", tmp->busyquietlength); 15498 else 15499 ast_cli(a->fd, " -- Detect Tone Only\n"); 15500 if(tmp->busyfuzziness > 0) 15501 ast_cli(a->fd, "Busy Pattern Fuziness: %d\n", tmp->busyfuzziness); 15502 } 15503 } 15504 } 15505 ast_mutex_unlock(&iflock); 15506 return CLI_SUCCESS; 15507 } 15508 } 15509 ast_mutex_unlock(&iflock); 15510 15511 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15512 return CLI_FAILURE; 15513 }
static char* dahdi_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15225 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.
15226 { 15227 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" 15228 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" 15229 unsigned int targetnum = 0; 15230 int filtertype = 0; 15231 struct dahdi_pvt *tmp = NULL; 15232 char tmps[20] = ""; 15233 char statestr[20] = ""; 15234 char blockstr[20] = ""; 15235 15236 switch (cmd) { 15237 case CLI_INIT: 15238 e->command = "dahdi show channels [group|context]"; 15239 e->usage = 15240 "Usage: dahdi show channels [ group <group> | context <context> ]\n" 15241 " Shows a list of available channels with optional filtering\n" 15242 " <group> must be a number between 0 and 63\n"; 15243 return NULL; 15244 case CLI_GENERATE: 15245 return NULL; 15246 } 15247 15248 /* syntax: dahdi show channels [ group <group> | context <context> ] */ 15249 15250 if (!((a->argc == 3) || (a->argc == 5))) 15251 return CLI_SHOWUSAGE; 15252 15253 if (a->argc == 5) { 15254 if (!strcasecmp(a->argv[3], "group")) { 15255 targetnum = atoi(a->argv[4]); 15256 if ((targetnum < 0) || (targetnum > 63)) 15257 return CLI_SHOWUSAGE; 15258 targetnum = 1 << targetnum; 15259 filtertype = 1; 15260 } else if (!strcasecmp(a->argv[3], "context")) { 15261 filtertype = 2; 15262 } 15263 } 15264 15265 ast_cli(a->fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret", "Blocked", "State"); 15266 ast_mutex_lock(&iflock); 15267 for (tmp = iflist; tmp; tmp = tmp->next) { 15268 if (filtertype) { 15269 switch(filtertype) { 15270 case 1: /* dahdi show channels group <group> */ 15271 if (!(tmp->group & targetnum)) { 15272 continue; 15273 } 15274 break; 15275 case 2: /* dahdi show channels context <context> */ 15276 if (strcasecmp(tmp->context, a->argv[4])) { 15277 continue; 15278 } 15279 break; 15280 default: 15281 break; 15282 } 15283 } 15284 if (tmp->channel > 0) { 15285 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 15286 } else 15287 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 15288 15289 if (tmp->locallyblocked) 15290 blockstr[0] = 'L'; 15291 else 15292 blockstr[0] = ' '; 15293 15294 if (tmp->remotelyblocked) 15295 blockstr[1] = 'R'; 15296 else 15297 blockstr[1] = ' '; 15298 15299 blockstr[2] = '\0'; 15300 15301 snprintf(statestr, sizeof(statestr), "%s", "In Service"); 15302 15303 ast_cli(a->fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret, blockstr, statestr); 15304 } 15305 ast_mutex_unlock(&iflock); 15306 return CLI_SUCCESS; 15307 #undef FORMAT 15308 #undef FORMAT2 15309 }
static char* dahdi_show_status | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15552 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.
15553 { 15554 #define FORMAT "%-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n" 15555 #define FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n" 15556 int span; 15557 int res; 15558 char alarmstr[50]; 15559 15560 int ctl; 15561 struct dahdi_spaninfo s; 15562 15563 switch (cmd) { 15564 case CLI_INIT: 15565 e->command = "dahdi show status"; 15566 e->usage = 15567 "Usage: dahdi show status\n" 15568 " Shows a list of DAHDI cards with status\n"; 15569 return NULL; 15570 case CLI_GENERATE: 15571 return NULL; 15572 } 15573 ctl = open("/dev/dahdi/ctl", O_RDWR); 15574 if (ctl < 0) { 15575 ast_cli(a->fd, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); 15576 return CLI_FAILURE; 15577 } 15578 ast_cli(a->fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC", "Framing", "Coding", "Options", "LBO"); 15579 15580 for (span = 1; span < DAHDI_MAX_SPANS; ++span) { 15581 s.spanno = span; 15582 res = ioctl(ctl, DAHDI_SPANSTAT, &s); 15583 if (res) { 15584 continue; 15585 } 15586 alarmstr[0] = '\0'; 15587 if (s.alarms > 0) { 15588 if (s.alarms & DAHDI_ALARM_BLUE) 15589 strcat(alarmstr, "BLU/"); 15590 if (s.alarms & DAHDI_ALARM_YELLOW) 15591 strcat(alarmstr, "YEL/"); 15592 if (s.alarms & DAHDI_ALARM_RED) 15593 strcat(alarmstr, "RED/"); 15594 if (s.alarms & DAHDI_ALARM_LOOPBACK) 15595 strcat(alarmstr, "LB/"); 15596 if (s.alarms & DAHDI_ALARM_RECOVER) 15597 strcat(alarmstr, "REC/"); 15598 if (s.alarms & DAHDI_ALARM_NOTOPEN) 15599 strcat(alarmstr, "NOP/"); 15600 if (!strlen(alarmstr)) 15601 strcat(alarmstr, "UUU/"); 15602 if (strlen(alarmstr)) { 15603 /* Strip trailing / */ 15604 alarmstr[strlen(alarmstr) - 1] = '\0'; 15605 } 15606 } else { 15607 if (s.numchans) 15608 strcpy(alarmstr, "OK"); 15609 else 15610 strcpy(alarmstr, "UNCONFIGURED"); 15611 } 15612 15613 ast_cli(a->fd, FORMAT, s.desc, alarmstr, s.irqmisses, s.bpvcount, s.crc4count, 15614 s.lineconfig & DAHDI_CONFIG_D4 ? "D4" : 15615 s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" : 15616 s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" : 15617 "CAS", 15618 s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" : 15619 s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" : 15620 s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" : 15621 "Unk", 15622 s.lineconfig & DAHDI_CONFIG_CRC4 ? 15623 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" : 15624 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : "", 15625 lbostr[s.lbo] 15626 ); 15627 } 15628 close(ctl); 15629 15630 return CLI_SUCCESS; 15631 #undef FORMAT 15632 #undef FORMAT2 15633 }
static char* dahdi_show_version | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15635 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.
15636 { 15637 int pseudo_fd = -1; 15638 struct dahdi_versioninfo vi; 15639 15640 switch (cmd) { 15641 case CLI_INIT: 15642 e->command = "dahdi show version"; 15643 e->usage = 15644 "Usage: dahdi show version\n" 15645 " Shows the DAHDI version in use\n"; 15646 return NULL; 15647 case CLI_GENERATE: 15648 return NULL; 15649 } 15650 if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) { 15651 ast_cli(a->fd, "Failed to open control file to get version.\n"); 15652 return CLI_SUCCESS; 15653 } 15654 15655 strcpy(vi.version, "Unknown"); 15656 strcpy(vi.echo_canceller, "Unknown"); 15657 15658 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi)) 15659 ast_cli(a->fd, "Failed to get DAHDI version: %s\n", strerror(errno)); 15660 else 15661 ast_cli(a->fd, "DAHDI Version: %s Echo Canceller: %s\n", vi.version, vi.echo_canceller); 15662 15663 close(pseudo_fd); 15664 15665 return CLI_SUCCESS; 15666 }
static char* dahdi_sig2str | ( | int | sig | ) | [static] |
Definition at line 4611 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.
04612 { 04613 static char buf[256]; 04614 switch (sig) { 04615 case SIG_EM: 04616 return "E & M Immediate"; 04617 case SIG_EMWINK: 04618 return "E & M Wink"; 04619 case SIG_EM_E1: 04620 return "E & M E1"; 04621 case SIG_FEATD: 04622 return "Feature Group D (DTMF)"; 04623 case SIG_FEATDMF: 04624 return "Feature Group D (MF)"; 04625 case SIG_FEATDMF_TA: 04626 return "Feature Groud D (MF) Tandem Access"; 04627 case SIG_FEATB: 04628 return "Feature Group B (MF)"; 04629 case SIG_E911: 04630 return "E911 (MF)"; 04631 case SIG_FGC_CAMA: 04632 return "FGC/CAMA (Dialpulse)"; 04633 case SIG_FGC_CAMAMF: 04634 return "FGC/CAMA (MF)"; 04635 case SIG_FXSLS: 04636 return "FXS Loopstart"; 04637 case SIG_FXSGS: 04638 return "FXS Groundstart"; 04639 case SIG_FXSKS: 04640 return "FXS Kewlstart"; 04641 case SIG_FXOLS: 04642 return "FXO Loopstart"; 04643 case SIG_FXOGS: 04644 return "FXO Groundstart"; 04645 case SIG_FXOKS: 04646 return "FXO Kewlstart"; 04647 case SIG_PRI: 04648 return "ISDN PRI"; 04649 case SIG_BRI: 04650 return "ISDN BRI Point to Point"; 04651 case SIG_BRI_PTMP: 04652 return "ISDN BRI Point to MultiPoint"; 04653 case SIG_SS7: 04654 return "SS7"; 04655 case SIG_MFCR2: 04656 return "MFC/R2"; 04657 case SIG_SF: 04658 return "SF (Tone) Immediate"; 04659 case SIG_SFWINK: 04660 return "SF (Tone) Wink"; 04661 case SIG_SF_FEATD: 04662 return "SF (Tone) with Feature Group D (DTMF)"; 04663 case SIG_SF_FEATDMF: 04664 return "SF (Tone) with Feature Group D (MF)"; 04665 case SIG_SF_FEATB: 04666 return "SF (Tone) with Feature Group B (MF)"; 04667 case 0: 04668 return "Pseudo"; 04669 default: 04670 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig); 04671 return buf; 04672 } 04673 }
static int dahdi_sig_pri_lib_handles | ( | int | signaling | ) | [inline, static] |
Definition at line 1553 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_pri_cc_agent_init(), dahdi_queryoption(), dahdi_read(), dahdi_request(), dahdi_setoption(), handle_alarms(), and handle_clear_alarms().
01554 { 01555 int handles; 01556 01557 switch (signaling) { 01558 case SIG_PRI_LIB_HANDLE_CASES: 01559 handles = 1; 01560 break; 01561 default: 01562 handles = 0; 01563 break; 01564 } 01565 01566 return handles; 01567 }
static void dahdi_softhangup_all | ( | void | ) | [static] |
Definition at line 15052 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().
15053 { 15054 struct dahdi_pvt *p; 15055 retry: 15056 ast_mutex_lock(&iflock); 15057 for (p = iflist; p; p = p->next) { 15058 ast_mutex_lock(&p->lock); 15059 if (p->owner && !p->restartpending) { 15060 if (ast_channel_trylock(p->owner)) { 15061 if (option_debug > 2) 15062 ast_verbose("Avoiding deadlock\n"); 15063 /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */ 15064 ast_mutex_unlock(&p->lock); 15065 ast_mutex_unlock(&iflock); 15066 goto retry; 15067 } 15068 if (option_debug > 2) 15069 ast_verbose("Softhanging up on %s\n", p->owner->name); 15070 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_EXPLICIT); 15071 p->restartpending = 1; 15072 num_restart_pending++; 15073 ast_channel_unlock(p->owner); 15074 } 15075 ast_mutex_unlock(&p->lock); 15076 } 15077 ast_mutex_unlock(&iflock); 15078 }
static int dahdi_status_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 18419 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.
18421 { 18422 int ctl, res, span; 18423 struct ast_data *data_span, *data_alarms; 18424 struct dahdi_spaninfo s; 18425 18426 ctl = open("/dev/dahdi/ctl", O_RDWR); 18427 if (ctl < 0) { 18428 ast_log(LOG_ERROR, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); 18429 return -1; 18430 } 18431 for (span = 1; span < DAHDI_MAX_SPANS; ++span) { 18432 s.spanno = span; 18433 res = ioctl(ctl, DAHDI_SPANSTAT, &s); 18434 if (res) { 18435 continue; 18436 } 18437 18438 data_span = ast_data_add_node(data_root, "span"); 18439 if (!data_span) { 18440 continue; 18441 } 18442 ast_data_add_str(data_span, "description", s.desc); 18443 18444 /* insert the alarms status */ 18445 data_alarms = ast_data_add_node(data_span, "alarms"); 18446 if (!data_alarms) { 18447 continue; 18448 } 18449 18450 ast_data_add_bool(data_alarms, "BLUE", s.alarms & DAHDI_ALARM_BLUE); 18451 ast_data_add_bool(data_alarms, "YELLOW", s.alarms & DAHDI_ALARM_YELLOW); 18452 ast_data_add_bool(data_alarms, "RED", s.alarms & DAHDI_ALARM_RED); 18453 ast_data_add_bool(data_alarms, "LOOPBACK", s.alarms & DAHDI_ALARM_LOOPBACK); 18454 ast_data_add_bool(data_alarms, "RECOVER", s.alarms & DAHDI_ALARM_RECOVER); 18455 ast_data_add_bool(data_alarms, "NOTOPEN", s.alarms & DAHDI_ALARM_NOTOPEN); 18456 18457 ast_data_add_int(data_span, "irqmisses", s.irqmisses); 18458 ast_data_add_int(data_span, "bpviol", s.bpvcount); 18459 ast_data_add_int(data_span, "crc4", s.crc4count); 18460 ast_data_add_str(data_span, "framing", s.lineconfig & DAHDI_CONFIG_D4 ? "D4" : 18461 s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" : 18462 s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" : 18463 "CAS"); 18464 ast_data_add_str(data_span, "coding", s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" : 18465 s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" : 18466 s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" : 18467 "Unknown"); 18468 ast_data_add_str(data_span, "options", s.lineconfig & DAHDI_CONFIG_CRC4 ? 18469 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" : 18470 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : ""); 18471 ast_data_add_str(data_span, "lbo", lbostr[s.lbo]); 18472 18473 /* if this span doesn't match remove it. */ 18474 if (!ast_data_search_match(search, data_span)) { 18475 ast_data_remove_node(data_root, data_span); 18476 } 18477 } 18478 close(ctl); 18479 18480 return 0; 18481 }
static void dahdi_train_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4953 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().
04954 { 04955 int x; 04956 int res; 04957 04958 if (p && p->echocanon && p->echotraining) { 04959 x = p->echotraining; 04960 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x); 04961 if (res) 04962 ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno)); 04963 else 04964 ast_debug(1, "Engaged echo training on channel %d\n", p->channel); 04965 } else { 04966 ast_debug(1, "No echo training requested\n"); 04967 } 04968 }
static void dahdi_unlink | ( | struct dahdi_pvt * | slave, | |
struct dahdi_pvt * | master, | |||
int | needlock | |||
) | [static] |
Definition at line 7150 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().
07151 { 07152 /* Unlink a specific slave or all slaves/masters from a given master */ 07153 int x; 07154 int hasslaves; 07155 if (!master) 07156 return; 07157 if (needlock) { 07158 ast_mutex_lock(&master->lock); 07159 if (slave) { 07160 while (ast_mutex_trylock(&slave->lock)) { 07161 DEADLOCK_AVOIDANCE(&master->lock); 07162 } 07163 } 07164 } 07165 hasslaves = 0; 07166 for (x = 0; x < MAX_SLAVES; x++) { 07167 if (master->slaves[x]) { 07168 if (!slave || (master->slaves[x] == slave)) { 07169 /* Take slave out of the conference */ 07170 ast_debug(1, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 07171 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 07172 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 07173 master->slaves[x]->master = NULL; 07174 master->slaves[x] = NULL; 07175 } else 07176 hasslaves = 1; 07177 } 07178 if (!hasslaves) 07179 master->inconference = 0; 07180 } 07181 if (!slave) { 07182 if (master->master) { 07183 /* Take master out of the conference */ 07184 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 07185 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 07186 hasslaves = 0; 07187 for (x = 0; x < MAX_SLAVES; x++) { 07188 if (master->master->slaves[x] == master) 07189 master->master->slaves[x] = NULL; 07190 else if (master->master->slaves[x]) 07191 hasslaves = 1; 07192 } 07193 if (!hasslaves) 07194 master->master->inconference = 0; 07195 } 07196 master->master = NULL; 07197 } 07198 update_conf(master); 07199 if (needlock) { 07200 if (slave) 07201 ast_mutex_unlock(&slave->lock); 07202 ast_mutex_unlock(&master->lock); 07203 } 07204 }
static void dahdi_unlink_pri_pvt | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5683 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().
05684 { 05685 unsigned idx; 05686 struct sig_pri_span *pri; 05687 05688 pri = pvt->pri; 05689 if (!pri) { 05690 /* Not PRI signaling so cannot be in a PRI private pointer array. */ 05691 return; 05692 } 05693 ast_mutex_lock(&pri->lock); 05694 for (idx = 0; idx < pri->numchans; ++idx) { 05695 if (pri->pvts[idx] == pvt->sig_pvt) { 05696 pri->pvts[idx] = NULL; 05697 ast_mutex_unlock(&pri->lock); 05698 return; 05699 } 05700 } 05701 ast_mutex_unlock(&pri->lock); 05702 }
static int dahdi_version_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 18522 of file chan_dahdi.c.
References ast_data_add_str(), ast_log(), and errno.
18524 { 18525 int pseudo_fd = -1; 18526 struct dahdi_versioninfo vi = { 18527 .version = "Unknown", 18528 .echo_canceller = "Unknown" 18529 }; 18530 18531 if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) { 18532 ast_log(LOG_ERROR, "Failed to open control file to get version.\n"); 18533 return -1; 18534 } 18535 18536 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi)) { 18537 ast_log(LOG_ERROR, "Failed to get DAHDI version: %s\n", strerror(errno)); 18538 } 18539 18540 close(pseudo_fd); 18541 18542 ast_data_add_str(data_root, "value", vi.version); 18543 ast_data_add_str(data_root, "echocanceller", vi.echo_canceller); 18544 18545 return 0; 18546 }
static int dahdi_wait_event | ( | int | fd | ) | [inline, static] |
Avoid the silly dahdi_waitevent which ignores a bunch of events.
Definition at line 498 of file chan_dahdi.c.
00499 { 00500 int i, j = 0; 00501 i = DAHDI_IOMUX_SIGEVENT; 00502 if (ioctl(fd, DAHDI_IOMUX, &i) == -1) 00503 return -1; 00504 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1) 00505 return -1; 00506 return j; 00507 }
static int dahdi_wink | ( | struct dahdi_pvt * | p, | |
int | index | |||
) | [static] |
Definition at line 9850 of file chan_dahdi.c.
References dahdi_set_hook(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
Referenced by analog_ss_thread(), and my_wink().
09851 { 09852 int j; 09853 dahdi_set_hook(p->subs[idx].dfd, DAHDI_WINK); 09854 for (;;) 09855 { 09856 /* set bits of interest */ 09857 j = DAHDI_IOMUX_SIGEVENT; 09858 /* wait for some happening */ 09859 if (ioctl(p->subs[idx].dfd,DAHDI_IOMUX,&j) == -1) return(-1); 09860 /* exit loop if we have it */ 09861 if (j & DAHDI_IOMUX_SIGEVENT) break; 09862 } 09863 /* get the event info */ 09864 if (ioctl(p->subs[idx].dfd,DAHDI_GETEVENT,&j) == -1) return(-1); 09865 return 0; 09866 }
static int dahdi_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 9372 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.
09373 { 09374 struct dahdi_pvt *p = ast->tech_pvt; 09375 int res; 09376 int idx; 09377 idx = dahdi_get_index(ast, p, 0); 09378 if (idx < 0) { 09379 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name); 09380 return -1; 09381 } 09382 09383 /* Write a frame of (presumably voice) data */ 09384 if (frame->frametype != AST_FRAME_VOICE) { 09385 if (frame->frametype != AST_FRAME_IMAGE) 09386 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 09387 return 0; 09388 } 09389 if ((frame->subclass.codec != AST_FORMAT_SLINEAR) && 09390 (frame->subclass.codec != AST_FORMAT_ULAW) && 09391 (frame->subclass.codec != AST_FORMAT_ALAW)) { 09392 ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(frame->subclass.codec)); 09393 return -1; 09394 } 09395 if (p->dialing) { 09396 ast_debug(1, "Dropping frame since I'm still dialing on %s...\n",ast->name); 09397 return 0; 09398 } 09399 if (!p->owner) { 09400 ast_debug(1, "Dropping frame since there is no active owner on %s...\n",ast->name); 09401 return 0; 09402 } 09403 if (p->cidspill) { 09404 ast_debug(1, "Dropping frame since I've still got a callerid spill on %s...\n", 09405 ast->name); 09406 return 0; 09407 } 09408 /* Return if it's not valid data */ 09409 if (!frame->data.ptr || !frame->datalen) 09410 return 0; 09411 09412 if (frame->subclass.codec == AST_FORMAT_SLINEAR) { 09413 if (!p->subs[idx].linear) { 09414 p->subs[idx].linear = 1; 09415 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09416 if (res) 09417 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 09418 } 09419 res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 1); 09420 } else { 09421 /* x-law already */ 09422 if (p->subs[idx].linear) { 09423 p->subs[idx].linear = 0; 09424 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09425 if (res) 09426 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 09427 } 09428 res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 0); 09429 } 09430 if (res < 0) { 09431 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 09432 return -1; 09433 } 09434 return 0; 09435 }
static enum analog_event dahdievent_to_analogevent | ( | int | event | ) | [static] |
Definition at line 2744 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().
02745 { 02746 enum analog_event res; 02747 02748 switch (event) { 02749 case DAHDI_EVENT_ONHOOK: 02750 res = ANALOG_EVENT_ONHOOK; 02751 break; 02752 case DAHDI_EVENT_RINGOFFHOOK: 02753 res = ANALOG_EVENT_RINGOFFHOOK; 02754 break; 02755 case DAHDI_EVENT_WINKFLASH: 02756 res = ANALOG_EVENT_WINKFLASH; 02757 break; 02758 case DAHDI_EVENT_ALARM: 02759 res = ANALOG_EVENT_ALARM; 02760 break; 02761 case DAHDI_EVENT_NOALARM: 02762 res = ANALOG_EVENT_NOALARM; 02763 break; 02764 case DAHDI_EVENT_DIALCOMPLETE: 02765 res = ANALOG_EVENT_DIALCOMPLETE; 02766 break; 02767 case DAHDI_EVENT_RINGERON: 02768 res = ANALOG_EVENT_RINGERON; 02769 break; 02770 case DAHDI_EVENT_RINGEROFF: 02771 res = ANALOG_EVENT_RINGEROFF; 02772 break; 02773 case DAHDI_EVENT_HOOKCOMPLETE: 02774 res = ANALOG_EVENT_HOOKCOMPLETE; 02775 break; 02776 case DAHDI_EVENT_PULSE_START: 02777 res = ANALOG_EVENT_PULSE_START; 02778 break; 02779 case DAHDI_EVENT_POLARITY: 02780 res = ANALOG_EVENT_POLARITY; 02781 break; 02782 case DAHDI_EVENT_RINGBEGIN: 02783 res = ANALOG_EVENT_RINGBEGIN; 02784 break; 02785 case DAHDI_EVENT_EC_DISABLED: 02786 res = ANALOG_EVENT_EC_DISABLED; 02787 break; 02788 case DAHDI_EVENT_REMOVED: 02789 res = ANALOG_EVENT_REMOVED; 02790 break; 02791 case DAHDI_EVENT_NEONMWI_ACTIVE: 02792 res = ANALOG_EVENT_NEONMWI_ACTIVE; 02793 break; 02794 case DAHDI_EVENT_NEONMWI_INACTIVE: 02795 res = ANALOG_EVENT_NEONMWI_INACTIVE; 02796 break; 02797 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 02798 case DAHDI_EVENT_TX_CED_DETECTED: 02799 res = ANALOG_EVENT_TX_CED_DETECTED; 02800 break; 02801 case DAHDI_EVENT_RX_CED_DETECTED: 02802 res = ANALOG_EVENT_RX_CED_DETECTED; 02803 break; 02804 case DAHDI_EVENT_EC_NLP_DISABLED: 02805 res = ANALOG_EVENT_EC_NLP_DISABLED; 02806 break; 02807 case DAHDI_EVENT_EC_NLP_ENABLED: 02808 res = ANALOG_EVENT_EC_NLP_ENABLED; 02809 break; 02810 #endif 02811 case DAHDI_EVENT_PULSEDIGIT: 02812 res = ANALOG_EVENT_PULSEDIGIT; 02813 break; 02814 case DAHDI_EVENT_DTMFDOWN: 02815 res = ANALOG_EVENT_DTMFDOWN; 02816 break; 02817 case DAHDI_EVENT_DTMFUP: 02818 res = ANALOG_EVENT_DTMFUP; 02819 break; 02820 default: 02821 switch(event & 0xFFFF0000) { 02822 case DAHDI_EVENT_PULSEDIGIT: 02823 case DAHDI_EVENT_DTMFDOWN: 02824 case DAHDI_EVENT_DTMFUP: 02825 /* The event includes a digit number in the low word. 02826 * Converting it to a 'enum analog_event' would remove 02827 * that information. Thus it is returned as-is. 02828 */ 02829 return event; 02830 } 02831 02832 res = ANALOG_EVENT_ERROR; 02833 break; 02834 } 02835 02836 return res; 02837 }
static enum analog_sigtype dahdisig_to_analogsig | ( | int | sig | ) | [static] |
Definition at line 1569 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.
01570 { 01571 switch (sig) { 01572 case SIG_FXOLS: 01573 return ANALOG_SIG_FXOLS; 01574 case SIG_FXOGS: 01575 return ANALOG_SIG_FXOGS; 01576 case SIG_FXOKS: 01577 return ANALOG_SIG_FXOKS; 01578 case SIG_FXSLS: 01579 return ANALOG_SIG_FXSLS; 01580 case SIG_FXSGS: 01581 return ANALOG_SIG_FXSGS; 01582 case SIG_FXSKS: 01583 return ANALOG_SIG_FXSKS; 01584 case SIG_EMWINK: 01585 return ANALOG_SIG_EMWINK; 01586 case SIG_EM: 01587 return ANALOG_SIG_EM; 01588 case SIG_EM_E1: 01589 return ANALOG_SIG_EM_E1; 01590 case SIG_FEATD: 01591 return ANALOG_SIG_FEATD; 01592 case SIG_FEATDMF: 01593 return ANALOG_SIG_FEATDMF; 01594 case SIG_E911: 01595 return SIG_E911; 01596 case SIG_FGC_CAMA: 01597 return ANALOG_SIG_FGC_CAMA; 01598 case SIG_FGC_CAMAMF: 01599 return ANALOG_SIG_FGC_CAMAMF; 01600 case SIG_FEATB: 01601 return ANALOG_SIG_FEATB; 01602 case SIG_SFWINK: 01603 return ANALOG_SIG_SFWINK; 01604 case SIG_SF: 01605 return ANALOG_SIG_SF; 01606 case SIG_SF_FEATD: 01607 return ANALOG_SIG_SF_FEATD; 01608 case SIG_SF_FEATDMF: 01609 return ANALOG_SIG_SF_FEATDMF; 01610 case SIG_FEATDMF_TA: 01611 return ANALOG_SIG_FEATDMF_TA; 01612 case SIG_SF_FEATB: 01613 return ANALOG_SIG_FEATB; 01614 default: 01615 return -1; 01616 } 01617 }
static void deep_copy_dahdi_chan_conf | ( | struct dahdi_chan_conf * | dest, | |
const struct dahdi_chan_conf * | src | |||
) | [static] |
Definition at line 18084 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().
18085 { 18086 struct ast_cc_config_params *cc_params; 18087 18088 cc_params = dest->chan.cc_params; 18089 *dest = *src; 18090 dest->chan.cc_params = cc_params; 18091 ast_cc_copy_config_params(dest->chan.cc_params, src->chan.cc_params); 18092 }
static void destroy_all_channels | ( | void | ) | [static] |
Definition at line 5836 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().
05837 { 05838 int chan; 05839 #if defined(HAVE_PRI) 05840 unsigned span; 05841 struct sig_pri_span *pri; 05842 #endif /* defined(HAVE_PRI) */ 05843 struct dahdi_pvt *p; 05844 05845 while (num_restart_pending) { 05846 usleep(1); 05847 } 05848 05849 ast_mutex_lock(&iflock); 05850 /* Destroy all the interfaces and free their memory */ 05851 while (iflist) { 05852 p = iflist; 05853 05854 chan = p->channel; 05855 #if defined(HAVE_PRI_SERVICE_MESSAGES) 05856 { 05857 char db_chan_name[20]; 05858 char db_answer[5]; 05859 char state; 05860 int why = -1; 05861 05862 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, p->span, chan); 05863 if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) { 05864 sscanf(db_answer, "%1c:%30d", &state, &why); 05865 } 05866 if (!why) { 05867 /* SRVST persistence is not required */ 05868 ast_db_del(db_chan_name, SRVST_DBKEY); 05869 } 05870 } 05871 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 05872 /* Free associated memory */ 05873 destroy_dahdi_pvt(p); 05874 ast_verb(3, "Unregistered channel %d\n", chan); 05875 } 05876 ifcount = 0; 05877 ast_mutex_unlock(&iflock); 05878 05879 #if defined(HAVE_PRI) 05880 /* Destroy all of the no B channel interface lists */ 05881 for (span = 0; span < NUM_SPANS; ++span) { 05882 if (!pris[span].dchannels[0]) { 05883 break; 05884 } 05885 pri = &pris[span].pri; 05886 ast_mutex_lock(&pri->lock); 05887 while (pri->no_b_chan_iflist) { 05888 p = pri->no_b_chan_iflist; 05889 05890 /* Free associated memory */ 05891 destroy_dahdi_pvt(p); 05892 } 05893 ast_mutex_unlock(&pri->lock); 05894 } 05895 #endif /* defined(HAVE_PRI) */ 05896 }
static void destroy_channel | ( | struct dahdi_pvt * | cur, | |
int | now | |||
) | [static] |
Definition at line 5818 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().
05819 { 05820 int i; 05821 05822 if (!now) { 05823 /* Do not destroy the channel now if it is owned by someone. */ 05824 if (cur->owner) { 05825 return; 05826 } 05827 for (i = 0; i < 3; i++) { 05828 if (cur->subs[i].owner) { 05829 return; 05830 } 05831 } 05832 } 05833 destroy_dahdi_pvt(cur); 05834 }
static void destroy_dahdi_pvt | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5748 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(), 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().
05749 { 05750 struct dahdi_pvt *p = pvt; 05751 05752 if (p->manages_span_alarms) { 05753 struct dahdi_pvt *next = find_next_iface_in_span(p); 05754 if (next) { 05755 next->manages_span_alarms = 1; 05756 } 05757 } 05758 05759 /* Remove channel from the list */ 05760 #if defined(HAVE_PRI) 05761 dahdi_unlink_pri_pvt(p); 05762 #endif /* defined(HAVE_PRI) */ 05763 #if defined(HAVE_SS7) 05764 dahdi_unlink_ss7_pvt(p); 05765 #endif /* defined(HAVE_SS7) */ 05766 switch (pvt->which_iflist) { 05767 case DAHDI_IFLIST_NONE: 05768 break; 05769 case DAHDI_IFLIST_MAIN: 05770 dahdi_iflist_extract(p); 05771 break; 05772 #if defined(HAVE_PRI) 05773 case DAHDI_IFLIST_NO_B_CHAN: 05774 if (p->pri) { 05775 dahdi_nobch_extract(p->pri, p); 05776 } 05777 break; 05778 #endif /* defined(HAVE_PRI) */ 05779 } 05780 05781 if (p->sig_pvt) { 05782 if (analog_lib_handles(p->sig, 0, 0)) { 05783 analog_delete(p->sig_pvt); 05784 } 05785 switch (p->sig) { 05786 #if defined(HAVE_PRI) 05787 case SIG_PRI_LIB_HANDLE_CASES: 05788 sig_pri_chan_delete(p->sig_pvt); 05789 break; 05790 #endif /* defined(HAVE_PRI) */ 05791 #if defined(HAVE_SS7) 05792 case SIG_SS7: 05793 sig_ss7_chan_delete(p->sig_pvt); 05794 break; 05795 #endif /* defined(HAVE_SS7) */ 05796 default: 05797 break; 05798 } 05799 } 05800 ast_free(p->cidspill); 05801 if (p->use_smdi) 05802 ast_smdi_interface_unref(p->smdi_iface); 05803 if (p->mwi_event_sub) 05804 ast_event_unsubscribe(p->mwi_event_sub); 05805 if (p->vars) { 05806 ast_variables_destroy(p->vars); 05807 } 05808 if (p->cc_params) { 05809 ast_cc_config_params_destroy(p->cc_params); 05810 } 05811 ast_mutex_destroy(&p->lock); 05812 dahdi_close_sub(p, SUB_REAL); 05813 if (p->owner) 05814 p->owner->tech_pvt = NULL; 05815 ast_free(p); 05816 }
static struct dahdi_pvt* determine_starting_point | ( | const char * | data, | |
struct dahdi_starting_point * | param | |||
) | [static] |
Definition at line 13486 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().
13487 { 13488 char *dest; 13489 char *s; 13490 int x; 13491 int res = 0; 13492 struct dahdi_pvt *p; 13493 char *subdir = NULL; 13494 AST_DECLARE_APP_ARGS(args, 13495 AST_APP_ARG(group); /* channel/group token */ 13496 //AST_APP_ARG(ext); /* extension token */ 13497 //AST_APP_ARG(opts); /* options token */ 13498 AST_APP_ARG(other); /* Any remining unused arguments */ 13499 ); 13500 13501 /* 13502 * data is ---v 13503 * Dial(DAHDI/pseudo[/extension[/options]]) 13504 * Dial(DAHDI/<channel#>[c|r<cadance#>|d][/extension[/options]]) 13505 * Dial(DAHDI/<subdir>!<channel#>[c|r<cadance#>|d][/extension[/options]]) 13506 * Dial(DAHDI/i<span>[/extension[/options]]) 13507 * Dial(DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]) 13508 * 13509 * i - ISDN span channel restriction. 13510 * Used by CC to ensure that the CC recall goes out the same span. 13511 * Also to make ISDN channel names dialable when the sequence number 13512 * is stripped off. (Used by DTMF attended transfer feature.) 13513 * 13514 * g - channel group allocation search forward 13515 * G - channel group allocation search backward 13516 * r - channel group allocation round robin search forward 13517 * R - channel group allocation round robin search backward 13518 * 13519 * c - Wait for DTMF digit to confirm answer 13520 * r<cadance#> - Set distintive ring cadance number 13521 * d - Force bearer capability for ISDN/SS7 call to digital. 13522 */ 13523 13524 if (data) { 13525 dest = ast_strdupa(data); 13526 } else { 13527 ast_log(LOG_WARNING, "Channel requested with no data\n"); 13528 return NULL; 13529 } 13530 AST_NONSTANDARD_APP_ARGS(args, dest, '/'); 13531 if (!args.argc || ast_strlen_zero(args.group)) { 13532 ast_log(LOG_WARNING, "No channel/group specified\n"); 13533 return NULL; 13534 } 13535 13536 /* Initialize the output parameters */ 13537 memset(param, 0, sizeof(*param)); 13538 param->channelmatch = -1; 13539 13540 if (strchr(args.group, '!') != NULL) { 13541 char *prev = args.group; 13542 while ((s = strchr(prev, '!')) != NULL) { 13543 *s++ = '/'; 13544 prev = s; 13545 } 13546 *(prev - 1) = '\0'; 13547 subdir = args.group; 13548 args.group = prev; 13549 } else if (args.group[0] == 'i') { 13550 /* Extract the ISDN span channel restriction specifier. */ 13551 res = sscanf(args.group + 1, "%30d", &x); 13552 if (res < 1) { 13553 ast_log(LOG_WARNING, "Unable to determine ISDN span for data %s\n", data); 13554 return NULL; 13555 } 13556 param->span = x; 13557 13558 /* Remove the ISDN span channel restriction specifier. */ 13559 s = strchr(args.group, '-'); 13560 if (!s) { 13561 /* Search all groups since we are ISDN span restricted. */ 13562 return iflist; 13563 } 13564 args.group = s + 1; 13565 res = 0; 13566 } 13567 if (toupper(args.group[0]) == 'G' || toupper(args.group[0])=='R') { 13568 /* Retrieve the group number */ 13569 s = args.group + 1; 13570 res = sscanf(s, "%30d%1c%30d", &x, ¶m->opt, ¶m->cadance); 13571 if (res < 1) { 13572 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", data); 13573 return NULL; 13574 } 13575 param->groupmatch = ((ast_group_t) 1 << x); 13576 13577 if (toupper(args.group[0]) == 'G') { 13578 if (args.group[0] == 'G') { 13579 param->backwards = 1; 13580 p = ifend; 13581 } else 13582 p = iflist; 13583 } else { 13584 if (ARRAY_LEN(round_robin) <= x) { 13585 ast_log(LOG_WARNING, "Round robin index %d out of range for data %s\n", 13586 x, data); 13587 return NULL; 13588 } 13589 if (args.group[0] == 'R') { 13590 param->backwards = 1; 13591 p = round_robin[x] ? round_robin[x]->prev : ifend; 13592 if (!p) 13593 p = ifend; 13594 } else { 13595 p = round_robin[x] ? round_robin[x]->next : iflist; 13596 if (!p) 13597 p = iflist; 13598 } 13599 param->roundrobin = 1; 13600 param->rr_starting_point = x; 13601 } 13602 } else { 13603 s = args.group; 13604 if (!strcasecmp(s, "pseudo")) { 13605 /* Special case for pseudo */ 13606 x = CHAN_PSEUDO; 13607 param->channelmatch = x; 13608 } else { 13609 res = sscanf(s, "%30d%1c%30d", &x, ¶m->opt, ¶m->cadance); 13610 if (res < 1) { 13611 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", data); 13612 return NULL; 13613 } else { 13614 param->channelmatch = x; 13615 } 13616 } 13617 if (subdir) { 13618 char path[PATH_MAX]; 13619 struct stat stbuf; 13620 13621 snprintf(path, sizeof(path), "/dev/dahdi/%s/%d", 13622 subdir, param->channelmatch); 13623 if (stat(path, &stbuf) < 0) { 13624 ast_log(LOG_WARNING, "stat(%s) failed: %s\n", 13625 path, strerror(errno)); 13626 return NULL; 13627 } 13628 if (!S_ISCHR(stbuf.st_mode)) { 13629 ast_log(LOG_ERROR, "%s: Not a character device file\n", 13630 path); 13631 return NULL; 13632 } 13633 param->channelmatch = minor(stbuf.st_rdev); 13634 } 13635 13636 p = iflist; 13637 } 13638 13639 if (param->opt == 'r' && res < 3) { 13640 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", data); 13641 param->opt = '\0'; 13642 } 13643 13644 return p; 13645 }
static int device2chan | ( | const char * | subdir, | |
int | channel, | |||
char * | path, | |||
int | pathlen | |||
) | [static] |
Definition at line 12256 of file chan_dahdi.c.
References ast_log(), errno, LOG_DEBUG, and LOG_ERROR.
Referenced by build_channels().
12257 { 12258 struct stat stbuf; 12259 int num; 12260 12261 snprintf(path, pathlen, "/dev/dahdi/%s/%d", subdir, channel); 12262 if (stat(path, &stbuf) < 0) { 12263 ast_log(LOG_ERROR, "stat(%s) failed: %s\n", path, strerror(errno)); 12264 return -errno; 12265 } 12266 if (!S_ISCHR(stbuf.st_mode)) { 12267 ast_log(LOG_ERROR, "%s: Not a character device file\n", path); 12268 return -EINVAL; 12269 } 12270 num = minor(stbuf.st_rdev); 12271 ast_log(LOG_DEBUG, "%s -> %d\n", path, num); 12272 return num; 12273 12274 }
static int digit_to_dtmfindex | ( | char | digit | ) | [static] |
Definition at line 4447 of file chan_dahdi.c.
Referenced by dahdi_digit_begin().
04448 { 04449 if (isdigit(digit)) 04450 return DAHDI_TONE_DTMF_BASE + (digit - '0'); 04451 else if (digit >= 'A' && digit <= 'D') 04452 return DAHDI_TONE_DTMF_A + (digit - 'A'); 04453 else if (digit >= 'a' && digit <= 'd') 04454 return DAHDI_TONE_DTMF_A + (digit - 'a'); 04455 else if (digit == '*') 04456 return DAHDI_TONE_DTMF_s; 04457 else if (digit == '#') 04458 return DAHDI_TONE_DTMF_p; 04459 else 04460 return -1; 04461 }
static void disable_dtmf_detect | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 6646 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().
06647 { 06648 int val = 0; 06649 06650 p->ignoredtmf = 1; 06651 06652 ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val); 06653 06654 if (!p->hardwaredtmf && p->dsp) { 06655 p->dsp_features &= ~DSP_FEATURE_DIGIT_DETECT; 06656 ast_dsp_set_features(p->dsp, p->dsp_features); 06657 } 06658 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 11680 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::owner, 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().
11681 { 11682 int count, res, res2, spoint, pollres=0; 11683 struct dahdi_pvt *i; 11684 struct dahdi_pvt *last = NULL; 11685 struct dahdi_pvt *doomed; 11686 time_t thispass = 0, lastpass = 0; 11687 int found; 11688 char buf[1024]; 11689 struct pollfd *pfds=NULL; 11690 int lastalloc = -1; 11691 /* This thread monitors all the frame relay interfaces which are not yet in use 11692 (and thus do not have a separate thread) indefinitely */ 11693 /* From here on out, we die whenever asked */ 11694 #if 0 11695 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 11696 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 11697 return NULL; 11698 } 11699 ast_debug(1, "Monitor starting...\n"); 11700 #endif 11701 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 11702 11703 for (;;) { 11704 /* Lock the interface list */ 11705 ast_mutex_lock(&iflock); 11706 if (!pfds || (lastalloc != ifcount)) { 11707 if (pfds) { 11708 ast_free(pfds); 11709 pfds = NULL; 11710 } 11711 if (ifcount) { 11712 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) { 11713 ast_mutex_unlock(&iflock); 11714 return NULL; 11715 } 11716 } 11717 lastalloc = ifcount; 11718 } 11719 /* Build the stuff we're going to poll on, that is the socket of every 11720 dahdi_pvt that does not have an associated owner channel */ 11721 count = 0; 11722 for (i = iflist; i; i = i->next) { 11723 ast_mutex_lock(&i->lock); 11724 if (pfds && (i->subs[SUB_REAL].dfd > -1) && i->sig && (!i->radio) && !(i->sig & SIG_MFCR2)) { 11725 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) { 11726 struct analog_pvt *p = i->sig_pvt; 11727 11728 if (!p) { 11729 ast_log(LOG_ERROR, "No sig_pvt?\n"); 11730 } else if (!p->owner && !p->subs[SUB_REAL].owner) { 11731 /* This needs to be watched, as it lacks an owner */ 11732 pfds[count].fd = i->subs[SUB_REAL].dfd; 11733 pfds[count].events = POLLPRI; 11734 pfds[count].revents = 0; 11735 /* Message waiting or r2 channels also get watched for reading */ 11736 if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk || 11737 (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) { 11738 pfds[count].events |= POLLIN; 11739 } 11740 count++; 11741 } 11742 } else { 11743 if (!i->owner && !i->subs[SUB_REAL].owner && !i->mwimonitoractive ) { 11744 /* This needs to be watched, as it lacks an owner */ 11745 pfds[count].fd = i->subs[SUB_REAL].dfd; 11746 pfds[count].events = POLLPRI; 11747 pfds[count].revents = 0; 11748 /* If we are monitoring for VMWI or sending CID, we need to 11749 read from the channel as well */ 11750 if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk || 11751 (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) { 11752 pfds[count].events |= POLLIN; 11753 } 11754 count++; 11755 } 11756 } 11757 } 11758 ast_mutex_unlock(&i->lock); 11759 } 11760 /* Okay, now that we know what to do, release the interface lock */ 11761 ast_mutex_unlock(&iflock); 11762 11763 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 11764 pthread_testcancel(); 11765 /* Wait at least a second for something to happen */ 11766 res = poll(pfds, count, 1000); 11767 pthread_testcancel(); 11768 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 11769 11770 /* Okay, poll has finished. Let's see what happened. */ 11771 if (res < 0) { 11772 if ((errno != EAGAIN) && (errno != EINTR)) 11773 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 11774 continue; 11775 } 11776 /* Alright, lock the interface list again, and let's look and see what has 11777 happened */ 11778 ast_mutex_lock(&iflock); 11779 found = 0; 11780 spoint = 0; 11781 lastpass = thispass; 11782 thispass = time(NULL); 11783 doomed = NULL; 11784 for (i = iflist;; i = i->next) { 11785 if (doomed) { 11786 int res; 11787 res = dahdi_destroy_channel_bynum(doomed->channel); 11788 if (res != RESULT_SUCCESS) { 11789 ast_log(LOG_WARNING, "Couldn't find channel to destroy, hopefully another destroy operation just happened.\n"); 11790 } 11791 doomed = NULL; 11792 } 11793 if (!i) { 11794 break; 11795 } 11796 11797 if (thispass != lastpass) { 11798 if (!found && ((i == last) || ((i == iflist) && !last))) { 11799 last = i; 11800 if (last) { 11801 struct analog_pvt *analog_p = last->sig_pvt; 11802 /* Only allow MWI to be initiated on a quiescent fxs port */ 11803 if (analog_p 11804 && !last->mwisendactive 11805 && (last->sig & __DAHDI_SIG_FXO) 11806 && !analog_p->fxsoffhookstate 11807 && !last->owner 11808 && !ast_strlen_zero(last->mailbox) 11809 && (thispass - analog_p->onhooktime > 3)) { 11810 res = has_voicemail(last); 11811 if (analog_p->msgstate != res) { 11812 /* Set driver resources for signalling VMWI */ 11813 res2 = ioctl(last->subs[SUB_REAL].dfd, DAHDI_VMWI, &res); 11814 if (res2) { 11815 /* TODO: This message will ALWAYS be generated on some cards; any way to restrict it to those cards where it is interesting? */ 11816 ast_debug(3, "Unable to control message waiting led on channel %d: %s\n", last->channel, strerror(errno)); 11817 } 11818 /* If enabled for FSK spill then initiate it */ 11819 if (mwi_send_init(last)) { 11820 ast_log(LOG_WARNING, "Unable to initiate mwi send sequence on channel %d\n", last->channel); 11821 } 11822 analog_p->msgstate = res; 11823 found ++; 11824 } 11825 } 11826 last = last->next; 11827 } 11828 } 11829 } 11830 if ((i->subs[SUB_REAL].dfd > -1) && i->sig) { 11831 if (i->radio && !i->owner) 11832 { 11833 res = dahdi_get_event(i->subs[SUB_REAL].dfd); 11834 if (res) 11835 { 11836 ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 11837 /* Don't hold iflock while handling init events */ 11838 ast_mutex_unlock(&iflock); 11839 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) 11840 doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res)); 11841 else 11842 doomed = handle_init_event(i, res); 11843 ast_mutex_lock(&iflock); 11844 } 11845 continue; 11846 } 11847 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].dfd, count, &spoint); 11848 if (pollres & POLLIN) { 11849 if (i->owner || i->subs[SUB_REAL].owner) { 11850 #ifdef HAVE_PRI 11851 if (!i->pri) 11852 #endif 11853 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd); 11854 continue; 11855 } 11856 if (!i->mwimonitor_fsk && !i->mwisendactive && i->cid_start != CID_START_DTMF_NOALERT) { 11857 ast_log(LOG_WARNING, "Whoa.... I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd); 11858 continue; 11859 } 11860 res = read(i->subs[SUB_REAL].dfd, buf, sizeof(buf)); 11861 if (res > 0) { 11862 if (i->mwimonitor_fsk) { 11863 if (calc_energy((unsigned char *) buf, res, AST_LAW(i)) > mwilevel) { 11864 pthread_attr_t attr; 11865 pthread_t threadid; 11866 struct mwi_thread_data *mtd; 11867 11868 pthread_attr_init(&attr); 11869 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 11870 11871 ast_log(LOG_DEBUG, "Maybe some MWI on port %d!\n", i->channel); 11872 if ((mtd = ast_calloc(1, sizeof(*mtd)))) { 11873 mtd->pvt = i; 11874 memcpy(mtd->buf, buf, res); 11875 mtd->len = res; 11876 i->mwimonitoractive = 1; 11877 if (ast_pthread_create_background(&threadid, &attr, mwi_thread, mtd)) { 11878 ast_log(LOG_WARNING, "Unable to start mwi thread on channel %d\n", i->channel); 11879 i->mwimonitoractive = 0; 11880 ast_free(mtd); 11881 } 11882 } 11883 } 11884 /* If configured to check for a DTMF CID spill that comes without alert (e.g no polarity reversal) */ 11885 } else if (i->cid_start == CID_START_DTMF_NOALERT) { 11886 int energy; 11887 struct timeval now; 11888 /* State machine dtmfcid_holdoff_state allows for the line to settle 11889 * before checking agin for dtmf energy. Presently waits for 500 mS before checking again 11890 */ 11891 if (1 == i->dtmfcid_holdoff_state) { 11892 gettimeofday(&i->dtmfcid_delay, NULL); 11893 i->dtmfcid_holdoff_state = 2; 11894 } else if (2 == i->dtmfcid_holdoff_state) { 11895 gettimeofday(&now, NULL); 11896 if ((int)(now.tv_sec - i->dtmfcid_delay.tv_sec) * 1000000 + (int)now.tv_usec - (int)i->dtmfcid_delay.tv_usec > 500000) { 11897 i->dtmfcid_holdoff_state = 0; 11898 } 11899 } else { 11900 energy = calc_energy((unsigned char *) buf, res, AST_LAW(i)); 11901 if (!i->mwisendactive && energy > dtmfcid_level) { 11902 pthread_t threadid; 11903 struct ast_channel *chan; 11904 ast_mutex_unlock(&iflock); 11905 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) { 11906 /* just in case this event changes or somehow destroys a channel, set doomed here too */ 11907 doomed = analog_handle_init_event(i->sig_pvt, ANALOG_EVENT_DTMFCID); 11908 i->dtmfcid_holdoff_state = 1; 11909 } else { 11910 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11911 if (!chan) { 11912 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11913 } else { 11914 res = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan); 11915 if (res) { 11916 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11917 ast_hangup(chan); 11918 } else { 11919 i->dtmfcid_holdoff_state = 1; 11920 } 11921 } 11922 } 11923 ast_mutex_lock(&iflock); 11924 } 11925 } 11926 } 11927 if (i->mwisendactive) { 11928 mwi_send_process_buffer(i, res); 11929 } 11930 } else { 11931 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 11932 } 11933 } 11934 if (pollres & POLLPRI) { 11935 if (i->owner || i->subs[SUB_REAL].owner) { 11936 #ifdef HAVE_PRI 11937 if (!i->pri) 11938 #endif 11939 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].dfd); 11940 continue; 11941 } 11942 res = dahdi_get_event(i->subs[SUB_REAL].dfd); 11943 ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 11944 /* Don't hold iflock while handling init events */ 11945 ast_mutex_unlock(&iflock); 11946 if (0 == i->mwisendactive || 0 == mwi_send_process_event(i, res)) { 11947 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) 11948 doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res)); 11949 else 11950 doomed = handle_init_event(i, res); 11951 } 11952 ast_mutex_lock(&iflock); 11953 } 11954 } 11955 } 11956 ast_mutex_unlock(&iflock); 11957 } 11958 /* Never reached */ 11959 return NULL; 11960 11961 }
static int drc_sample | ( | int | sample, | |
float | drc | |||
) | [static] |
Definition at line 4989 of file chan_dahdi.c.
Referenced by fill_rxgain(), and fill_txgain().
04990 { 04991 float neg; 04992 float shallow, steep; 04993 float max = SHRT_MAX; 04994 04995 neg = (sample < 0 ? -1 : 1); 04996 steep = drc*sample; 04997 shallow = neg*(max-max/drc)+(float)sample/drc; 04998 if (abs(steep) < abs(shallow)) { 04999 sample = steep; 05000 } 05001 else { 05002 sample = shallow; 05003 } 05004 05005 return sample; 05006 }
Definition at line 13422 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().
13423 { 13424 struct dahdi_pvt *p; 13425 struct dahdi_bufferinfo bi; 13426 int res; 13427 13428 p = ast_malloc(sizeof(*p)); 13429 if (!p) { 13430 return NULL; 13431 } 13432 *p = *src; 13433 13434 /* Must deep copy the cc_params. */ 13435 p->cc_params = ast_cc_config_params_init(); 13436 if (!p->cc_params) { 13437 ast_free(p); 13438 return NULL; 13439 } 13440 ast_cc_copy_config_params(p->cc_params, src->cc_params); 13441 13442 p->which_iflist = DAHDI_IFLIST_NONE; 13443 p->next = NULL; 13444 p->prev = NULL; 13445 ast_mutex_init(&p->lock); 13446 p->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo"); 13447 if (p->subs[SUB_REAL].dfd < 0) { 13448 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 13449 destroy_dahdi_pvt(p); 13450 return NULL; 13451 } 13452 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi); 13453 if (!res) { 13454 bi.txbufpolicy = src->buf_policy; 13455 bi.rxbufpolicy = src->buf_policy; 13456 bi.numbufs = src->buf_no; 13457 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi); 13458 if (res < 0) { 13459 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel: %s\n", strerror(errno)); 13460 } 13461 } else 13462 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel: %s\n", strerror(errno)); 13463 p->destroy = 1; 13464 dahdi_iflist_insert(p); 13465 return p; 13466 }
static void enable_dtmf_detect | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 6660 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().
06661 { 06662 int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE; 06663 06664 if (p->channel == CHAN_PSEUDO) 06665 return; 06666 06667 p->ignoredtmf = 0; 06668 06669 ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val); 06670 06671 if (!p->hardwaredtmf && p->dsp) { 06672 p->dsp_features |= DSP_FEATURE_DIGIT_DETECT; 06673 ast_dsp_set_features(p->dsp, p->dsp_features); 06674 } 06675 }
static const char * event2str | ( | int | event | ) | [static] |
Definition at line 4602 of file chan_dahdi.c.
References ARRAY_LEN.
Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_handle_event(), mwi_thread(), my_distinctive_ring(), and my_handle_dchan_exception().
04603 { 04604 static char buf[256]; 04605 if ((event < (ARRAY_LEN(events))) && (event > -1)) 04606 return events[event]; 04607 sprintf(buf, "Event %d", event); /* safe */ 04608 return buf; 04609 }
static void fill_rxgain | ( | struct dahdi_gains * | g, | |
float | gain, | |||
float | drc, | |||
int | law | |||
) | [static] |
Definition at line 5053 of file chan_dahdi.c.
References ARRAY_LEN, AST_ALAW, AST_LIN2A, AST_LIN2MU, AST_MULAW, and drc_sample().
Referenced by set_actual_rxgain().
05054 { 05055 int j; 05056 int k; 05057 float linear_gain = pow(10.0, gain / 20.0); 05058 05059 switch (law) { 05060 case DAHDI_LAW_ALAW: 05061 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) { 05062 if (gain || drc) { 05063 k = AST_ALAW(j); 05064 if (drc) { 05065 k = drc_sample(k, drc); 05066 } 05067 k = (float)k*linear_gain; 05068 if (k > 32767) k = 32767; 05069 if (k < -32767) k = -32767; 05070 g->rxgain[j] = AST_LIN2A(k); 05071 } else { 05072 g->rxgain[j] = j; 05073 } 05074 } 05075 break; 05076 case DAHDI_LAW_MULAW: 05077 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) { 05078 if (gain || drc) { 05079 k = AST_MULAW(j); 05080 if (drc) { 05081 k = drc_sample(k, drc); 05082 } 05083 k = (float)k*linear_gain; 05084 if (k > 32767) k = 32767; 05085 if (k < -32767) k = -32767; 05086 g->rxgain[j] = AST_LIN2MU(k); 05087 } else { 05088 g->rxgain[j] = j; 05089 } 05090 } 05091 break; 05092 } 05093 }
static void fill_txgain | ( | struct dahdi_gains * | g, | |
float | gain, | |||
float | drc, | |||
int | law | |||
) | [static] |
Definition at line 5009 of file chan_dahdi.c.
References ARRAY_LEN, AST_ALAW, AST_LIN2A, AST_LIN2MU, AST_MULAW, and drc_sample().
Referenced by set_actual_txgain().
05010 { 05011 int j; 05012 int k; 05013 05014 float linear_gain = pow(10.0, gain / 20.0); 05015 05016 switch (law) { 05017 case DAHDI_LAW_ALAW: 05018 for (j = 0; j < ARRAY_LEN(g->txgain); j++) { 05019 if (gain || drc) { 05020 k = AST_ALAW(j); 05021 if (drc) { 05022 k = drc_sample(k, drc); 05023 } 05024 k = (float)k*linear_gain; 05025 if (k > 32767) k = 32767; 05026 if (k < -32767) k = -32767; 05027 g->txgain[j] = AST_LIN2A(k); 05028 } else { 05029 g->txgain[j] = j; 05030 } 05031 } 05032 break; 05033 case DAHDI_LAW_MULAW: 05034 for (j = 0; j < ARRAY_LEN(g->txgain); j++) { 05035 if (gain || drc) { 05036 k = AST_MULAW(j); 05037 if (drc) { 05038 k = drc_sample(k, drc); 05039 } 05040 k = (float)k*linear_gain; 05041 if (k > 32767) k = 32767; 05042 if (k < -32767) k = -32767; 05043 g->txgain[j] = AST_LIN2MU(k); 05044 05045 } else { 05046 g->txgain[j] = j; 05047 } 05048 } 05049 break; 05050 } 05051 }
static struct dahdi_pvt* find_channel | ( | int | channel | ) | [static] |
Definition at line 15897 of file chan_dahdi.c.
References ast_mutex_lock, dahdi_pvt::channel, iflist, and dahdi_pvt::next.
Referenced by find_channel_from_str().
15898 { 15899 struct dahdi_pvt *p; 15900 15901 ast_mutex_lock(&iflock); 15902 for (p = iflist; p; p = p->next) { 15903 if (p->channel == channel) { 15904 break; 15905 } 15906 } 15907 ast_mutex_unlock(&iflock); 15908 return p; 15909 }
static struct dahdi_pvt* find_channel_from_str | ( | const char * | channel | ) | [static] |
Definition at line 15920 of file chan_dahdi.c.
References find_channel().
Referenced by action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_transfer(), and action_transferhangup().
15921 { 15922 int chan_num; 15923 15924 if (sscanf(channel, "%30d", &chan_num) != 1) { 15925 /* Not numeric string. */ 15926 return NULL; 15927 } 15928 15929 return find_channel(chan_num); 15930 }
Definition at line 5737 of file chan_dahdi.c.
References dahdi_pvt::next, dahdi_pvt::prev, and dahdi_pvt::span.
Referenced by destroy_dahdi_pvt().
05738 { 05739 if (cur->next && cur->next->span == cur->span) { 05740 return cur->next; 05741 } else if (cur->prev && cur->prev->span == cur->span) { 05742 return cur->prev; 05743 } 05744 05745 return NULL; 05746 }
static int get_alarms | ( | struct dahdi_pvt * | p | ) | [static] |
Checks channel for alarms
p | a channel to check for alarms. |
Definition at line 7730 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().
07731 { 07732 int res; 07733 struct dahdi_spaninfo zi; 07734 struct dahdi_params params; 07735 07736 memset(&zi, 0, sizeof(zi)); 07737 zi.spanno = p->span; 07738 07739 if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SPANSTAT, &zi)) >= 0) { 07740 if (zi.alarms != DAHDI_ALARM_NONE) 07741 return zi.alarms; 07742 } else { 07743 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d: %s\n", p->channel, strerror(errno)); 07744 return 0; 07745 } 07746 07747 /* No alarms on the span. Check for channel alarms. */ 07748 memset(¶ms, 0, sizeof(params)); 07749 if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, ¶ms)) >= 0) 07750 return params.chan_alarms; 07751 07752 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 07753 07754 return DAHDI_ALARM_NONE; 07755 }
static void handle_alarms | ( | struct dahdi_pvt * | p, | |
int | alms | |||
) | [static] |
Definition at line 7855 of file chan_dahdi.c.
References alarm2str(), ast_log(), dahdi_pvt::channel, dahdi_sig_pri_lib_handles(), EVENT_FLAG_SYSTEM, manager_event, dahdi_pvt::manages_span_alarms, dahdi_pvt::pri, report_alarms, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, dahdi_pvt::sig, sig_pri_is_alarm_ignored(), 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().
07856 { 07857 const char *alarm_str; 07858 07859 #if defined(HAVE_PRI) 07860 if (dahdi_sig_pri_lib_handles(p->sig) && sig_pri_is_alarm_ignored(p->pri)) { 07861 return; 07862 } 07863 #endif /* defined(HAVE_PRI) */ 07864 07865 alarm_str = alarm2str(alms); 07866 if (report_alarms & REPORT_CHANNEL_ALARMS) { 07867 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str); 07868 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 07869 "Alarm: %s\r\n" 07870 "Channel: %d\r\n", 07871 alarm_str, p->channel); 07872 } 07873 07874 if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) { 07875 ast_log(LOG_WARNING, "Detected alarm on span %d: %s\n", p->span, alarm_str); 07876 manager_event(EVENT_FLAG_SYSTEM, "SpanAlarm", 07877 "Alarm: %s\r\n" 07878 "Span: %d\r\n", 07879 alarm_str, p->span); 07880 } 07881 }
static void handle_clear_alarms | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 3816 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, dahdi_sig_pri_lib_handles(), EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_event, dahdi_pvt::manages_span_alarms, dahdi_pvt::pri, report_alarms, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, dahdi_pvt::sig, sig_pri_is_alarm_ignored(), and dahdi_pvt::span.
Referenced by dahdi_handle_event(), dahdi_r2_on_hardware_alarm(), handle_init_event(), and mwi_thread().
03817 { 03818 #if defined(HAVE_PRI) 03819 if (dahdi_sig_pri_lib_handles(p->sig) && sig_pri_is_alarm_ignored(p->pri)) { 03820 return; 03821 } 03822 #endif /* defined(HAVE_PRI) */ 03823 03824 if (report_alarms & REPORT_CHANNEL_ALARMS) { 03825 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 03826 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel); 03827 } 03828 if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) { 03829 ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", p->span); 03830 manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear", "Span: %d\r\n", p->span); 03831 } 03832 }
static char* handle_dahdi_show_cadences | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 15515 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.
15516 { 15517 int i, j; 15518 switch (cmd) { 15519 case CLI_INIT: 15520 e->command = "dahdi show cadences"; 15521 e->usage = 15522 "Usage: dahdi show cadences\n" 15523 " Shows all cadences currently defined\n"; 15524 return NULL; 15525 case CLI_GENERATE: 15526 return NULL; 15527 } 15528 for (i = 0; i < num_cadence; i++) { 15529 char output[1024]; 15530 char tmp[16], tmp2[64]; 15531 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 15532 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 15533 15534 for (j = 0; j < 16; j++) { 15535 if (cadences[i].ringcadence[j] == 0) 15536 break; 15537 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 15538 if (cidrings[i] * 2 - 1 == j) 15539 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 15540 else 15541 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 15542 if (j != 0) 15543 strncat(output, ",", sizeof(output) - strlen(output) - 1); 15544 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 15545 } 15546 ast_cli(a->fd,"%s\n",output); 15547 } 15548 return CLI_SUCCESS; 15549 }
Definition at line 11433 of file chan_dahdi.c.
References analog_ss_thread(), ast_free, ast_hangup(), ast_log(), ast_mutex_lock, ast_mutex_unlock, 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, dahdi_pvt::lock, 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.
11434 { 11435 int res; 11436 pthread_t threadid; 11437 struct ast_channel *chan; 11438 11439 /* Handle an event on a given channel for the monitor thread. */ 11440 11441 switch (event) { 11442 case DAHDI_EVENT_NONE: 11443 case DAHDI_EVENT_BITSCHANGED: 11444 break; 11445 case DAHDI_EVENT_WINKFLASH: 11446 case DAHDI_EVENT_RINGOFFHOOK: 11447 if (i->inalarm) break; 11448 if (i->radio) break; 11449 /* Got a ring/answer. What kind of channel are we? */ 11450 switch (i->sig) { 11451 case SIG_FXOLS: 11452 case SIG_FXOGS: 11453 case SIG_FXOKS: 11454 res = dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 11455 if (res && (errno == EBUSY)) 11456 break; 11457 11458 /* Cancel VMWI spill */ 11459 ast_free(i->cidspill); 11460 i->cidspill = NULL; 11461 restore_conference(i); 11462 11463 if (i->immediate) { 11464 dahdi_enable_ec(i); 11465 /* The channel is immediately up. Start right away */ 11466 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 11467 chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, NULL); 11468 if (!chan) { 11469 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 11470 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11471 if (res < 0) 11472 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11473 } 11474 } else { 11475 /* Check for callerid, digits, etc */ 11476 chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, NULL); 11477 if (chan) { 11478 if (has_voicemail(i)) 11479 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER); 11480 else 11481 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE); 11482 if (res < 0) 11483 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 11484 if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11485 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11486 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11487 if (res < 0) 11488 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11489 ast_hangup(chan); 11490 } 11491 } else 11492 ast_log(LOG_WARNING, "Unable to create channel\n"); 11493 } 11494 break; 11495 case SIG_FXSLS: 11496 case SIG_FXSGS: 11497 case SIG_FXSKS: 11498 i->ringt = i->ringt_base; 11499 /* Fall through */ 11500 case SIG_EMWINK: 11501 case SIG_FEATD: 11502 case SIG_FEATDMF: 11503 case SIG_FEATDMF_TA: 11504 case SIG_E911: 11505 case SIG_FGC_CAMA: 11506 case SIG_FGC_CAMAMF: 11507 case SIG_FEATB: 11508 case SIG_EM: 11509 case SIG_EM_E1: 11510 case SIG_SFWINK: 11511 case SIG_SF_FEATD: 11512 case SIG_SF_FEATDMF: 11513 case SIG_SF_FEATB: 11514 case SIG_SF: 11515 /* Check for callerid, digits, etc */ 11516 if (i->cid_start == CID_START_POLARITY_IN) { 11517 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11518 } else { 11519 chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, NULL); 11520 } 11521 11522 if (!chan) { 11523 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11524 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11525 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11526 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11527 if (res < 0) { 11528 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11529 } 11530 ast_hangup(chan); 11531 } 11532 break; 11533 default: 11534 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 11535 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11536 if (res < 0) 11537 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11538 return NULL; 11539 } 11540 break; 11541 case DAHDI_EVENT_NOALARM: 11542 switch (i->sig) { 11543 #if defined(HAVE_PRI) 11544 case SIG_PRI_LIB_HANDLE_CASES: 11545 ast_mutex_lock(&i->lock); 11546 sig_pri_chan_alarm_notify(i->sig_pvt, 1); 11547 ast_mutex_unlock(&i->lock); 11548 break; 11549 #endif /* defined(HAVE_PRI) */ 11550 #if defined(HAVE_SS7) 11551 case SIG_SS7: 11552 sig_ss7_set_alarm(i->sig_pvt, 0); 11553 break; 11554 #endif /* defined(HAVE_SS7) */ 11555 default: 11556 i->inalarm = 0; 11557 break; 11558 } 11559 handle_clear_alarms(i); 11560 break; 11561 case DAHDI_EVENT_ALARM: 11562 switch (i->sig) { 11563 #if defined(HAVE_PRI) 11564 case SIG_PRI_LIB_HANDLE_CASES: 11565 ast_mutex_lock(&i->lock); 11566 sig_pri_chan_alarm_notify(i->sig_pvt, 0); 11567 ast_mutex_unlock(&i->lock); 11568 break; 11569 #endif /* defined(HAVE_PRI) */ 11570 #if defined(HAVE_SS7) 11571 case SIG_SS7: 11572 sig_ss7_set_alarm(i->sig_pvt, 1); 11573 break; 11574 #endif /* defined(HAVE_SS7) */ 11575 default: 11576 i->inalarm = 1; 11577 break; 11578 } 11579 res = get_alarms(i); 11580 handle_alarms(i, res); 11581 /* fall thru intentionally */ 11582 case DAHDI_EVENT_ONHOOK: 11583 if (i->radio) 11584 break; 11585 /* Back on hook. Hang up. */ 11586 switch (i->sig) { 11587 case SIG_FXOLS: 11588 case SIG_FXOGS: 11589 case SIG_FEATD: 11590 case SIG_FEATDMF: 11591 case SIG_FEATDMF_TA: 11592 case SIG_E911: 11593 case SIG_FGC_CAMA: 11594 case SIG_FGC_CAMAMF: 11595 case SIG_FEATB: 11596 case SIG_EM: 11597 case SIG_EM_E1: 11598 case SIG_EMWINK: 11599 case SIG_SF_FEATD: 11600 case SIG_SF_FEATDMF: 11601 case SIG_SF_FEATB: 11602 case SIG_SF: 11603 case SIG_SFWINK: 11604 case SIG_FXSLS: 11605 case SIG_FXSGS: 11606 case SIG_FXSKS: 11607 case SIG_FXOKS: 11608 dahdi_disable_ec(i); 11609 /* Diddle the battery for the zhone */ 11610 #ifdef ZHONE_HACK 11611 dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 11612 usleep(1); 11613 #endif 11614 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11615 dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 11616 break; 11617 case SIG_SS7: 11618 case SIG_PRI_LIB_HANDLE_CASES: 11619 dahdi_disable_ec(i); 11620 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11621 break; 11622 default: 11623 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 11624 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11625 return NULL; 11626 } 11627 break; 11628 case DAHDI_EVENT_POLARITY: 11629 switch (i->sig) { 11630 case SIG_FXSLS: 11631 case SIG_FXSKS: 11632 case SIG_FXSGS: 11633 /* We have already got a PR before the channel was 11634 created, but it wasn't handled. We need polarity 11635 to be REV for remote hangup detection to work. 11636 At least in Spain */ 11637 if (i->hanguponpolarityswitch) 11638 i->polarity = POLARITY_REV; 11639 if (i->cid_start == CID_START_POLARITY || i->cid_start == CID_START_POLARITY_IN) { 11640 i->polarity = POLARITY_REV; 11641 ast_verb(2, "Starting post polarity " 11642 "CID detection on channel %d\n", 11643 i->channel); 11644 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11645 if (!chan) { 11646 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11647 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11648 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11649 ast_hangup(chan); 11650 } 11651 } 11652 break; 11653 default: 11654 ast_log(LOG_WARNING, "handle_init_event detected " 11655 "polarity reversal on non-FXO (SIG_FXS) " 11656 "interface %d\n", i->channel); 11657 } 11658 break; 11659 case DAHDI_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */ 11660 ast_log(LOG_NOTICE, 11661 "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n", 11662 i->channel); 11663 return i; 11664 case DAHDI_EVENT_NEONMWI_ACTIVE: 11665 if (i->mwimonitor_neon) { 11666 notify_message(i->mailbox, 1); 11667 ast_log(LOG_NOTICE, "NEON MWI set for channel %d, mailbox %s \n", i->channel, i->mailbox); 11668 } 11669 break; 11670 case DAHDI_EVENT_NEONMWI_INACTIVE: 11671 if (i->mwimonitor_neon) { 11672 notify_message(i->mailbox, 0); 11673 ast_log(LOG_NOTICE, "NEON MWI cleared for channel %d, mailbox %s\n", i->channel, i->mailbox); 11674 } 11675 break; 11676 } 11677 return NULL; 11678 }
static char* handle_mfcr2_call_files | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14882 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.
14883 { 14884 struct dahdi_pvt *p = NULL; 14885 int channo = 0; 14886 switch (cmd) { 14887 case CLI_INIT: 14888 e->command = "mfcr2 call files [on|off]"; 14889 e->usage = 14890 "Usage: mfcr2 call files [on|off] <channel>\n" 14891 " Enable call files creation on the specified channel.\n" 14892 " If no channel is specified call files creation policy will be applied to all channels.\n"; 14893 return NULL; 14894 case CLI_GENERATE: 14895 return NULL; 14896 } 14897 if (a->argc < 4) { 14898 return CLI_SHOWUSAGE; 14899 } 14900 channo = (a->argc == 5) ? atoi(a->argv[4]) : -1; 14901 ast_mutex_lock(&iflock); 14902 for (p = iflist; p; p = p->next) { 14903 if (!(p->sig & SIG_MFCR2) || !p->r2chan) { 14904 continue; 14905 } 14906 if ((channo != -1) && (p->channel != channo )) { 14907 continue; 14908 } 14909 if (ast_true(a->argv[3])) { 14910 openr2_chan_enable_call_files(p->r2chan); 14911 } else { 14912 openr2_chan_disable_call_files(p->r2chan); 14913 } 14914 if (channo != -1) { 14915 if (ast_true(a->argv[3])) { 14916 ast_cli(a->fd, "MFC/R2 call files enabled for channel %d.\n", p->channel); 14917 } else { 14918 ast_cli(a->fd, "MFC/R2 call files disabled for channel %d.\n", p->channel); 14919 } 14920 break; 14921 } 14922 } 14923 if ((channo != -1) && !p) { 14924 ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo); 14925 } 14926 if (channo == -1) { 14927 if (ast_true(a->argv[3])) { 14928 ast_cli(a->fd, "MFC/R2 Call files enabled for all channels.\n"); 14929 } else { 14930 ast_cli(a->fd, "MFC/R2 Call files disabled for all channels.\n"); 14931 } 14932 } 14933 ast_mutex_unlock(&iflock); 14934 return CLI_SUCCESS; 14935 }
static char* handle_mfcr2_set_blocked | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14978 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.
14979 { 14980 struct dahdi_pvt *p = NULL; 14981 int channo = 0; 14982 switch (cmd) { 14983 case CLI_INIT: 14984 e->command = "mfcr2 set blocked"; 14985 e->usage = 14986 "Usage: mfcr2 set blocked <channel>\n" 14987 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n" 14988 " Force the given channel into BLOCKED state.\n" 14989 " If no channel is specified, all channels will be set to BLOCKED.\n"; 14990 return NULL; 14991 case CLI_GENERATE: 14992 return NULL; 14993 } 14994 channo = (a->argc == 4) ? atoi(a->argv[3]) : -1; 14995 ast_mutex_lock(&iflock); 14996 for (p = iflist; p; p = p->next) { 14997 if (!(p->sig & SIG_MFCR2) || !p->r2chan) { 14998 continue; 14999 } 15000 if ((channo != -1) && (p->channel != channo )) { 15001 continue; 15002 } 15003 openr2_chan_set_blocked(p->r2chan); 15004 ast_mutex_lock(&p->lock); 15005 p->locallyblocked = 1; 15006 ast_mutex_unlock(&p->lock); 15007 if (channo != -1) { 15008 break; 15009 } 15010 } 15011 if ((channo != -1) && !p) { 15012 ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo); 15013 } 15014 ast_mutex_unlock(&iflock); 15015 return CLI_SUCCESS; 15016 }
static char* handle_mfcr2_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14817 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.
14818 { 14819 struct dahdi_pvt *p = NULL; 14820 int channo = 0; 14821 char *toklevel = NULL; 14822 char *saveptr = NULL; 14823 char *logval = NULL; 14824 openr2_log_level_t loglevel = OR2_LOG_NOTHING; 14825 openr2_log_level_t tmplevel = OR2_LOG_NOTHING; 14826 switch (cmd) { 14827 case CLI_INIT: 14828 e->command = "mfcr2 set debug"; 14829 e->usage = 14830 "Usage: mfcr2 set debug <loglevel> <channel>\n" 14831 " Set a new logging level for the specified channel.\n" 14832 " If no channel is specified the logging level will be applied to all channels.\n"; 14833 return NULL; 14834 case CLI_GENERATE: 14835 return NULL; 14836 } 14837 if (a->argc < 4) { 14838 return CLI_SHOWUSAGE; 14839 } 14840 channo = (a->argc == 5) ? atoi(a->argv[4]) : -1; 14841 logval = ast_strdupa(a->argv[3]); 14842 toklevel = strtok_r(logval, ",", &saveptr); 14843 if (-1 == (tmplevel = openr2_log_get_level(toklevel))) { 14844 ast_cli(a->fd, "Invalid MFC/R2 logging level '%s'.\n", a->argv[3]); 14845 return CLI_FAILURE; 14846 } else if (OR2_LOG_NOTHING == tmplevel) { 14847 loglevel = tmplevel; 14848 } else { 14849 loglevel |= tmplevel; 14850 while ((toklevel = strtok_r(NULL, ",", &saveptr))) { 14851 if (-1 == (tmplevel = openr2_log_get_level(toklevel))) { 14852 ast_cli(a->fd, "Ignoring invalid logging level: '%s'.\n", toklevel); 14853 continue; 14854 } 14855 loglevel |= tmplevel; 14856 } 14857 } 14858 ast_mutex_lock(&iflock); 14859 for (p = iflist; p; p = p->next) { 14860 if (!(p->sig & SIG_MFCR2) || !p->r2chan) { 14861 continue; 14862 } 14863 if ((channo != -1) && (p->channel != channo )) { 14864 continue; 14865 } 14866 openr2_chan_set_log_level(p->r2chan, loglevel); 14867 if (channo != -1) { 14868 ast_cli(a->fd, "MFC/R2 debugging set to '%s' for channel %d.\n", a->argv[3], p->channel); 14869 break; 14870 } 14871 } 14872 if ((channo != -1) && !p) { 14873 ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo); 14874 } 14875 if (channo == -1) { 14876 ast_cli(a->fd, "MFC/R2 debugging set to '%s' for all channels.\n", a->argv[3]); 14877 } 14878 ast_mutex_unlock(&iflock); 14879 return CLI_SUCCESS; 14880 }
static char* handle_mfcr2_set_idle | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14937 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.
14938 { 14939 struct dahdi_pvt *p = NULL; 14940 int channo = 0; 14941 switch (cmd) { 14942 case CLI_INIT: 14943 e->command = "mfcr2 set idle"; 14944 e->usage = 14945 "Usage: mfcr2 set idle <channel>\n" 14946 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n" 14947 " Force the given channel into IDLE state.\n" 14948 " If no channel is specified, all channels will be set to IDLE.\n"; 14949 return NULL; 14950 case CLI_GENERATE: 14951 return NULL; 14952 } 14953 channo = (a->argc == 4) ? atoi(a->argv[3]) : -1; 14954 ast_mutex_lock(&iflock); 14955 for (p = iflist; p; p = p->next) { 14956 if (!(p->sig & SIG_MFCR2) || !p->r2chan) { 14957 continue; 14958 } 14959 if ((channo != -1) && (p->channel != channo )) { 14960 continue; 14961 } 14962 openr2_chan_set_idle(p->r2chan); 14963 ast_mutex_lock(&p->lock); 14964 p->locallyblocked = 0; 14965 p->mfcr2call = 0; 14966 ast_mutex_unlock(&p->lock); 14967 if (channo != -1) { 14968 break; 14969 } 14970 } 14971 if ((channo != -1) && !p) { 14972 ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo); 14973 } 14974 ast_mutex_unlock(&iflock); 14975 return CLI_SUCCESS; 14976 }
static char* handle_mfcr2_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14743 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.
14744 { 14745 #define FORMAT "%4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n" 14746 int filtertype = 0; 14747 int targetnum = 0; 14748 char channo[5]; 14749 char anino[5]; 14750 char dnisno[5]; 14751 struct dahdi_pvt *p; 14752 openr2_context_t *r2context; 14753 openr2_variant_t r2variant; 14754 switch (cmd) { 14755 case CLI_INIT: 14756 e->command = "mfcr2 show channels [group|context]"; 14757 e->usage = 14758 "Usage: mfcr2 show channels [group <group> | context <context>]\n" 14759 " Shows the DAHDI channels configured with MFC/R2 signaling.\n"; 14760 return NULL; 14761 case CLI_GENERATE: 14762 return NULL; 14763 } 14764 if (!((a->argc == 3) || (a->argc == 5))) { 14765 return CLI_SHOWUSAGE; 14766 } 14767 if (a->argc == 5) { 14768 if (!strcasecmp(a->argv[3], "group")) { 14769 targetnum = atoi(a->argv[4]); 14770 if ((targetnum < 0) || (targetnum > 63)) 14771 return CLI_SHOWUSAGE; 14772 targetnum = 1 << targetnum; 14773 filtertype = 1; 14774 } else if (!strcasecmp(a->argv[3], "context")) { 14775 filtertype = 2; 14776 } else { 14777 return CLI_SHOWUSAGE; 14778 } 14779 } 14780 ast_cli(a->fd, FORMAT, "Chan", "Variant", "Max ANI", "Max DNIS", "ANI First", "Immediate Accept", "Tx CAS", "Rx CAS"); 14781 ast_mutex_lock(&iflock); 14782 for (p = iflist; p; p = p->next) { 14783 if (!(p->sig & SIG_MFCR2) || !p->r2chan) { 14784 continue; 14785 } 14786 if (filtertype) { 14787 switch(filtertype) { 14788 case 1: /* mfcr2 show channels group <group> */ 14789 if (p->group != targetnum) { 14790 continue; 14791 } 14792 break; 14793 case 2: /* mfcr2 show channels context <context> */ 14794 if (strcasecmp(p->context, a->argv[4])) { 14795 continue; 14796 } 14797 break; 14798 default: 14799 ; 14800 } 14801 } 14802 r2context = openr2_chan_get_context(p->r2chan); 14803 r2variant = openr2_context_get_variant(r2context); 14804 snprintf(channo, sizeof(channo), "%d", p->channel); 14805 snprintf(anino, sizeof(anino), "%d", openr2_context_get_max_ani(r2context)); 14806 snprintf(dnisno, sizeof(dnisno), "%d", openr2_context_get_max_dnis(r2context)); 14807 ast_cli(a->fd, FORMAT, channo, openr2_proto_get_variant_string(r2variant), 14808 anino, dnisno, openr2_context_get_ani_first(r2context) ? "Yes" : "No", 14809 openr2_context_get_immediate_accept(r2context) ? "Yes" : "No", 14810 openr2_chan_get_tx_cas_string(p->r2chan), openr2_chan_get_rx_cas_string(p->r2chan)); 14811 } 14812 ast_mutex_unlock(&iflock); 14813 return CLI_SUCCESS; 14814 #undef FORMAT 14815 }
static char* handle_mfcr2_show_variants | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14715 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.
14716 { 14717 #define FORMAT "%4s %40s\n" 14718 int i = 0; 14719 int numvariants = 0; 14720 const openr2_variant_entry_t *variants; 14721 switch (cmd) { 14722 case CLI_INIT: 14723 e->command = "mfcr2 show variants"; 14724 e->usage = 14725 "Usage: mfcr2 show variants\n" 14726 " Shows the list of MFC/R2 variants supported.\n"; 14727 return NULL; 14728 case CLI_GENERATE: 14729 return NULL; 14730 } 14731 if (!(variants = openr2_proto_get_variant_list(&numvariants))) { 14732 ast_cli(a->fd, "Failed to get list of variants.\n"); 14733 return CLI_FAILURE; 14734 } 14735 ast_cli(a->fd, FORMAT, "Variant Code", "Country"); 14736 for (i = 0; i < numvariants; i++) { 14737 ast_cli(a->fd, FORMAT, variants[i].name, variants[i].country); 14738 } 14739 return CLI_SUCCESS; 14740 #undef FORMAT 14741 }
static char* handle_mfcr2_version | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14699 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.
14700 { 14701 switch (cmd) { 14702 case CLI_INIT: 14703 e->command = "mfcr2 show version"; 14704 e->usage = 14705 "Usage: mfcr2 show version\n" 14706 " Shows the version of the OpenR2 library being used.\n"; 14707 return NULL; 14708 case CLI_GENERATE: 14709 return NULL; 14710 } 14711 ast_cli(a->fd, "OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision()); 14712 return CLI_SUCCESS; 14713 }
static char* handle_pri_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14311 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.
14312 { 14313 int span; 14314 int x; 14315 int level = 0; 14316 switch (cmd) { 14317 case CLI_INIT: 14318 e->command = "pri set debug {on|off|0|1|2} span"; 14319 e->usage = 14320 "Usage: pri set debug {<level>|on|off} span <span>\n" 14321 " Enables debugging on a given PRI span\n"; 14322 return NULL; 14323 case CLI_GENERATE: 14324 return complete_span_4(a->line, a->word, a->pos, a->n); 14325 } 14326 if (a->argc < 6) { 14327 return CLI_SHOWUSAGE; 14328 } 14329 14330 if (!strcasecmp(a->argv[3], "on")) { 14331 level = 1; 14332 } else if (!strcasecmp(a->argv[3], "off")) { 14333 level = 0; 14334 } else { 14335 level = atoi(a->argv[3]); 14336 } 14337 span = atoi(a->argv[5]); 14338 if ((span < 1) || (span > NUM_SPANS)) { 14339 ast_cli(a->fd, "Invalid span %s. Should be a number %d to %d\n", a->argv[5], 1, NUM_SPANS); 14340 return CLI_SUCCESS; 14341 } 14342 if (!pris[span-1].pri.pri) { 14343 ast_cli(a->fd, "No PRI running on span %d\n", span); 14344 return CLI_SUCCESS; 14345 } 14346 14347 /* Set debug level in libpri */ 14348 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 14349 if (pris[span - 1].pri.dchans[x]) { 14350 switch (level) { 14351 case 0: 14352 pri_set_debug(pris[span - 1].pri.dchans[x], 0); 14353 break; 14354 case 1: 14355 pri_set_debug(pris[span - 1].pri.dchans[x], SIG_PRI_DEBUG_NORMAL); 14356 break; 14357 default: 14358 pri_set_debug(pris[span - 1].pri.dchans[x], SIG_PRI_DEBUG_INTENSE); 14359 break; 14360 } 14361 } 14362 } 14363 if (level == 0) { 14364 /* Close the debugging file if it's set */ 14365 ast_mutex_lock(&pridebugfdlock); 14366 if (0 <= pridebugfd) { 14367 close(pridebugfd); 14368 pridebugfd = -1; 14369 ast_cli(a->fd, "Disabled PRI debug output to file '%s'\n", 14370 pridebugfilename); 14371 } 14372 ast_mutex_unlock(&pridebugfdlock); 14373 } 14374 pris[span - 1].pri.debug = (level) ? 1 : 0; 14375 ast_cli(a->fd, "%s debugging on span %d\n", (level) ? "Enabled" : "Disabled", span); 14376 return CLI_SUCCESS; 14377 }
static char* handle_pri_service_disable_channel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14506 of file chan_dahdi.c.
References CLI_GENERATE, CLI_INIT, ast_cli_entry::command, handle_pri_service_generic(), and ast_cli_entry::usage.
14507 { 14508 switch (cmd) { 14509 case CLI_INIT: 14510 e->command = "pri service disable channel"; 14511 e->usage = 14512 "Usage: pri service disable channel <chan num> [<interface id>]\n" 14513 " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n" 14514 " to remove a channel from service, with optional interface id\n" 14515 " as agreed upon with remote switch operator\n"; 14516 return NULL; 14517 case CLI_GENERATE: 14518 return NULL; 14519 } 14520 return handle_pri_service_generic(e, cmd, a, 2); 14521 }
static char* handle_pri_service_enable_channel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14489 of file chan_dahdi.c.
References CLI_GENERATE, CLI_INIT, ast_cli_entry::command, handle_pri_service_generic(), and ast_cli_entry::usage.
14490 { 14491 switch (cmd) { 14492 case CLI_INIT: 14493 e->command = "pri service enable channel"; 14494 e->usage = 14495 "Usage: pri service enable channel <channel> [<interface id>]\n" 14496 " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n" 14497 " to restore a channel to service, with optional interface id\n" 14498 " as agreed upon with remote switch operator\n"; 14499 return NULL; 14500 case CLI_GENERATE: 14501 return NULL; 14502 } 14503 return handle_pri_service_generic(e, cmd, a, 0); 14504 }
static char* handle_pri_service_generic | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a, | |||
int | changestatus | |||
) | [static] |
Definition at line 14382 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().
14383 { 14384 unsigned *why; 14385 int channel; 14386 int trunkgroup; 14387 int x, y, fd = a->fd; 14388 int interfaceid = 0; 14389 char db_chan_name[20], db_answer[5]; 14390 struct dahdi_pvt *tmp; 14391 struct dahdi_pri *pri; 14392 14393 if (a->argc < 5 || a->argc > 6) 14394 return CLI_SHOWUSAGE; 14395 if (strchr(a->argv[4], ':')) { 14396 if (sscanf(a->argv[4], "%30d:%30d", &trunkgroup, &channel) != 2) 14397 return CLI_SHOWUSAGE; 14398 if ((trunkgroup < 1) || (channel < 1)) 14399 return CLI_SHOWUSAGE; 14400 pri = NULL; 14401 for (x=0;x<NUM_SPANS;x++) { 14402 if (pris[x].pri.trunkgroup == trunkgroup) { 14403 pri = pris + x; 14404 break; 14405 } 14406 } 14407 if (!pri) { 14408 ast_cli(fd, "No such trunk group %d\n", trunkgroup); 14409 return CLI_FAILURE; 14410 } 14411 } else 14412 channel = atoi(a->argv[4]); 14413 14414 if (a->argc == 6) 14415 interfaceid = atoi(a->argv[5]); 14416 14417 /* either servicing a D-Channel */ 14418 for (x = 0; x < NUM_SPANS; x++) { 14419 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 14420 if (pris[x].dchannels[y] == channel) { 14421 pri = pris + x; 14422 if (pri->pri.enable_service_message_support) { 14423 ast_mutex_lock(&pri->pri.lock); 14424 pri_maintenance_service(pri->pri.pri, interfaceid, -1, changestatus); 14425 ast_mutex_unlock(&pri->pri.lock); 14426 } else { 14427 ast_cli(fd, 14428 "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n" 14429 "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n"); 14430 } 14431 return CLI_SUCCESS; 14432 } 14433 } 14434 } 14435 14436 /* or servicing a B-Channel */ 14437 ast_mutex_lock(&iflock); 14438 for (tmp = iflist; tmp; tmp = tmp->next) { 14439 if (tmp->pri && tmp->channel == channel) { 14440 ast_mutex_unlock(&iflock); 14441 ast_mutex_lock(&tmp->pri->lock); 14442 if (!tmp->pri->enable_service_message_support) { 14443 ast_mutex_unlock(&tmp->pri->lock); 14444 ast_cli(fd, 14445 "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n" 14446 "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n"); 14447 return CLI_SUCCESS; 14448 } 14449 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, tmp->span, channel); 14450 why = &((struct sig_pri_chan *) tmp->sig_pvt)->service_status; 14451 switch(changestatus) { 14452 case 0: /* enable */ 14453 /* Near end wants to be in service now. */ 14454 ast_db_del(db_chan_name, SRVST_DBKEY); 14455 *why &= ~SRVST_NEAREND; 14456 if (*why) { 14457 snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS, *why); 14458 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer); 14459 } else { 14460 dahdi_pri_update_span_devstate(tmp->pri); 14461 } 14462 break; 14463 /* case 1: -- loop */ 14464 case 2: /* disable */ 14465 /* Near end wants to be out-of-service now. */ 14466 ast_db_del(db_chan_name, SRVST_DBKEY); 14467 *why |= SRVST_NEAREND; 14468 snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS, *why); 14469 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer); 14470 dahdi_pri_update_span_devstate(tmp->pri); 14471 break; 14472 /* case 3: -- continuity */ 14473 /* case 4: -- shutdown */ 14474 default: 14475 ast_log(LOG_WARNING, "Unsupported changestatus: '%d'\n", changestatus); 14476 break; 14477 } 14478 pri_maintenance_bservice(tmp->pri->pri, tmp->sig_pvt, changestatus); 14479 ast_mutex_unlock(&tmp->pri->lock); 14480 return CLI_SUCCESS; 14481 } 14482 } 14483 ast_mutex_unlock(&iflock); 14484 14485 ast_cli(fd, "Unable to find given channel %d, possibly not a PRI\n", channel); 14486 return CLI_FAILURE; 14487 }
static char* handle_pri_set_debug_file | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14273 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.
14274 { 14275 int myfd; 14276 switch (cmd) { 14277 case CLI_INIT: 14278 e->command = "pri set debug file"; 14279 e->usage = "Usage: pri set debug file [output-file]\n" 14280 " Sends PRI debug output to the specified output file\n"; 14281 return NULL; 14282 case CLI_GENERATE: 14283 return NULL; 14284 } 14285 if (a->argc < 5) 14286 return CLI_SHOWUSAGE; 14287 14288 if (ast_strlen_zero(a->argv[4])) 14289 return CLI_SHOWUSAGE; 14290 14291 myfd = open(a->argv[4], O_CREAT|O_WRONLY, AST_FILE_MODE); 14292 if (myfd < 0) { 14293 ast_cli(a->fd, "Unable to open '%s' for writing\n", a->argv[4]); 14294 return CLI_SUCCESS; 14295 } 14296 14297 ast_mutex_lock(&pridebugfdlock); 14298 14299 if (pridebugfd >= 0) 14300 close(pridebugfd); 14301 14302 pridebugfd = myfd; 14303 ast_copy_string(pridebugfilename,a->argv[4],sizeof(pridebugfilename)); 14304 ast_mutex_unlock(&pridebugfdlock); 14305 ast_cli(a->fd, "PRI debug output will be sent to '%s'\n", a->argv[4]); 14306 return CLI_SUCCESS; 14307 }
static char* handle_pri_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14526 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_channels(), sig_pri_cli_show_channels_header(), and ast_cli_entry::usage.
14527 { 14528 int span; 14529 14530 switch (cmd) { 14531 case CLI_INIT: 14532 e->command = "pri show channels"; 14533 e->usage = 14534 "Usage: pri show channels\n" 14535 " Displays PRI channel information such as the current mapping\n" 14536 " of DAHDI B channels to Asterisk channel names and which calls\n" 14537 " are on hold or call-waiting. Calls on hold or call-waiting\n" 14538 " are not associated with any B channel.\n"; 14539 return NULL; 14540 case CLI_GENERATE: 14541 return NULL; 14542 } 14543 14544 if (a->argc != 3) 14545 return CLI_SHOWUSAGE; 14546 14547 sig_pri_cli_show_channels_header(a->fd); 14548 for (span = 0; span < NUM_SPANS; ++span) { 14549 if (pris[span].pri.pri) { 14550 sig_pri_cli_show_channels(a->fd, &pris[span].pri); 14551 } 14552 } 14553 return CLI_SUCCESS; 14554 }
static char* handle_pri_show_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14620 of file chan_dahdi.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, ast_cli_entry::command, sig_pri_span::dchans, ast_cli_args::fd, sig_pri_span::pri, sig_pri_chan::pri, pris, and ast_cli_entry::usage.
14621 { 14622 int x; 14623 int span; 14624 int count=0; 14625 int debug; 14626 14627 switch (cmd) { 14628 case CLI_INIT: 14629 e->command = "pri show debug"; 14630 e->usage = 14631 "Usage: pri show debug\n" 14632 " Show the debug state of pri spans\n"; 14633 return NULL; 14634 case CLI_GENERATE: 14635 return NULL; 14636 } 14637 14638 for (span = 0; span < NUM_SPANS; span++) { 14639 if (pris[span].pri.pri) { 14640 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) { 14641 if (pris[span].pri.dchans[x]) { 14642 debug = pri_get_debug(pris[span].pri.dchans[x]); 14643 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" ); 14644 count++; 14645 } 14646 } 14647 } 14648 14649 } 14650 ast_mutex_lock(&pridebugfdlock); 14651 if (pridebugfd >= 0) 14652 ast_cli(a->fd, "Logging PRI debug to file %s\n", pridebugfilename); 14653 ast_mutex_unlock(&pridebugfdlock); 14654 14655 if (!count) 14656 ast_cli(a->fd, "No PRI running\n"); 14657 return CLI_SUCCESS; 14658 }
static char* handle_pri_show_span | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14586 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.
14587 { 14588 int span; 14589 14590 switch (cmd) { 14591 case CLI_INIT: 14592 e->command = "pri show span"; 14593 e->usage = 14594 "Usage: pri show span <span>\n" 14595 " Displays PRI Information on a given PRI span\n"; 14596 return NULL; 14597 case CLI_GENERATE: 14598 return complete_span_4(a->line, a->word, a->pos, a->n); 14599 } 14600 14601 if (a->argc < 4) 14602 return CLI_SHOWUSAGE; 14603 span = atoi(a->argv[3]); 14604 if ((span < 1) || (span > NUM_SPANS)) { 14605 ast_cli(a->fd, "Invalid span '%s'. Should be a number from %d to %d\n", a->argv[3], 1, NUM_SPANS); 14606 return CLI_SUCCESS; 14607 } 14608 if (!pris[span-1].pri.pri) { 14609 ast_cli(a->fd, "No PRI running on span %d\n", span); 14610 return CLI_SUCCESS; 14611 } 14612 14613 sig_pri_cli_show_span(a->fd, pris[span-1].dchannels, &pris[span-1].pri); 14614 14615 return CLI_SUCCESS; 14616 }
static char* handle_pri_show_spans | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14558 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.
14559 { 14560 int span; 14561 14562 switch (cmd) { 14563 case CLI_INIT: 14564 e->command = "pri show spans"; 14565 e->usage = 14566 "Usage: pri show spans\n" 14567 " Displays PRI span information\n"; 14568 return NULL; 14569 case CLI_GENERATE: 14570 return NULL; 14571 } 14572 14573 if (a->argc != 3) 14574 return CLI_SHOWUSAGE; 14575 14576 for (span = 0; span < NUM_SPANS; span++) { 14577 if (pris[span].pri.pri) { 14578 sig_pri_cli_show_spans(a->fd, span + 1, &pris[span].pri); 14579 } 14580 } 14581 return CLI_SUCCESS; 14582 }
static char* handle_pri_version | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 14662 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.
14663 { 14664 switch (cmd) { 14665 case CLI_INIT: 14666 e->command = "pri show version"; 14667 e->usage = 14668 "Usage: pri show version\n" 14669 "Show libpri version information\n"; 14670 return NULL; 14671 case CLI_GENERATE: 14672 return NULL; 14673 } 14674 14675 ast_cli(a->fd, "libpri version: %s\n", pri_get_version()); 14676 14677 return CLI_SUCCESS; 14678 }
static int has_voicemail | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5272 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().
05273 { 05274 int new_msgs; 05275 struct ast_event *event; 05276 char *mailbox, *context; 05277 05278 mailbox = context = ast_strdupa(p->mailbox); 05279 strsep(&context, "@"); 05280 if (ast_strlen_zero(context)) 05281 context = "default"; 05282 05283 event = ast_event_get_cached(AST_EVENT_MWI, 05284 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 05285 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 05286 AST_EVENT_IE_END); 05287 05288 if (event) { 05289 new_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 05290 ast_event_destroy(event); 05291 } else 05292 new_msgs = ast_app_has_voicemail(p->mailbox, NULL); 05293 05294 return new_msgs; 05295 }
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 13181 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().
13182 { 13183 #if defined(HAVE_PRI) 13184 if (0 < span) { 13185 /* The channel must be on the specified PRI span. */ 13186 if (!p->pri || p->pri->span != span) { 13187 return 0; 13188 } 13189 if (!groupmatch && channelmatch == -1) { 13190 /* Match any group since it only needs to be on the PRI span. */ 13191 *groupmatched = 1; 13192 return 1; 13193 } 13194 } 13195 #endif /* defined(HAVE_PRI) */ 13196 /* check group matching */ 13197 if (groupmatch) { 13198 if ((p->group & groupmatch) != groupmatch) 13199 /* Doesn't match the specified group, try the next one */ 13200 return 0; 13201 *groupmatched = 1; 13202 } 13203 /* Check to see if we have a channel match */ 13204 if (channelmatch != -1) { 13205 if (p->channel != channelmatch) 13206 /* Doesn't match the specified channel, try the next one */ 13207 return 0; 13208 *channelmatched = 1; 13209 } 13210 13211 return 1; 13212 }
static int isourconf | ( | struct dahdi_pvt * | p, | |
struct dahdi_subchannel * | c | |||
) | [static] |
Definition at line 4754 of file chan_dahdi.c.
References dahdi_pvt::channel, dahdi_pvt::confno, and dahdi_subchannel::curconf.
Referenced by conf_del().
04755 { 04756 /* If they're listening to our channel, they're ours */ 04757 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON)) 04758 return 1; 04759 /* If they're a talker on our (allocated) conference, they're ours */ 04760 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER)) 04761 return 1; 04762 return 0; 04763 }
Definition at line 4784 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().
04785 { 04786 int x; 04787 int useslavenative; 04788 struct dahdi_pvt *slave = NULL; 04789 /* Start out optimistic */ 04790 useslavenative = 1; 04791 /* Update conference state in a stateless fashion */ 04792 for (x = 0; x < 3; x++) { 04793 /* Any three-way calling makes slave native mode *definitely* out 04794 of the question */ 04795 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) 04796 useslavenative = 0; 04797 } 04798 /* If we don't have any 3-way calls, check to see if we have 04799 precisely one slave */ 04800 if (useslavenative) { 04801 for (x = 0; x < MAX_SLAVES; x++) { 04802 if (p->slaves[x]) { 04803 if (slave) { 04804 /* Whoops already have a slave! No 04805 slave native and stop right away */ 04806 slave = NULL; 04807 useslavenative = 0; 04808 break; 04809 } else { 04810 /* We have one slave so far */ 04811 slave = p->slaves[x]; 04812 } 04813 } 04814 } 04815 } 04816 /* If no slave, slave native definitely out */ 04817 if (!slave) 04818 useslavenative = 0; 04819 else if (slave->law != p->law) { 04820 useslavenative = 0; 04821 slave = NULL; 04822 } 04823 if (out) 04824 *out = slave; 04825 return useslavenative; 04826 }
static int load_module | ( | void | ) | [static] |
Definition at line 18569 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_cc_agent_callbacks, dahdi_pri_cc_monitor_callbacks, dahdi_pri_cc_type, dahdi_pri_cli, dahdi_pri_error(), dahdi_pri_message(), dahdi_send_callrerouting_facility_exec(), dahdi_send_keypad_facility_exec(), dahdi_tech, HAVE_PRI_CCSS, round_robin, setup_dahdi(), sig_pri_init_pri(), sig_pri_load(), sig_ss7_init_linkset(), and ss_thread_complete.
18570 { 18571 int res; 18572 #if defined(HAVE_PRI) || defined(HAVE_SS7) 18573 int y; 18574 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 18575 18576 #ifdef HAVE_PRI 18577 memset(pris, 0, sizeof(pris)); 18578 for (y = 0; y < NUM_SPANS; y++) { 18579 sig_pri_init_pri(&pris[y].pri); 18580 } 18581 pri_set_error(dahdi_pri_error); 18582 pri_set_message(dahdi_pri_message); 18583 ast_register_application_xml(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec); 18584 #ifdef HAVE_PRI_PROG_W_CAUSE 18585 ast_register_application_xml(dahdi_send_callrerouting_facility_app, dahdi_send_callrerouting_facility_exec); 18586 #endif 18587 #if defined(HAVE_PRI_CCSS) 18588 if (ast_cc_agent_register(&dahdi_pri_cc_agent_callbacks) 18589 || ast_cc_monitor_register(&dahdi_pri_cc_monitor_callbacks)) { 18590 __unload_module(); 18591 return AST_MODULE_LOAD_FAILURE; 18592 } 18593 #endif /* defined(HAVE_PRI_CCSS) */ 18594 if (sig_pri_load( 18595 #if defined(HAVE_PRI_CCSS) 18596 dahdi_pri_cc_type 18597 #else 18598 NULL 18599 #endif /* defined(HAVE_PRI_CCSS) */ 18600 )) { 18601 __unload_module(); 18602 return AST_MODULE_LOAD_FAILURE; 18603 } 18604 #endif 18605 #if defined(HAVE_SS7) 18606 memset(linksets, 0, sizeof(linksets)); 18607 for (y = 0; y < NUM_SPANS; y++) { 18608 sig_ss7_init_linkset(&linksets[y].ss7); 18609 } 18610 ss7_set_error(dahdi_ss7_error); 18611 ss7_set_message(dahdi_ss7_message); 18612 #endif /* defined(HAVE_SS7) */ 18613 res = setup_dahdi(0); 18614 /* Make sure we can register our DAHDI channel type */ 18615 if (res) 18616 return AST_MODULE_LOAD_DECLINE; 18617 if (ast_channel_register(&dahdi_tech)) { 18618 ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n"); 18619 __unload_module(); 18620 return AST_MODULE_LOAD_FAILURE; 18621 } 18622 #ifdef HAVE_PRI 18623 ast_cli_register_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli)); 18624 #endif 18625 #if defined(HAVE_SS7) 18626 ast_cli_register_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli)); 18627 #endif /* defined(HAVE_SS7) */ 18628 #ifdef HAVE_OPENR2 18629 ast_cli_register_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli)); 18630 ast_register_application_xml(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec); 18631 #endif 18632 18633 ast_cli_register_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli)); 18634 /* register all the data providers */ 18635 ast_data_register_multiple(dahdi_data_providers, ARRAY_LEN(dahdi_data_providers)); 18636 memset(round_robin, 0, sizeof(round_robin)); 18637 ast_manager_register_xml("DAHDITransfer", 0, action_transfer); 18638 ast_manager_register_xml("DAHDIHangup", 0, action_transferhangup); 18639 ast_manager_register_xml("DAHDIDialOffhook", 0, action_dahdidialoffhook); 18640 ast_manager_register_xml("DAHDIDNDon", 0, action_dahdidndon); 18641 ast_manager_register_xml("DAHDIDNDoff", 0, action_dahdidndoff); 18642 ast_manager_register_xml("DAHDIShowChannels", 0, action_dahdishowchannels); 18643 ast_manager_register_xml("DAHDIRestart", 0, action_dahdirestart); 18644 18645 ast_cond_init(&ss_thread_complete, NULL); 18646 18647 return res; 18648 }
static void* mfcr2_monitor | ( | void * | data | ) | [static] |
Definition at line 14004 of file chan_dahdi.c.
References ast_log(), LOG_DEBUG, and SUB_REAL.
14005 { 14006 struct dahdi_mfcr2 *mfcr2 = data; 14007 /* we should be using pthread_key_create 14008 and allocate pollers dynamically. 14009 I think do_monitor() could be leaking, since it 14010 could be cancelled at any time and is not 14011 using thread keys, why?, */ 14012 struct pollfd pollers[ARRAY_LEN(mfcr2->pvts)]; 14013 int res = 0; 14014 int i = 0; 14015 int oldstate = 0; 14016 int quit_loop = 0; 14017 int maxsleep = 20; 14018 int was_idle = 0; 14019 int pollsize = 0; 14020 /* now that we're ready to get calls, unblock our side and 14021 get current line state */ 14022 for (i = 0; i < mfcr2->numchans; i++) { 14023 openr2_chan_set_idle(mfcr2->pvts[i]->r2chan); 14024 openr2_chan_handle_cas(mfcr2->pvts[i]->r2chan); 14025 } 14026 while (1) { 14027 /* we trust here that the mfcr2 channel list will not ever change once 14028 the module is loaded */ 14029 pollsize = 0; 14030 for (i = 0; i < mfcr2->numchans; i++) { 14031 pollers[i].revents = 0; 14032 pollers[i].events = 0; 14033 if (mfcr2->pvts[i]->owner) { 14034 continue; 14035 } 14036 if (!mfcr2->pvts[i]->r2chan) { 14037 ast_log(LOG_DEBUG, "Wow, no r2chan on channel %d\n", mfcr2->pvts[i]->channel); 14038 quit_loop = 1; 14039 break; 14040 } 14041 openr2_chan_enable_read(mfcr2->pvts[i]->r2chan); 14042 pollers[i].events = POLLIN | POLLPRI; 14043 pollers[i].fd = mfcr2->pvts[i]->subs[SUB_REAL].dfd; 14044 pollsize++; 14045 } 14046 if (quit_loop) { 14047 break; 14048 } 14049 if (pollsize == 0) { 14050 if (!was_idle) { 14051 ast_log(LOG_DEBUG, "Monitor thread going idle since everybody has an owner\n"); 14052 was_idle = 1; 14053 } 14054 poll(NULL, 0, maxsleep); 14055 continue; 14056 } 14057 was_idle = 0; 14058 /* probably poll() is a valid cancel point, lets just be on the safe side 14059 by calling pthread_testcancel */ 14060 pthread_testcancel(); 14061 res = poll(pollers, mfcr2->numchans, maxsleep); 14062 pthread_testcancel(); 14063 if ((res < 0) && (errno != EINTR)) { 14064 ast_log(LOG_ERROR, "going out, poll failed: %s\n", strerror(errno)); 14065 break; 14066 } 14067 /* do we want to allow to cancel while processing events? */ 14068 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); 14069 for (i = 0; i < mfcr2->numchans; i++) { 14070 if (pollers[i].revents & POLLPRI || pollers[i].revents & POLLIN) { 14071 openr2_chan_process_event(mfcr2->pvts[i]->r2chan); 14072 } 14073 } 14074 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); 14075 } 14076 ast_log(LOG_NOTICE, "Quitting MFC/R2 monitor thread\n"); 14077 return 0; 14078 }
static struct dahdi_pvt* mkintf | ( | int | channel, | |
const struct dahdi_chan_conf * | conf, | |||
int | reloading | |||
) | [static] |
Definition at line 12290 of file chan_dahdi.c.
References dahdi_pvt::channel, dahdi_pvt::destroy, iflist, and dahdi_pvt::next.
Referenced by build_channels().
12291 { 12292 /* Make a dahdi_pvt structure for this interface */ 12293 struct dahdi_pvt *tmp;/*!< Current channel structure initializing */ 12294 char fn[80]; 12295 struct dahdi_bufferinfo bi; 12296 12297 int res; 12298 #if defined(HAVE_PRI) 12299 int span = 0; 12300 #endif /* defined(HAVE_PRI) */ 12301 int here = 0;/*!< TRUE if the channel interface already exists. */ 12302 int x; 12303 struct analog_pvt *analog_p = NULL; 12304 struct dahdi_params p; 12305 #if defined(HAVE_PRI) 12306 struct dahdi_spaninfo si; 12307 struct sig_pri_chan *pri_chan = NULL; 12308 #endif /* defined(HAVE_PRI) */ 12309 #if defined(HAVE_SS7) 12310 struct sig_ss7_chan *ss7_chan = NULL; 12311 #endif /* defined(HAVE_SS7) */ 12312 12313 /* Search channel interface list to see if it already exists. */ 12314 for (tmp = iflist; tmp; tmp = tmp->next) { 12315 if (!tmp->destroy) { 12316 if (tmp->channel == channel) { 12317 /* The channel interface already exists. */ 12318 here = 1; 12319 break; 12320 } 12321 if (tmp->channel > channel) { 12322 /* No way it can be in the sorted list. */ 12323 tmp = NULL; 12324 break; 12325 } 12326 } 12327 } 12328 12329 if (!here && reloading != 1) { 12330 tmp = ast_calloc(1, sizeof(*tmp)); 12331 if (!tmp) { 12332 return NULL; 12333 } 12334 tmp->cc_params = ast_cc_config_params_init(); 12335 if (!tmp->cc_params) { 12336 ast_free(tmp); 12337 return NULL; 12338 } 12339 ast_mutex_init(&tmp->lock); 12340 ifcount++; 12341 for (x = 0; x < 3; x++) 12342 tmp->subs[x].dfd = -1; 12343 tmp->channel = channel; 12344 tmp->priindication_oob = conf->chan.priindication_oob; 12345 } 12346 12347 if (tmp) { 12348 int chan_sig = conf->chan.sig; 12349 12350 /* If there are variables in tmp before it is updated to match the new config, clear them */ 12351 if (reloading && tmp->vars) { 12352 ast_variables_destroy(tmp->vars); 12353 tmp->vars = NULL; 12354 } 12355 12356 12357 if (!here) { 12358 /* Can only get here if this is a new channel interface being created. */ 12359 if ((channel != CHAN_PSEUDO)) { 12360 int count = 0; 12361 12362 snprintf(fn, sizeof(fn), "%d", channel); 12363 /* Open non-blocking */ 12364 tmp->subs[SUB_REAL].dfd = dahdi_open(fn); 12365 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 */ 12366 usleep(1); 12367 tmp->subs[SUB_REAL].dfd = dahdi_open(fn); 12368 count++; 12369 } 12370 /* Allocate a DAHDI structure */ 12371 if (tmp->subs[SUB_REAL].dfd < 0) { 12372 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); 12373 destroy_dahdi_pvt(tmp); 12374 return NULL; 12375 } 12376 memset(&p, 0, sizeof(p)); 12377 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 12378 if (res < 0) { 12379 ast_log(LOG_ERROR, "Unable to get parameters: %s\n", strerror(errno)); 12380 destroy_dahdi_pvt(tmp); 12381 return NULL; 12382 } 12383 if (conf->is_sig_auto) 12384 chan_sig = sigtype_to_signalling(p.sigtype); 12385 if (p.sigtype != (chan_sig & 0x3ffff)) { 12386 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)); 12387 destroy_dahdi_pvt(tmp); 12388 return NULL; 12389 } 12390 tmp->law_default = p.curlaw; 12391 tmp->law = p.curlaw; 12392 tmp->span = p.spanno; 12393 #if defined(HAVE_PRI) 12394 span = p.spanno - 1; 12395 #endif /* defined(HAVE_PRI) */ 12396 } else { 12397 chan_sig = 0; 12398 } 12399 tmp->sig = chan_sig; 12400 tmp->outsigmod = conf->chan.outsigmod; 12401 12402 if (analog_lib_handles(chan_sig, tmp->radio, tmp->oprmode)) { 12403 analog_p = analog_new(dahdisig_to_analogsig(chan_sig), &dahdi_analog_callbacks, tmp); 12404 if (!analog_p) { 12405 destroy_dahdi_pvt(tmp); 12406 return NULL; 12407 } 12408 tmp->sig_pvt = analog_p; 12409 } 12410 #if defined(HAVE_SS7) 12411 if (chan_sig == SIG_SS7) { 12412 struct dahdi_ss7 *ss7; 12413 int clear = 0; 12414 12415 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &clear)) { 12416 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 12417 destroy_dahdi_pvt(tmp); 12418 return NULL; 12419 } 12420 12421 ss7 = ss7_resolve_linkset(cur_linkset); 12422 if (!ss7) { 12423 ast_log(LOG_ERROR, "Unable to find linkset %d\n", cur_linkset); 12424 destroy_dahdi_pvt(tmp); 12425 return NULL; 12426 } 12427 ss7->ss7.span = cur_linkset; 12428 if (cur_cicbeginswith < 0) { 12429 ast_log(LOG_ERROR, "Need to set cicbeginswith for the channels!\n"); 12430 destroy_dahdi_pvt(tmp); 12431 return NULL; 12432 } 12433 ss7_chan = sig_ss7_chan_new(tmp, &dahdi_ss7_callbacks, &ss7->ss7); 12434 if (!ss7_chan) { 12435 destroy_dahdi_pvt(tmp); 12436 return NULL; 12437 } 12438 tmp->sig_pvt = ss7_chan; 12439 tmp->ss7 = &ss7->ss7; 12440 12441 ss7_chan->channel = tmp->channel; 12442 ss7_chan->cic = cur_cicbeginswith++; 12443 12444 /* DB: Add CIC's DPC information */ 12445 ss7_chan->dpc = cur_defaultdpc; 12446 12447 ss7->ss7.pvts[ss7->ss7.numchans++] = ss7_chan; 12448 12449 ast_copy_string(ss7->ss7.internationalprefix, conf->ss7.ss7.internationalprefix, sizeof(ss7->ss7.internationalprefix)); 12450 ast_copy_string(ss7->ss7.nationalprefix, conf->ss7.ss7.nationalprefix, sizeof(ss7->ss7.nationalprefix)); 12451 ast_copy_string(ss7->ss7.subscriberprefix, conf->ss7.ss7.subscriberprefix, sizeof(ss7->ss7.subscriberprefix)); 12452 ast_copy_string(ss7->ss7.unknownprefix, conf->ss7.ss7.unknownprefix, sizeof(ss7->ss7.unknownprefix)); 12453 12454 ss7->ss7.called_nai = conf->ss7.ss7.called_nai; 12455 ss7->ss7.calling_nai = conf->ss7.ss7.calling_nai; 12456 } 12457 #endif /* defined(HAVE_SS7) */ 12458 #ifdef HAVE_OPENR2 12459 if (chan_sig == SIG_MFCR2) { 12460 struct dahdi_mfcr2 *r2_link; 12461 r2_link = dahdi_r2_get_link(); 12462 if (!r2_link) { 12463 ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n"); 12464 destroy_dahdi_pvt(tmp); 12465 return NULL; 12466 } 12467 if (!r2_link->protocol_context && dahdi_r2_set_context(r2_link, conf)) { 12468 ast_log(LOG_ERROR, "Cannot create OpenR2 protocol context.\n"); 12469 destroy_dahdi_pvt(tmp); 12470 return NULL; 12471 } 12472 if (r2_link->numchans == ARRAY_LEN(r2_link->pvts)) { 12473 ast_log(LOG_ERROR, "Cannot add more channels to this link!\n"); 12474 destroy_dahdi_pvt(tmp); 12475 return NULL; 12476 } 12477 r2_link->pvts[r2_link->numchans++] = tmp; 12478 tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context, 12479 tmp->subs[SUB_REAL].dfd, 12480 NULL, NULL); 12481 if (!tmp->r2chan) { 12482 openr2_liberr_t err = openr2_context_get_last_error(r2_link->protocol_context); 12483 ast_log(LOG_ERROR, "Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err)); 12484 destroy_dahdi_pvt(tmp); 12485 return NULL; 12486 } 12487 tmp->mfcr2 = r2_link; 12488 if (conf->mfcr2.call_files) { 12489 openr2_chan_enable_call_files(tmp->r2chan); 12490 } 12491 openr2_chan_set_client_data(tmp->r2chan, tmp); 12492 /* cast seems to be needed to get rid of the annoying warning regarding format attribute */ 12493 openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log); 12494 openr2_chan_set_log_level(tmp->r2chan, conf->mfcr2.loglevel); 12495 tmp->mfcr2_category = conf->mfcr2.category; 12496 tmp->mfcr2_charge_calls = conf->mfcr2.charge_calls; 12497 tmp->mfcr2_allow_collect_calls = conf->mfcr2.allow_collect_calls; 12498 tmp->mfcr2_forced_release = conf->mfcr2.forced_release; 12499 tmp->mfcr2_accept_on_offer = conf->mfcr2.accept_on_offer; 12500 tmp->mfcr2call = 0; 12501 tmp->mfcr2_dnis_index = 0; 12502 tmp->mfcr2_ani_index = 0; 12503 r2_link->monitored_count++; 12504 } 12505 #endif 12506 #ifdef HAVE_PRI 12507 if (dahdi_sig_pri_lib_handles(chan_sig)) { 12508 int offset; 12509 int matchesdchan; 12510 int x,y; 12511 int myswitchtype = 0; 12512 12513 offset = 0; 12514 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &offset)) { 12515 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 12516 destroy_dahdi_pvt(tmp); 12517 return NULL; 12518 } 12519 if (span >= NUM_SPANS) { 12520 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 12521 destroy_dahdi_pvt(tmp); 12522 return NULL; 12523 } else { 12524 si.spanno = 0; 12525 if (ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SPANSTAT,&si) == -1) { 12526 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 12527 destroy_dahdi_pvt(tmp); 12528 return NULL; 12529 } 12530 /* Store the logical span first based upon the real span */ 12531 tmp->logicalspan = pris[span].prilogicalspan; 12532 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 12533 if (span < 0) { 12534 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 12535 destroy_dahdi_pvt(tmp); 12536 return NULL; 12537 } 12538 myswitchtype = conf->pri.pri.switchtype; 12539 /* Make sure this isn't a d-channel */ 12540 matchesdchan=0; 12541 for (x = 0; x < NUM_SPANS; x++) { 12542 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 12543 if (pris[x].dchannels[y] == tmp->channel) { 12544 matchesdchan = 1; 12545 break; 12546 } 12547 } 12548 } 12549 if (!matchesdchan) { 12550 if (pris[span].pri.nodetype && (pris[span].pri.nodetype != conf->pri.pri.nodetype)) { 12551 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].pri.nodetype)); 12552 destroy_dahdi_pvt(tmp); 12553 return NULL; 12554 } 12555 if (pris[span].pri.switchtype && (pris[span].pri.switchtype != myswitchtype)) { 12556 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].pri.switchtype)); 12557 destroy_dahdi_pvt(tmp); 12558 return NULL; 12559 } 12560 if ((pris[span].pri.dialplan) && (pris[span].pri.dialplan != conf->pri.pri.dialplan)) { 12561 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)); 12562 destroy_dahdi_pvt(tmp); 12563 return NULL; 12564 } 12565 if (!ast_strlen_zero(pris[span].pri.idledial) && strcmp(pris[span].pri.idledial, conf->pri.pri.idledial)) { 12566 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.pri.idledial); 12567 destroy_dahdi_pvt(tmp); 12568 return NULL; 12569 } 12570 if (!ast_strlen_zero(pris[span].pri.idleext) && strcmp(pris[span].pri.idleext, conf->pri.pri.idleext)) { 12571 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.pri.idleext); 12572 destroy_dahdi_pvt(tmp); 12573 return NULL; 12574 } 12575 if (pris[span].pri.minunused && (pris[span].pri.minunused != conf->pri.pri.minunused)) { 12576 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.pri.minunused); 12577 destroy_dahdi_pvt(tmp); 12578 return NULL; 12579 } 12580 if (pris[span].pri.minidle && (pris[span].pri.minidle != conf->pri.pri.minidle)) { 12581 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.pri.minidle); 12582 destroy_dahdi_pvt(tmp); 12583 return NULL; 12584 } 12585 if (pris[span].pri.numchans >= ARRAY_LEN(pris[span].pri.pvts)) { 12586 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 12587 pris[span].pri.trunkgroup); 12588 destroy_dahdi_pvt(tmp); 12589 return NULL; 12590 } 12591 12592 ast_debug(4, "Adding callbacks %p to chan %d\n", &dahdi_pri_callbacks, tmp->channel); 12593 pri_chan = sig_pri_chan_new(tmp, &dahdi_pri_callbacks, &pris[span].pri, tmp->logicalspan, p.chanpos, pris[span].mastertrunkgroup); 12594 if (!pri_chan) { 12595 destroy_dahdi_pvt(tmp); 12596 return NULL; 12597 } 12598 tmp->sig_pvt = pri_chan; 12599 tmp->pri = &pris[span].pri; 12600 12601 tmp->priexclusive = conf->chan.priexclusive; 12602 12603 if (!tmp->pri->cc_params) { 12604 tmp->pri->cc_params = ast_cc_config_params_init(); 12605 if (!tmp->pri->cc_params) { 12606 destroy_dahdi_pvt(tmp); 12607 return NULL; 12608 } 12609 } 12610 ast_cc_copy_config_params(tmp->pri->cc_params, 12611 conf->chan.cc_params); 12612 12613 pris[span].pri.sig = chan_sig; 12614 pris[span].pri.nodetype = conf->pri.pri.nodetype; 12615 pris[span].pri.switchtype = myswitchtype; 12616 pris[span].pri.nsf = conf->pri.pri.nsf; 12617 pris[span].pri.dialplan = conf->pri.pri.dialplan; 12618 pris[span].pri.localdialplan = conf->pri.pri.localdialplan; 12619 pris[span].pri.pvts[pris[span].pri.numchans++] = tmp->sig_pvt; 12620 pris[span].pri.minunused = conf->pri.pri.minunused; 12621 pris[span].pri.minidle = conf->pri.pri.minidle; 12622 pris[span].pri.overlapdial = conf->pri.pri.overlapdial; 12623 pris[span].pri.qsigchannelmapping = conf->pri.pri.qsigchannelmapping; 12624 pris[span].pri.discardremoteholdretrieval = conf->pri.pri.discardremoteholdretrieval; 12625 #if defined(HAVE_PRI_SERVICE_MESSAGES) 12626 pris[span].pri.enable_service_message_support = conf->pri.pri.enable_service_message_support; 12627 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 12628 #ifdef HAVE_PRI_INBANDDISCONNECT 12629 pris[span].pri.inbanddisconnect = conf->pri.pri.inbanddisconnect; 12630 #endif 12631 #if defined(HAVE_PRI_CALL_HOLD) 12632 pris[span].pri.hold_disconnect_transfer = 12633 conf->pri.pri.hold_disconnect_transfer; 12634 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 12635 #if defined(HAVE_PRI_CCSS) 12636 pris[span].pri.cc_ptmp_recall_mode = 12637 conf->pri.pri.cc_ptmp_recall_mode; 12638 pris[span].pri.cc_qsig_signaling_link_req = 12639 conf->pri.pri.cc_qsig_signaling_link_req; 12640 pris[span].pri.cc_qsig_signaling_link_rsp = 12641 conf->pri.pri.cc_qsig_signaling_link_rsp; 12642 #endif /* defined(HAVE_PRI_CCSS) */ 12643 #if defined(HAVE_PRI_CALL_WAITING) 12644 pris[span].pri.max_call_waiting_calls = 12645 conf->pri.pri.max_call_waiting_calls; 12646 pris[span].pri.allow_call_waiting_calls = 12647 conf->pri.pri.allow_call_waiting_calls; 12648 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 12649 pris[span].pri.transfer = conf->chan.transfer; 12650 pris[span].pri.facilityenable = conf->pri.pri.facilityenable; 12651 #if defined(HAVE_PRI_L2_PERSISTENCE) 12652 pris[span].pri.l2_persistence = conf->pri.pri.l2_persistence; 12653 #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */ 12654 #if defined(HAVE_PRI_AOC_EVENTS) 12655 pris[span].pri.aoc_passthrough_flag = conf->pri.pri.aoc_passthrough_flag; 12656 pris[span].pri.aoce_delayhangup = conf->pri.pri.aoce_delayhangup; 12657 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 12658 if (chan_sig == SIG_BRI_PTMP) { 12659 pris[span].pri.layer1_ignored = conf->pri.pri.layer1_ignored; 12660 } else { 12661 /* Option does not apply to this line type. */ 12662 pris[span].pri.layer1_ignored = 0; 12663 } 12664 pris[span].pri.append_msn_to_user_tag = conf->pri.pri.append_msn_to_user_tag; 12665 ast_copy_string(pris[span].pri.initial_user_tag, conf->chan.cid_tag, sizeof(pris[span].pri.initial_user_tag)); 12666 ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list)); 12667 #if defined(HAVE_PRI_MWI) 12668 ast_copy_string(pris[span].pri.mwi_mailboxes, 12669 conf->pri.pri.mwi_mailboxes, 12670 sizeof(pris[span].pri.mwi_mailboxes)); 12671 #endif /* defined(HAVE_PRI_MWI) */ 12672 ast_copy_string(pris[span].pri.idledial, conf->pri.pri.idledial, sizeof(pris[span].pri.idledial)); 12673 ast_copy_string(pris[span].pri.idleext, conf->pri.pri.idleext, sizeof(pris[span].pri.idleext)); 12674 ast_copy_string(pris[span].pri.internationalprefix, conf->pri.pri.internationalprefix, sizeof(pris[span].pri.internationalprefix)); 12675 ast_copy_string(pris[span].pri.nationalprefix, conf->pri.pri.nationalprefix, sizeof(pris[span].pri.nationalprefix)); 12676 ast_copy_string(pris[span].pri.localprefix, conf->pri.pri.localprefix, sizeof(pris[span].pri.localprefix)); 12677 ast_copy_string(pris[span].pri.privateprefix, conf->pri.pri.privateprefix, sizeof(pris[span].pri.privateprefix)); 12678 ast_copy_string(pris[span].pri.unknownprefix, conf->pri.pri.unknownprefix, sizeof(pris[span].pri.unknownprefix)); 12679 pris[span].pri.resetinterval = conf->pri.pri.resetinterval; 12680 12681 for (x = 0; x < PRI_MAX_TIMERS; x++) { 12682 pris[span].pri.pritimers[x] = conf->pri.pri.pritimers[x]; 12683 } 12684 12685 #if defined(HAVE_PRI_CALL_WAITING) 12686 /* Channel initial config parameters. */ 12687 pris[span].pri.ch_cfg.stripmsd = conf->chan.stripmsd; 12688 pris[span].pri.ch_cfg.hidecallerid = conf->chan.hidecallerid; 12689 pris[span].pri.ch_cfg.hidecalleridname = conf->chan.hidecalleridname; 12690 pris[span].pri.ch_cfg.immediate = conf->chan.immediate; 12691 pris[span].pri.ch_cfg.priexclusive = conf->chan.priexclusive; 12692 pris[span].pri.ch_cfg.priindication_oob = conf->chan.priindication_oob; 12693 pris[span].pri.ch_cfg.use_callerid = conf->chan.use_callerid; 12694 pris[span].pri.ch_cfg.use_callingpres = conf->chan.use_callingpres; 12695 ast_copy_string(pris[span].pri.ch_cfg.context, conf->chan.context, sizeof(pris[span].pri.ch_cfg.context)); 12696 ast_copy_string(pris[span].pri.ch_cfg.mohinterpret, conf->chan.mohinterpret, sizeof(pris[span].pri.ch_cfg.mohinterpret)); 12697 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 12698 } else { 12699 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", p.chanpos); 12700 destroy_dahdi_pvt(tmp); 12701 return NULL; 12702 } 12703 } 12704 } 12705 #endif 12706 } else { 12707 /* already exists in interface list */ 12708 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)); 12709 chan_sig = tmp->sig; 12710 if (tmp->subs[SUB_REAL].dfd > -1) { 12711 memset(&p, 0, sizeof(p)); 12712 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 12713 } 12714 } 12715 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 12716 switch (chan_sig) { 12717 case SIG_FXSKS: 12718 case SIG_FXSLS: 12719 case SIG_EM: 12720 case SIG_EM_E1: 12721 case SIG_EMWINK: 12722 case SIG_FEATD: 12723 case SIG_FEATDMF: 12724 case SIG_FEATDMF_TA: 12725 case SIG_FEATB: 12726 case SIG_E911: 12727 case SIG_SF: 12728 case SIG_SFWINK: 12729 case SIG_FGC_CAMA: 12730 case SIG_FGC_CAMAMF: 12731 case SIG_SF_FEATD: 12732 case SIG_SF_FEATDMF: 12733 case SIG_SF_FEATB: 12734 p.starttime = 250; 12735 break; 12736 } 12737 12738 if (tmp->radio) { 12739 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 12740 p.channo = channel; 12741 p.rxwinktime = 1; 12742 p.rxflashtime = 1; 12743 p.starttime = 1; 12744 p.debouncetime = 5; 12745 } else { 12746 p.channo = channel; 12747 /* Override timing settings based on config file */ 12748 if (conf->timing.prewinktime >= 0) 12749 p.prewinktime = conf->timing.prewinktime; 12750 if (conf->timing.preflashtime >= 0) 12751 p.preflashtime = conf->timing.preflashtime; 12752 if (conf->timing.winktime >= 0) 12753 p.winktime = conf->timing.winktime; 12754 if (conf->timing.flashtime >= 0) 12755 p.flashtime = conf->timing.flashtime; 12756 if (conf->timing.starttime >= 0) 12757 p.starttime = conf->timing.starttime; 12758 if (conf->timing.rxwinktime >= 0) 12759 p.rxwinktime = conf->timing.rxwinktime; 12760 if (conf->timing.rxflashtime >= 0) 12761 p.rxflashtime = conf->timing.rxflashtime; 12762 if (conf->timing.debouncetime >= 0) 12763 p.debouncetime = conf->timing.debouncetime; 12764 } 12765 12766 /* don't set parms on a pseudo-channel */ 12767 if (tmp->subs[SUB_REAL].dfd >= 0) 12768 { 12769 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_PARAMS, &p); 12770 if (res < 0) { 12771 ast_log(LOG_ERROR, "Unable to set parameters: %s\n", strerror(errno)); 12772 destroy_dahdi_pvt(tmp); 12773 return NULL; 12774 } 12775 } 12776 #if 1 12777 if (!here && (tmp->subs[SUB_REAL].dfd > -1)) { 12778 memset(&bi, 0, sizeof(bi)); 12779 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi); 12780 if (!res) { 12781 bi.txbufpolicy = conf->chan.buf_policy; 12782 bi.rxbufpolicy = conf->chan.buf_policy; 12783 bi.numbufs = conf->chan.buf_no; 12784 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi); 12785 if (res < 0) { 12786 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", channel, strerror(errno)); 12787 } 12788 } else { 12789 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", channel, strerror(errno)); 12790 } 12791 tmp->buf_policy = conf->chan.buf_policy; 12792 tmp->buf_no = conf->chan.buf_no; 12793 tmp->usefaxbuffers = conf->chan.usefaxbuffers; 12794 tmp->faxbuf_policy = conf->chan.faxbuf_policy; 12795 tmp->faxbuf_no = conf->chan.faxbuf_no; 12796 /* This is not as gnarly as it may first appear. If the ioctl above failed, we'd be setting 12797 * tmp->bufsize to zero which would cause subsequent faxbuffer-related ioctl calls to fail. 12798 * The reason the ioctl call above failed should to be determined before worrying about the 12799 * faxbuffer-related ioctl calls */ 12800 tmp->bufsize = bi.bufsize; 12801 } 12802 #endif 12803 tmp->immediate = conf->chan.immediate; 12804 tmp->transfertobusy = conf->chan.transfertobusy; 12805 if (chan_sig & __DAHDI_SIG_FXS) { 12806 tmp->mwimonitor_fsk = conf->chan.mwimonitor_fsk; 12807 tmp->mwimonitor_neon = conf->chan.mwimonitor_neon; 12808 tmp->mwimonitor_rpas = conf->chan.mwimonitor_rpas; 12809 } 12810 tmp->ringt_base = ringt_base; 12811 tmp->firstradio = 0; 12812 if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS)) 12813 tmp->permcallwaiting = conf->chan.callwaiting; 12814 else 12815 tmp->permcallwaiting = 0; 12816 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 12817 tmp->destroy = 0; 12818 tmp->drings = conf->chan.drings; 12819 12820 /* 10 is a nice default. */ 12821 if (tmp->drings.ringnum[0].range == 0) 12822 tmp->drings.ringnum[0].range = 10; 12823 if (tmp->drings.ringnum[1].range == 0) 12824 tmp->drings.ringnum[1].range = 10; 12825 if (tmp->drings.ringnum[2].range == 0) 12826 tmp->drings.ringnum[2].range = 10; 12827 12828 tmp->usedistinctiveringdetection = usedistinctiveringdetection; 12829 tmp->callwaitingcallerid = conf->chan.callwaitingcallerid; 12830 tmp->threewaycalling = conf->chan.threewaycalling; 12831 tmp->adsi = conf->chan.adsi; 12832 tmp->use_smdi = conf->chan.use_smdi; 12833 tmp->permhidecallerid = conf->chan.hidecallerid; 12834 tmp->hidecalleridname = conf->chan.hidecalleridname; 12835 tmp->callreturn = conf->chan.callreturn; 12836 tmp->echocancel = conf->chan.echocancel; 12837 tmp->echotraining = conf->chan.echotraining; 12838 tmp->pulse = conf->chan.pulse; 12839 if (tmp->echocancel.head.tap_length) { 12840 tmp->echocanbridged = conf->chan.echocanbridged; 12841 } else { 12842 if (conf->chan.echocanbridged) 12843 ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n"); 12844 tmp->echocanbridged = 0; 12845 } 12846 tmp->busydetect = conf->chan.busydetect; 12847 tmp->busycount = conf->chan.busycount; 12848 tmp->busycompare = conf->chan.busycompare; 12849 tmp->busytonelength = conf->chan.busytonelength; 12850 tmp->busyquietlength = conf->chan.busyquietlength; 12851 tmp->busyfuzziness = conf->chan.busyfuzziness; 12852 tmp->silencethreshold = conf->chan.silencethreshold; 12853 tmp->callprogress = conf->chan.callprogress; 12854 tmp->waitfordialtone = conf->chan.waitfordialtone; 12855 tmp->cancallforward = conf->chan.cancallforward; 12856 tmp->dtmfrelax = conf->chan.dtmfrelax; 12857 tmp->callwaiting = tmp->permcallwaiting; 12858 tmp->hidecallerid = tmp->permhidecallerid; 12859 tmp->channel = channel; 12860 tmp->stripmsd = conf->chan.stripmsd; 12861 tmp->use_callerid = conf->chan.use_callerid; 12862 tmp->cid_signalling = conf->chan.cid_signalling; 12863 tmp->cid_start = conf->chan.cid_start; 12864 tmp->dahditrcallerid = conf->chan.dahditrcallerid; 12865 tmp->restrictcid = conf->chan.restrictcid; 12866 tmp->use_callingpres = conf->chan.use_callingpres; 12867 if (tmp->usedistinctiveringdetection) { 12868 if (!tmp->use_callerid) { 12869 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 12870 tmp->use_callerid = 1; 12871 } 12872 } 12873 12874 if (tmp->cid_signalling == CID_SIG_SMDI) { 12875 if (!tmp->use_smdi) { 12876 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n"); 12877 tmp->use_smdi = 1; 12878 } 12879 } 12880 if (tmp->use_smdi) { 12881 tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port); 12882 if (!(tmp->smdi_iface)) { 12883 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n"); 12884 tmp->use_smdi = 0; 12885 } 12886 } 12887 12888 ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode)); 12889 tmp->amaflags = conf->chan.amaflags; 12890 if (!here) { 12891 tmp->confno = -1; 12892 tmp->propconfno = -1; 12893 } 12894 tmp->canpark = conf->chan.canpark; 12895 tmp->transfer = conf->chan.transfer; 12896 ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext)); 12897 ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language)); 12898 ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret)); 12899 ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest)); 12900 ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context)); 12901 ast_copy_string(tmp->parkinglot, conf->chan.parkinglot, sizeof(tmp->parkinglot)); 12902 tmp->cid_ton = 0; 12903 if (analog_lib_handles(tmp->sig, tmp->radio, tmp->oprmode)) { 12904 ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num)); 12905 ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name)); 12906 } else { 12907 tmp->cid_num[0] = '\0'; 12908 tmp->cid_name[0] = '\0'; 12909 } 12910 #if defined(HAVE_PRI) 12911 if (dahdi_sig_pri_lib_handles(tmp->sig)) { 12912 tmp->cid_tag[0] = '\0'; 12913 } else 12914 #endif /* defined(HAVE_PRI) */ 12915 { 12916 ast_copy_string(tmp->cid_tag, conf->chan.cid_tag, sizeof(tmp->cid_tag)); 12917 } 12918 tmp->cid_subaddr[0] = '\0'; 12919 ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox)); 12920 if (channel != CHAN_PSEUDO && !ast_strlen_zero(tmp->mailbox)) { 12921 char *mailbox, *context; 12922 mailbox = context = ast_strdupa(tmp->mailbox); 12923 strsep(&context, "@"); 12924 if (ast_strlen_zero(context)) 12925 context = "default"; 12926 tmp->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "Dahdi MWI subscription", NULL, 12927 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12928 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12929 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS, 12930 AST_EVENT_IE_END); 12931 } 12932 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 12933 tmp->mwisend_setting = conf->chan.mwisend_setting; 12934 tmp->mwisend_fsk = conf->chan.mwisend_fsk; 12935 tmp->mwisend_rpas = conf->chan.mwisend_rpas; 12936 #endif 12937 12938 tmp->group = conf->chan.group; 12939 tmp->callgroup = conf->chan.callgroup; 12940 tmp->pickupgroup= conf->chan.pickupgroup; 12941 if (conf->chan.vars) { 12942 struct ast_variable *v, *tmpvar; 12943 for (v = conf->chan.vars ; v ; v = v->next) { 12944 if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 12945 tmpvar->next = tmp->vars; 12946 tmp->vars = tmpvar; 12947 } 12948 } 12949 } 12950 tmp->cid_rxgain = conf->chan.cid_rxgain; 12951 tmp->rxgain = conf->chan.rxgain; 12952 tmp->txgain = conf->chan.txgain; 12953 tmp->txdrc = conf->chan.txdrc; 12954 tmp->rxdrc = conf->chan.rxdrc; 12955 tmp->tonezone = conf->chan.tonezone; 12956 if (tmp->subs[SUB_REAL].dfd > -1) { 12957 set_actual_gain(tmp->subs[SUB_REAL].dfd, tmp->rxgain, tmp->txgain, tmp->rxdrc, tmp->txdrc, tmp->law); 12958 if (tmp->dsp) 12959 ast_dsp_set_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 12960 update_conf(tmp); 12961 if (!here) { 12962 switch (chan_sig) { 12963 case SIG_PRI_LIB_HANDLE_CASES: 12964 case SIG_SS7: 12965 case SIG_MFCR2: 12966 break; 12967 default: 12968 /* Hang it up to be sure it's good */ 12969 dahdi_set_hook(tmp->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 12970 break; 12971 } 12972 } 12973 ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SETTONEZONE,&tmp->tonezone); 12974 if ((res = get_alarms(tmp)) != DAHDI_ALARM_NONE) { 12975 /* the dchannel is down so put the channel in alarm */ 12976 switch (tmp->sig) { 12977 #ifdef HAVE_PRI 12978 case SIG_PRI_LIB_HANDLE_CASES: 12979 sig_pri_set_alarm(tmp->sig_pvt, 1); 12980 break; 12981 #endif 12982 #if defined(HAVE_SS7) 12983 case SIG_SS7: 12984 sig_ss7_set_alarm(tmp->sig_pvt, 1); 12985 break; 12986 #endif /* defined(HAVE_SS7) */ 12987 default: 12988 /* The only sig submodule left should be sig_analog. */ 12989 analog_p = tmp->sig_pvt; 12990 if (analog_p) { 12991 analog_p->inalarm = 1; 12992 } 12993 tmp->inalarm = 1; 12994 break; 12995 } 12996 handle_alarms(tmp, res); 12997 } 12998 } 12999 13000 tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay; 13001 tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch; 13002 tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch; 13003 tmp->sendcalleridafter = conf->chan.sendcalleridafter; 13004 ast_cc_copy_config_params(tmp->cc_params, conf->chan.cc_params); 13005 13006 if (!here) { 13007 tmp->locallyblocked = 0; 13008 tmp->remotelyblocked = 0; 13009 switch (tmp->sig) { 13010 #if defined(HAVE_PRI) 13011 case SIG_PRI_LIB_HANDLE_CASES: 13012 tmp->inservice = 1;/* Inservice until actually implemented. */ 13013 #if defined(HAVE_PRI_SERVICE_MESSAGES) 13014 ((struct sig_pri_chan *) tmp->sig_pvt)->service_status = 0; 13015 if (chan_sig == SIG_PRI) { 13016 char db_chan_name[20]; 13017 char db_answer[5]; 13018 13019 /* 13020 * Initialize the active out-of-service status 13021 * and delete any record if the feature is not enabled. 13022 */ 13023 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, tmp->span, tmp->channel); 13024 if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) { 13025 unsigned *why; 13026 13027 why = &((struct sig_pri_chan *) tmp->sig_pvt)->service_status; 13028 if (tmp->pri->enable_service_message_support) { 13029 char state; 13030 13031 sscanf(db_answer, "%1c:%30u", &state, why); 13032 13033 /* Ensure that only the implemented bits could be set.*/ 13034 *why &= (SRVST_NEAREND | SRVST_FAREND); 13035 } 13036 if (!*why) { 13037 ast_db_del(db_chan_name, SRVST_DBKEY); 13038 } 13039 } 13040 } 13041 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 13042 break; 13043 #endif /* defined(HAVE_PRI) */ 13044 #if defined(HAVE_SS7) 13045 case SIG_SS7: 13046 tmp->inservice = 0; 13047 break; 13048 #endif /* defined(HAVE_SS7) */ 13049 default: 13050 /* We default to in service on protocols that don't have a reset */ 13051 tmp->inservice = 1; 13052 break; 13053 } 13054 } 13055 13056 switch (tmp->sig) { 13057 #if defined(HAVE_PRI) 13058 case SIG_PRI_LIB_HANDLE_CASES: 13059 if (pri_chan) { 13060 pri_chan->channel = tmp->channel; 13061 pri_chan->hidecallerid = tmp->hidecallerid; 13062 pri_chan->hidecalleridname = tmp->hidecalleridname; 13063 pri_chan->immediate = tmp->immediate; 13064 pri_chan->inalarm = tmp->inalarm; 13065 pri_chan->priexclusive = tmp->priexclusive; 13066 pri_chan->priindication_oob = tmp->priindication_oob; 13067 pri_chan->use_callerid = tmp->use_callerid; 13068 pri_chan->use_callingpres = tmp->use_callingpres; 13069 ast_copy_string(pri_chan->context, tmp->context, 13070 sizeof(pri_chan->context)); 13071 ast_copy_string(pri_chan->mohinterpret, tmp->mohinterpret, 13072 sizeof(pri_chan->mohinterpret)); 13073 pri_chan->stripmsd = tmp->stripmsd; 13074 } 13075 break; 13076 #endif /* defined(HAVE_PRI) */ 13077 #if defined(HAVE_SS7) 13078 case SIG_SS7: 13079 if (ss7_chan) { 13080 ss7_chan->inalarm = tmp->inalarm; 13081 13082 ss7_chan->stripmsd = tmp->stripmsd; 13083 ss7_chan->hidecallerid = tmp->hidecallerid; 13084 ss7_chan->use_callerid = tmp->use_callerid; 13085 ss7_chan->use_callingpres = tmp->use_callingpres; 13086 ss7_chan->immediate = tmp->immediate; 13087 ss7_chan->locallyblocked = tmp->locallyblocked; 13088 ss7_chan->remotelyblocked = tmp->remotelyblocked; 13089 ast_copy_string(ss7_chan->context, tmp->context, 13090 sizeof(ss7_chan->context)); 13091 ast_copy_string(ss7_chan->mohinterpret, tmp->mohinterpret, 13092 sizeof(ss7_chan->mohinterpret)); 13093 } 13094 break; 13095 #endif /* defined(HAVE_SS7) */ 13096 default: 13097 /* The only sig submodule left should be sig_analog. */ 13098 analog_p = tmp->sig_pvt; 13099 if (analog_p) { 13100 analog_p->channel = tmp->channel; 13101 analog_p->polarityonanswerdelay = conf->chan.polarityonanswerdelay; 13102 analog_p->answeronpolarityswitch = conf->chan.answeronpolarityswitch; 13103 analog_p->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch; 13104 analog_p->permcallwaiting = conf->chan.callwaiting; /* permcallwaiting possibly modified in analog_config_complete */ 13105 analog_p->callreturn = conf->chan.callreturn; 13106 analog_p->cancallforward = conf->chan.cancallforward; 13107 analog_p->canpark = conf->chan.canpark; 13108 analog_p->dahditrcallerid = conf->chan.dahditrcallerid; 13109 analog_p->immediate = conf->chan.immediate; 13110 analog_p->permhidecallerid = conf->chan.permhidecallerid; 13111 analog_p->pulse = conf->chan.pulse; 13112 analog_p->threewaycalling = conf->chan.threewaycalling; 13113 analog_p->transfer = conf->chan.transfer; 13114 analog_p->transfertobusy = conf->chan.transfertobusy; 13115 analog_p->use_callerid = tmp->use_callerid; 13116 analog_p->use_smdi = tmp->use_smdi; 13117 analog_p->smdi_iface = tmp->smdi_iface; 13118 analog_p->outsigmod = ANALOG_SIG_NONE; 13119 analog_p->echotraining = conf->chan.echotraining; 13120 analog_p->cid_signalling = conf->chan.cid_signalling; 13121 analog_p->stripmsd = conf->chan.stripmsd; 13122 switch (conf->chan.cid_start) { 13123 case CID_START_POLARITY: 13124 analog_p->cid_start = ANALOG_CID_START_POLARITY; 13125 break; 13126 case CID_START_POLARITY_IN: 13127 analog_p->cid_start = ANALOG_CID_START_POLARITY_IN; 13128 break; 13129 case CID_START_DTMF_NOALERT: 13130 analog_p->cid_start = ANALOG_CID_START_DTMF_NOALERT; 13131 break; 13132 default: 13133 analog_p->cid_start = ANALOG_CID_START_RING; 13134 break; 13135 } 13136 analog_p->callwaitingcallerid = conf->chan.callwaitingcallerid; 13137 analog_p->ringt = conf->chan.ringt; 13138 analog_p->ringt_base = ringt_base; 13139 analog_p->chan_tech = &dahdi_tech; 13140 analog_p->onhooktime = time(NULL); 13141 if (chan_sig & __DAHDI_SIG_FXO) { 13142 memset(&p, 0, sizeof(p)); 13143 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 13144 if (!res) { 13145 analog_p->fxsoffhookstate = p.rxisoffhook; 13146 } 13147 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 13148 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting); 13149 #endif 13150 } 13151 analog_p->msgstate = -1; 13152 13153 ast_copy_string(analog_p->mohsuggest, conf->chan.mohsuggest, sizeof(analog_p->mohsuggest)); 13154 ast_copy_string(analog_p->cid_num, conf->chan.cid_num, sizeof(analog_p->cid_num)); 13155 ast_copy_string(analog_p->cid_name, conf->chan.cid_name, sizeof(analog_p->cid_name)); 13156 13157 analog_config_complete(analog_p); 13158 } 13159 break; 13160 } 13161 #if defined(HAVE_PRI) 13162 if (tmp->channel == CHAN_PSEUDO) { 13163 /* 13164 * Save off pseudo channel buffer policy values for dynamic creation of 13165 * no B channel interfaces. 13166 */ 13167 dahdi_pseudo_parms.buf_no = tmp->buf_no; 13168 dahdi_pseudo_parms.buf_policy = tmp->buf_policy; 13169 dahdi_pseudo_parms.faxbuf_no = tmp->faxbuf_no; 13170 dahdi_pseudo_parms.faxbuf_policy = tmp->faxbuf_policy; 13171 } 13172 #endif /* defined(HAVE_PRI) */ 13173 } 13174 if (tmp && !here) { 13175 /* Add the new channel interface to the sorted channel interface list. */ 13176 dahdi_iflist_insert(tmp); 13177 } 13178 return tmp; 13179 }
static void mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 480 of file chan_dahdi.c.
Referenced by add_peer_mwi_subs(), build_peer(), config_line(), and skinny_register().
00481 { 00482 /* This module does not handle MWI in an event-based manner. However, it 00483 * subscribes to MWI for each mailbox that is configured so that the core 00484 * knows that we care about it. Then, chan_dahdi will get the MWI from the 00485 * event cache instead of checking the mailbox directly. */ 00486 }
static int mwi_send_init | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 11227 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.
11228 { 11229 int x; 11230 11231 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11232 /* Determine how this spill is to be sent */ 11233 if (pvt->mwisend_rpas) { 11234 pvt->mwisend_data.mwisend_current = MWI_SEND_SA; 11235 pvt->mwisendactive = 1; 11236 } else if (pvt->mwisend_fsk) { 11237 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 11238 pvt->mwisendactive = 1; 11239 } else { 11240 pvt->mwisendactive = 0; 11241 return 0; 11242 } 11243 #else 11244 if (mwisend_rpas) { 11245 pvt->mwisend_data.mwisend_current = MWI_SEND_SA; 11246 } else { 11247 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 11248 } 11249 pvt->mwisendactive = 1; 11250 #endif 11251 11252 if (pvt->cidspill) { 11253 ast_log(LOG_WARNING, "cidspill already exists when trying to send FSK MWI\n"); 11254 ast_free(pvt->cidspill); 11255 pvt->cidspill = NULL; 11256 pvt->cidpos = 0; 11257 pvt->cidlen = 0; 11258 } 11259 pvt->cidspill = ast_calloc(1, MAX_CALLERID_SIZE); 11260 if (!pvt->cidspill) { 11261 pvt->mwisendactive = 0; 11262 return -1; 11263 } 11264 x = DAHDI_FLUSH_BOTH; 11265 ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x); 11266 x = 3000; 11267 ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_ONHOOKTRANSFER, &x); 11268 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11269 if (pvt->mwisend_fsk) { 11270 #endif 11271 pvt->cidlen = ast_callerid_vmwi_generate(pvt->cidspill, has_voicemail(pvt), CID_MWI_TYPE_MDMF_FULL, 11272 AST_LAW(pvt), pvt->cid_name, pvt->cid_num, 0); 11273 pvt->cidpos = 0; 11274 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11275 } 11276 #endif 11277 return 0; 11278 }
static int mwi_send_process_buffer | ( | struct dahdi_pvt * | pvt, | |
int | num_read | |||
) | [static] |
Definition at line 11280 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.
11281 { 11282 struct timeval now; 11283 int res; 11284 11285 /* sanity check to catch if this had been interrupted previously 11286 * i.e. state says there is more to do but there is no spill allocated 11287 */ 11288 if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current && !pvt->cidspill) { 11289 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11290 } else if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) { 11291 /* Normal processing -- Perform mwi send action */ 11292 switch ( pvt->mwisend_data.mwisend_current) { 11293 case MWI_SEND_SA: 11294 /* Send the Ring Pulse Signal Alert */ 11295 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &AS_RP_cadence); 11296 if (res) { 11297 ast_log(LOG_WARNING, "Unable to set RP-AS ring cadence: %s\n", strerror(errno)); 11298 goto quit; 11299 } 11300 res = dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RING); 11301 pvt->mwisend_data.mwisend_current = MWI_SEND_SA_WAIT; 11302 break; 11303 case MWI_SEND_SA_WAIT: /* do nothing until I get RINGEROFF event */ 11304 break; 11305 case MWI_SEND_PAUSE: /* Wait between alert and spill - min of 500 mS*/ 11306 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11307 if (pvt->mwisend_fsk) { 11308 #endif 11309 gettimeofday(&now, NULL); 11310 if ((int)(now.tv_sec - pvt->mwisend_data.pause.tv_sec) * 1000000 + (int)now.tv_usec - (int)pvt->mwisend_data.pause.tv_usec > 500000) { 11311 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 11312 } 11313 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11314 } else { /* support for mwisendtype=nofsk */ 11315 pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP; 11316 } 11317 #endif 11318 break; 11319 case MWI_SEND_SPILL: 11320 /* We read some number of bytes. Write an equal amount of data */ 11321 if(0 < num_read) { 11322 if (num_read > pvt->cidlen - pvt->cidpos) 11323 num_read = pvt->cidlen - pvt->cidpos; 11324 res = write(pvt->subs[SUB_REAL].dfd, pvt->cidspill + pvt->cidpos, num_read); 11325 if (res > 0) { 11326 pvt->cidpos += res; 11327 if (pvt->cidpos >= pvt->cidlen) { 11328 pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP; 11329 } 11330 } else { 11331 ast_log(LOG_WARNING, "MWI FSK Send Write failed: %s\n", strerror(errno)); 11332 goto quit; 11333 } 11334 } 11335 break; 11336 case MWI_SEND_CLEANUP: 11337 /* For now, do nothing */ 11338 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11339 break; 11340 default: 11341 /* Should not get here, punt*/ 11342 goto quit; 11343 } 11344 } 11345 11346 if (MWI_SEND_DONE == pvt->mwisend_data.mwisend_current) { 11347 if (pvt->cidspill) { 11348 ast_free(pvt->cidspill); 11349 pvt->cidspill = NULL; 11350 pvt->cidpos = 0; 11351 pvt->cidlen = 0; 11352 } 11353 pvt->mwisendactive = 0; 11354 } 11355 return 0; 11356 quit: 11357 if (pvt->cidspill) { 11358 ast_free(pvt->cidspill); 11359 pvt->cidspill = NULL; 11360 pvt->cidpos = 0; 11361 pvt->cidlen = 0; 11362 } 11363 pvt->mwisendactive = 0; 11364 return -1; 11365 }
static int mwi_send_process_event | ( | struct dahdi_pvt * | pvt, | |
int | event | |||
) | [static] |
Definition at line 11367 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.
11368 { 11369 int handled = 0; 11370 11371 if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) { 11372 switch (event) { 11373 case DAHDI_EVENT_RINGEROFF: 11374 if(pvt->mwisend_data.mwisend_current == MWI_SEND_SA_WAIT) { 11375 handled = 1; 11376 11377 if (dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RINGOFF) ) { 11378 ast_log(LOG_WARNING, "Unable to finish RP-AS: %s mwi send aborted\n", strerror(errno)); 11379 ast_free(pvt->cidspill); 11380 pvt->cidspill = NULL; 11381 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11382 pvt->mwisendactive = 0; 11383 } else { 11384 pvt->mwisend_data.mwisend_current = MWI_SEND_PAUSE; 11385 gettimeofday(&pvt->mwisend_data.pause, NULL); 11386 } 11387 } 11388 break; 11389 /* Going off hook, I need to punt this spill */ 11390 case DAHDI_EVENT_RINGOFFHOOK: 11391 if (pvt->cidspill) { 11392 ast_free(pvt->cidspill); 11393 pvt->cidspill = NULL; 11394 pvt->cidpos = 0; 11395 pvt->cidlen = 0; 11396 } 11397 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11398 pvt->mwisendactive = 0; 11399 break; 11400 case DAHDI_EVENT_RINGERON: 11401 case DAHDI_EVENT_HOOKCOMPLETE: 11402 break; 11403 default: 11404 break; 11405 } 11406 } 11407 return handled; 11408 }
static void* mwi_thread | ( | void * | data | ) | [static] |
Definition at line 11075 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, 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.
11076 { 11077 struct mwi_thread_data *mtd = data; 11078 struct callerid_state *cs; 11079 pthread_t threadid; 11080 int samples = 0; 11081 char *name, *number; 11082 int flags; 11083 int i, res; 11084 unsigned int spill_done = 0; 11085 int spill_result = -1; 11086 11087 if (!(cs = callerid_new(mtd->pvt->cid_signalling))) { 11088 goto quit_no_clean; 11089 } 11090 11091 callerid_feed(cs, mtd->buf, mtd->len, AST_LAW(mtd->pvt)); 11092 11093 bump_gains(mtd->pvt); 11094 11095 for (;;) { 11096 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 11097 if ((res = ioctl(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_IOMUX, &i))) { 11098 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 11099 goto quit; 11100 } 11101 11102 if (i & DAHDI_IOMUX_SIGEVENT) { 11103 struct ast_channel *chan; 11104 11105 /* If we get an event, screen out events that we do not act on. 11106 * Otherwise, cancel and go to the simple switch to let it deal with it. 11107 */ 11108 res = dahdi_get_event(mtd->pvt->subs[SUB_REAL].dfd); 11109 11110 switch (res) { 11111 case DAHDI_EVENT_NEONMWI_ACTIVE: 11112 case DAHDI_EVENT_NEONMWI_INACTIVE: 11113 case DAHDI_EVENT_NONE: 11114 case DAHDI_EVENT_BITSCHANGED: 11115 break; 11116 case DAHDI_EVENT_NOALARM: 11117 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 11118 struct analog_pvt *analog_p = mtd->pvt->sig_pvt; 11119 11120 analog_p->inalarm = 0; 11121 } 11122 mtd->pvt->inalarm = 0; 11123 handle_clear_alarms(mtd->pvt); 11124 break; 11125 case DAHDI_EVENT_ALARM: 11126 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 11127 struct analog_pvt *analog_p = mtd->pvt->sig_pvt; 11128 11129 analog_p->inalarm = 1; 11130 } 11131 mtd->pvt->inalarm = 1; 11132 res = get_alarms(mtd->pvt); 11133 handle_alarms(mtd->pvt, res); 11134 break; /* What to do on channel alarm ???? -- fall thru intentionally?? */ 11135 default: 11136 ast_log(LOG_NOTICE, "Got event %d (%s)... Passing along to analog_ss_thread\n", res, event2str(res)); 11137 callerid_free(cs); 11138 11139 restore_gains(mtd->pvt); 11140 mtd->pvt->ringt = mtd->pvt->ringt_base; 11141 11142 if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, NULL))) { 11143 int result; 11144 11145 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 11146 result = analog_ss_thread_start(mtd->pvt->sig_pvt, chan); 11147 } else { 11148 result = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan); 11149 } 11150 if (result) { 11151 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", mtd->pvt->channel); 11152 res = tone_zone_play_tone(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11153 if (res < 0) 11154 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", mtd->pvt->channel); 11155 ast_hangup(chan); 11156 } 11157 } else { 11158 ast_log(LOG_WARNING, "Could not create channel to handle call\n"); 11159 } 11160 goto quit_no_clean; 11161 } 11162 } else if (i & DAHDI_IOMUX_READ) { 11163 if ((res = read(mtd->pvt->subs[SUB_REAL].dfd, mtd->buf, sizeof(mtd->buf))) < 0) { 11164 if (errno != ELAST) { 11165 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 11166 goto quit; 11167 } 11168 break; 11169 } 11170 samples += res; 11171 if (!spill_done) { 11172 if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) { 11173 /* 11174 * The previous diagnostic message output likely 11175 * explains why it failed. 11176 */ 11177 ast_log(LOG_WARNING, "Failed to decode CallerID\n"); 11178 break; 11179 } else if (spill_result) { 11180 spill_done = 1; 11181 } 11182 } else { 11183 /* keep reading data until the energy level drops below the threshold 11184 so we don't get another 'trigger' on the remaining carrier signal 11185 */ 11186 if (calc_energy(mtd->buf, res, AST_LAW(mtd->pvt)) <= mwilevel) 11187 break; 11188 } 11189 if (samples > (8000 * 4)) /*Termination case - time to give up*/ 11190 break; 11191 } 11192 } 11193 11194 if (spill_result == 1) { 11195 callerid_get(cs, &name, &number, &flags); 11196 if (flags & CID_MSGWAITING) { 11197 ast_log(LOG_NOTICE, "mwi: Have Messages on channel %d\n", mtd->pvt->channel); 11198 notify_message(mtd->pvt->mailbox, 1); 11199 } else if (flags & CID_NOMSGWAITING) { 11200 ast_log(LOG_NOTICE, "mwi: No Messages on channel %d\n", mtd->pvt->channel); 11201 notify_message(mtd->pvt->mailbox, 0); 11202 } else { 11203 ast_log(LOG_NOTICE, "mwi: Status unknown on channel %d\n", mtd->pvt->channel); 11204 } 11205 } 11206 11207 11208 quit: 11209 callerid_free(cs); 11210 11211 restore_gains(mtd->pvt); 11212 11213 quit_no_clean: 11214 mtd->pvt->mwimonitoractive = 0; 11215 ast_free(mtd); 11216 11217 return NULL; 11218 }
static void my_all_subchannels_hungup | ( | void * | pvt | ) | [static] |
Definition at line 2407 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.
02408 { 02409 struct dahdi_pvt *p = pvt; 02410 int res, law; 02411 02412 p->faxhandled = 0; 02413 p->didtdd = 0; 02414 02415 if (p->dsp) { 02416 ast_dsp_free(p->dsp); 02417 p->dsp = NULL; 02418 } 02419 02420 p->law = p->law_default; 02421 law = p->law_default; 02422 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 02423 if (res < 0) 02424 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno)); 02425 02426 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 02427 02428 #if 1 02429 { 02430 int i; 02431 p->owner = NULL; 02432 /* Cleanup owners here */ 02433 for (i = 0; i < 3; i++) { 02434 p->subs[i].owner = NULL; 02435 } 02436 } 02437 #endif 02438 02439 reset_conf(p); 02440 if (num_restart_pending == 0) { 02441 restart_monitor(); 02442 } 02443 }
static int my_allocate_sub | ( | void * | pvt, | |
enum analog_sub | analogsub | |||
) | [static] |
Definition at line 2718 of file chan_dahdi.c.
References alloc_sub(), and analogsub_to_dahdisub().
02719 { 02720 struct dahdi_pvt *p = pvt; 02721 02722 return alloc_sub(p, analogsub_to_dahdisub(analogsub)); 02723 }
static void my_ami_channel_event | ( | void * | pvt, | |
struct ast_channel * | chan | |||
) | [static] |
Definition at line 2175 of file chan_dahdi.c.
References dahdi_ami_channel_event().
02176 { 02177 struct dahdi_pvt *p = pvt; 02178 02179 dahdi_ami_channel_event(p, chan); 02180 }
static void my_answer_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2956 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, and my_set_polarity().
02957 { 02958 struct dahdi_pvt *p = pvt; 02959 02960 if (!p->answeronpolarityswitch) { 02961 return; 02962 } 02963 02964 my_set_polarity(pvt, 1); 02965 }
static int my_callwait | ( | void * | pvt | ) | [static] |
Definition at line 1904 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().
01905 { 01906 struct dahdi_pvt *p = pvt; 01907 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 01908 if (p->cidspill) { 01909 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 01910 ast_free(p->cidspill); 01911 } 01912 01913 /* 01914 * SAS: Subscriber Alert Signal, 440Hz for 300ms 01915 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves 01916 */ 01917 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 01918 return -1; 01919 save_conference(p); 01920 /* Silence */ 01921 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 01922 if (!p->callwaitrings && p->callwaitingcallerid) { 01923 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 01924 p->callwaitcas = 1; 01925 p->cidlen = 2400 + 680 + READ_SIZE * 4; 01926 } else { 01927 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 01928 p->callwaitcas = 0; 01929 p->cidlen = 2400 + READ_SIZE * 4; 01930 } 01931 p->cidpos = 0; 01932 send_callerid(p); 01933 01934 return 0; 01935 }
static void my_cancel_cidspill | ( | void * | pvt | ) | [static] |
Definition at line 2357 of file chan_dahdi.c.
References ast_free, dahdi_pvt::cidspill, and restore_conference().
02358 { 02359 struct dahdi_pvt *p = pvt; 02360 02361 ast_free(p->cidspill); 02362 p->cidspill = NULL; 02363 restore_conference(p); 02364 }
static int my_check_confirmanswer | ( | void * | pvt | ) | [static] |
Definition at line 2340 of file chan_dahdi.c.
References dahdi_pvt::confirmanswer.
02341 { 02342 struct dahdi_pvt *p = pvt; 02343 if (p->confirmanswer) { 02344 return 1; 02345 } 02346 02347 return 0; 02348 }
static int my_check_for_conference | ( | void * | pvt | ) | [static] |
Definition at line 2517 of file chan_dahdi.c.
References check_for_conference().
02518 { 02519 struct dahdi_pvt *p = pvt; 02520 return check_for_conference(p); 02521 }
static int my_check_waitingfordt | ( | void * | pvt | ) | [static] |
Definition at line 2323 of file chan_dahdi.c.
References dahdi_pvt::waitingfordt.
02324 { 02325 struct dahdi_pvt *p = pvt; 02326 02327 if (p->waitingfordt.tv_usec) { 02328 return 1; 02329 } 02330 02331 return 0; 02332 }
static int my_complete_conference_update | ( | void * | pvt, | |
int | needconference | |||
) | [static] |
Definition at line 2467 of file chan_dahdi.c.
References conf_add(), GET_CHANNEL, isslavenative(), MAX_SLAVES, dahdi_pvt::slaves, SUB_REAL, and dahdi_pvt::subs.
02468 { 02469 struct dahdi_pvt *p = pvt; 02470 int needconf = needconference; 02471 int x; 02472 int useslavenative; 02473 struct dahdi_pvt *slave = NULL; 02474 02475 useslavenative = isslavenative(p, &slave); 02476 02477 /* If we have a slave, add him to our conference now. or DAX 02478 if this is slave native */ 02479 for (x = 0; x < MAX_SLAVES; x++) { 02480 if (p->slaves[x]) { 02481 if (useslavenative) 02482 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 02483 else { 02484 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 02485 needconf++; 02486 } 02487 } 02488 } 02489 /* If we're supposed to be in there, do so now */ 02490 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 02491 if (useslavenative) 02492 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 02493 else { 02494 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 02495 needconf++; 02496 } 02497 } 02498 /* If we have a master, add ourselves to his conference */ 02499 if (p->master) { 02500 if (isslavenative(p->master, NULL)) { 02501 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 02502 } else { 02503 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 02504 } 02505 } 02506 if (!needconf) { 02507 /* Nobody is left (or should be left) in our conference. 02508 Kill it. */ 02509 p->confno = -1; 02510 } 02511 02512 return 0; 02513 }
static int my_conf_add | ( | void * | pvt, | |
enum analog_sub | sub | |||
) | [static] |
Definition at line 2457 of file chan_dahdi.c.
References analogsub_to_dahdisub(), conf_add(), and dahdi_pvt::subs.
02458 { 02459 struct dahdi_pvt *p = pvt; 02460 int x = analogsub_to_dahdisub(sub); 02461 02462 return conf_add(p, &p->subs[x], x, 0); 02463 }
static int my_conf_del | ( | void * | pvt, | |
enum analog_sub | sub | |||
) | [static] |
Definition at line 2447 of file chan_dahdi.c.
References analogsub_to_dahdisub(), conf_del(), and dahdi_pvt::subs.
02448 { 02449 struct dahdi_pvt *p = pvt; 02450 int x = analogsub_to_dahdisub(sub); 02451 02452 return conf_del(p, &p->subs[x], x); 02453 }
static int my_confmute | ( | void * | pvt, | |
int | mute | |||
) | [static] |
Definition at line 2366 of file chan_dahdi.c.
References dahdi_confmute().
02367 { 02368 struct dahdi_pvt *p = pvt; 02369 return dahdi_confmute(p, mute); 02370 }
static int my_dahdi_write | ( | struct dahdi_pvt * | p, | |
unsigned char * | buf, | |||
int | len, | |||
int | idx, | |||
int | linear | |||
) | [static] |
Definition at line 9350 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().
09351 { 09352 int sent=0; 09353 int size; 09354 int res; 09355 int fd; 09356 fd = p->subs[idx].dfd; 09357 while (len) { 09358 size = len; 09359 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 09360 size = (linear ? READ_SIZE * 2 : READ_SIZE); 09361 res = write(fd, buf, size); 09362 if (res != size) { 09363 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 09364 return sent; 09365 } 09366 len -= size; 09367 buf += size; 09368 } 09369 return sent; 09370 }
static void my_deadlock_avoidance_private | ( | void * | pvt | ) | [static] |
Definition at line 2122 of file chan_dahdi.c.
References DEADLOCK_AVOIDANCE, and dahdi_pvt::lock.
02123 { 02124 struct dahdi_pvt *p = pvt; 02125 02126 DEADLOCK_AVOIDANCE(&p->lock); 02127 }
static void my_decrease_ss_count | ( | void | ) | [static] |
Definition at line 2399 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.
02400 { 02401 ast_mutex_lock(&ss_thread_lock); 02402 ss_thread_count--; 02403 ast_cond_signal(&ss_thread_complete); 02404 ast_mutex_unlock(&ss_thread_lock); 02405 }
static int my_dial_digits | ( | void * | pvt, | |
enum analog_sub | sub, | |||
struct analog_dialoperation * | dop | |||
) | [static] |
Definition at line 2990 of file chan_dahdi.c.
References ANALOG_DIAL_OP_REPLACE, ANALOG_SUB_REAL, analogsub_to_dahdisub(), ast_copy_string(), ast_debug, ast_log(), dahdi_pvt::channel, dahdi_subchannel::dfd, analog_dialoperation::dialstr, errno, LOG_ERROR, ast_channel::name, analog_dialoperation::op, dahdi_pvt::owner, and dahdi_pvt::subs.
02991 { 02992 int index = analogsub_to_dahdisub(sub); 02993 int res; 02994 struct dahdi_pvt *p = pvt; 02995 struct dahdi_dialoperation ddop; 02996 02997 if (dop->op != ANALOG_DIAL_OP_REPLACE) { 02998 ast_log(LOG_ERROR, "Fix the dial_digits callback!\n"); 02999 return -1; 03000 } 03001 03002 if (sub != ANALOG_SUB_REAL) { 03003 ast_log(LOG_ERROR, "Trying to dial_digits '%s' on channel %d subchannel %d\n", 03004 dop->dialstr, p->channel, sub); 03005 return -1; 03006 } 03007 03008 ddop.op = DAHDI_DIAL_OP_REPLACE; 03009 ast_copy_string(ddop.dialstr, dop->dialstr, sizeof(ddop.dialstr)); 03010 03011 ast_debug(1, "Channel %d: Sending '%s' to DAHDI_DIAL.\n", p->channel, ddop.dialstr); 03012 03013 res = ioctl(p->subs[index].dfd, DAHDI_DIAL, &ddop); 03014 if (res == -1) { 03015 ast_debug(1, "DAHDI_DIAL ioctl failed on %s: %s\n", p->owner->name, strerror(errno)); 03016 } 03017 03018 return res; 03019 }
static int my_distinctive_ring | ( | struct ast_channel * | chan, | |
void * | pvt, | |||
int | idx, | |||
int * | ringdata | |||
) | [static] |
Definition at line 1768 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.
01769 { 01770 unsigned char buf[256]; 01771 int distMatches; 01772 int curRingData[RING_PATTERNS]; 01773 int receivedRingT; 01774 int counter1; 01775 int counter; 01776 int i; 01777 int res; 01778 int checkaftercid = 0; 01779 01780 struct dahdi_pvt *p = pvt; 01781 struct analog_pvt *analog_p = p->sig_pvt; 01782 01783 if (ringdata == NULL) { 01784 ringdata = curRingData; 01785 } else { 01786 checkaftercid = 1; 01787 } 01788 01789 /* We must have a ring by now, so, if configured, lets try to listen for 01790 * distinctive ringing */ 01791 if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) { 01792 /* Clear the current ring data array so we don't have old data in it. */ 01793 for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++) 01794 ringdata[receivedRingT] = 0; 01795 receivedRingT = 0; 01796 if (checkaftercid && distinctiveringaftercid) 01797 ast_verb(3, "Detecting post-CID distinctive ring\n"); 01798 /* Check to see if context is what it should be, if not set to be. */ 01799 else if (strcmp(p->context,p->defcontext) != 0) { 01800 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 01801 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 01802 } 01803 01804 for (;;) { 01805 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 01806 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 01807 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 01808 ast_hangup(chan); 01809 return 1; 01810 } 01811 if (i & DAHDI_IOMUX_SIGEVENT) { 01812 res = dahdi_get_event(p->subs[idx].dfd); 01813 if (res == DAHDI_EVENT_NOALARM) { 01814 p->inalarm = 0; 01815 analog_p->inalarm = 0; 01816 } 01817 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 01818 res = 0; 01819 /* Let us detect distinctive ring */ 01820 01821 ringdata[receivedRingT] = analog_p->ringt; 01822 01823 if (analog_p->ringt < analog_p->ringt_base/2) 01824 break; 01825 /* Increment the ringT counter so we can match it against 01826 values in chan_dahdi.conf for distinctive ring */ 01827 if (++receivedRingT == RING_PATTERNS) 01828 break; 01829 } else if (i & DAHDI_IOMUX_READ) { 01830 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 01831 if (res < 0) { 01832 if (errno != ELAST) { 01833 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 01834 ast_hangup(chan); 01835 return 1; 01836 } 01837 break; 01838 } 01839 if (analog_p->ringt > 0) { 01840 if (!(--analog_p->ringt)) { 01841 res = -1; 01842 break; 01843 } 01844 } 01845 } 01846 } 01847 } 01848 if ((checkaftercid && usedistinctiveringdetection) || !checkaftercid) { 01849 /* this only shows up if you have n of the dring patterns filled in */ 01850 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",ringdata[0],ringdata[1],ringdata[2]); 01851 for (counter = 0; counter < 3; counter++) { 01852 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */ 01853 distMatches = 0; 01854 /* this only shows up if you have n of the dring patterns filled in */ 01855 ast_verb(3, "Checking %d,%d,%d\n", 01856 p->drings.ringnum[counter].ring[0], 01857 p->drings.ringnum[counter].ring[1], 01858 p->drings.ringnum[counter].ring[2]); 01859 for (counter1 = 0; counter1 < 3; counter1++) { 01860 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 01861 if (p->drings.ringnum[counter].ring[counter1] == -1) { 01862 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 01863 ringdata[counter1]); 01864 distMatches++; 01865 } else if (ringdata[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 01866 ringdata[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 01867 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 01868 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 01869 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 01870 distMatches++; 01871 } 01872 } 01873 01874 if (distMatches == 3) { 01875 /* The ring matches, set the context to whatever is for distinctive ring.. */ 01876 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 01877 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 01878 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 01879 break; 01880 } 01881 } 01882 } 01883 /* Restore linear mode (if appropriate) for Caller*ID processing */ 01884 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 01885 restore_gains(p); 01886 01887 return 0; 01888 }
static int my_dsp_reset_and_flush_digits | ( | void * | pvt | ) | [static] |
Definition at line 1972 of file chan_dahdi.c.
References ast_dsp_digitreset(), and dahdi_pvt::dsp.
01973 { 01974 struct dahdi_pvt *p = pvt; 01975 if (p->dsp) 01976 ast_dsp_digitreset(p->dsp); 01977 01978 return 0; 01979 }
static int my_dsp_set_digitmode | ( | void * | pvt, | |
enum analog_dsp_digitmode | mode | |||
) | [static] |
Definition at line 1981 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.
01982 { 01983 struct dahdi_pvt *p = pvt; 01984 01985 if (p->channel == CHAN_PSEUDO) 01986 ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n"); 01987 01988 if (mode == ANALOG_DIGITMODE_DTMF) { 01989 /* If we do hardware dtmf, no need for a DSP */ 01990 if (p->hardwaredtmf) { 01991 if (p->dsp) { 01992 ast_dsp_free(p->dsp); 01993 p->dsp = NULL; 01994 } 01995 return 0; 01996 } 01997 01998 if (!p->dsp) { 01999 p->dsp = ast_dsp_new(); 02000 if (!p->dsp) { 02001 ast_log(LOG_ERROR, "Unable to allocate DSP\n"); 02002 return -1; 02003 } 02004 } 02005 02006 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 02007 } else if (mode == ANALOG_DIGITMODE_MF) { 02008 if (!p->dsp) { 02009 p->dsp = ast_dsp_new(); 02010 if (!p->dsp) { 02011 ast_log(LOG_ERROR, "Unable to allocate DSP\n"); 02012 return -1; 02013 } 02014 } 02015 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 02016 } 02017 return 0; 02018 }
static int my_flash | ( | void * | pvt | ) | [static] |
Definition at line 2915 of file chan_dahdi.c.
References SUB_REAL, and dahdi_pvt::subs.
02916 { 02917 struct dahdi_pvt *p = pvt; 02918 int func = DAHDI_FLASH; 02919 return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func); 02920 }
static void my_get_and_handle_alarms | ( | void * | pvt | ) | [static] |
Definition at line 2208 of file chan_dahdi.c.
References get_alarms(), and handle_alarms().
02209 { 02210 int res; 02211 struct dahdi_pvt *p = pvt; 02212 02213 res = get_alarms(p); 02214 handle_alarms(p, res); 02215 }
static int my_get_callerid | ( | void * | pvt, | |
char * | namebuf, | |||
char * | numbuf, | |||
enum analog_event * | ev, | |||
size_t | timeout | |||
) | [static] |
Definition at line 1691 of file chan_dahdi.c.
References ANALOG_EVENT_NONE, ANALOG_MAX_CID, ast_copy_string(), ast_debug, 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_WARNING, name, analog_pvt::ringt, dahdi_pvt::sig_pvt, SUB_REAL, and dahdi_pvt::subs.
01692 { 01693 struct dahdi_pvt *p = pvt; 01694 struct analog_pvt *analog_p = p->sig_pvt; 01695 struct pollfd poller; 01696 char *name, *num; 01697 int index = SUB_REAL; 01698 int res; 01699 unsigned char buf[256]; 01700 int flags; 01701 01702 poller.fd = p->subs[SUB_REAL].dfd; 01703 poller.events = POLLPRI | POLLIN; 01704 poller.revents = 0; 01705 01706 res = poll(&poller, 1, timeout); 01707 01708 if (poller.revents & POLLPRI) { 01709 *ev = dahdievent_to_analogevent(dahdi_get_event(p->subs[SUB_REAL].dfd)); 01710 return 1; 01711 } 01712 01713 if (poller.revents & POLLIN) { 01714 /*** NOTES ***/ 01715 /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function 01716 * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until 01717 * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be 01718 * a failure and die, and returning 2 means no event was received. */ 01719 res = read(p->subs[index].dfd, buf, sizeof(buf)); 01720 if (res < 0) { 01721 if (errno != ELAST) { 01722 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 01723 callerid_free(p->cs); 01724 return -1; 01725 } 01726 } 01727 01728 if (analog_p->ringt > 0) { 01729 if (!(--analog_p->ringt)) { 01730 /* only return if we timeout from a ring event */ 01731 return -1; 01732 } 01733 } 01734 01735 if (p->cid_signalling == CID_SIG_V23_JP) { 01736 res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p)); 01737 } else { 01738 res = callerid_feed(p->cs, buf, res, AST_LAW(p)); 01739 } 01740 if (res < 0) { 01741 /* 01742 * The previous diagnostic message output likely 01743 * explains why it failed. 01744 */ 01745 ast_log(LOG_WARNING, "Failed to decode CallerID\n"); 01746 return -1; 01747 } 01748 01749 if (res == 1) { 01750 callerid_get(p->cs, &name, &num, &flags); 01751 if (name) 01752 ast_copy_string(namebuf, name, ANALOG_MAX_CID); 01753 if (num) 01754 ast_copy_string(numbuf, num, ANALOG_MAX_CID); 01755 01756 ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags); 01757 return 0; 01758 } 01759 } 01760 01761 *ev = ANALOG_EVENT_NONE; 01762 return 2; 01763 }
static int my_get_event | ( | void * | pvt | ) | [static] |
Definition at line 2848 of file chan_dahdi.c.
References dahdi_get_event(), dahdievent_to_analogevent(), dahdi_pvt::fake_event, SUB_REAL, and dahdi_pvt::subs.
02849 { 02850 struct dahdi_pvt *p = pvt; 02851 int res; 02852 02853 if (p->fake_event) { 02854 res = p->fake_event; 02855 p->fake_event = 0; 02856 } else 02857 res = dahdi_get_event(p->subs[SUB_REAL].dfd); 02858 02859 return dahdievent_to_analogevent(res); 02860 }
static const char* my_get_orig_dialstring | ( | void * | pvt | ) | [static] |
Definition at line 2385 of file chan_dahdi.c.
References dahdi_pvt::dialstring.
02386 { 02387 struct dahdi_pvt *p = pvt; 02388 02389 return p->dialstring; 02390 }
static void* my_get_sigpvt_bridged_channel | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 2217 of file chan_dahdi.c.
References ast_bridged_channel(), dahdi_pvt::sig_pvt, and ast_channel::tech_pvt.
02218 { 02219 struct dahdi_pvt *p = ast_bridged_channel(chan)->tech_pvt; 02220 if (p) 02221 return p->sig_pvt; 02222 else 02223 return NULL; 02224 }
static int my_get_sub_fd | ( | void * | pvt, | |
enum analog_sub | sub | |||
) | [static] |
Definition at line 2226 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
02227 { 02228 struct dahdi_pvt *p = pvt; 02229 int dahdi_sub = analogsub_to_dahdisub(sub); 02230 return p->subs[dahdi_sub].dfd; 02231 }
static int my_getsigstr | ( | struct ast_channel * | chan, | |
char * | str, | |||
const char * | term, | |||
int | ms | |||
) | [static] |
Definition at line 9831 of file chan_dahdi.c.
References ast_waitfordigit().
Referenced by analog_ss_thread().
09832 { 09833 char c; 09834 09835 *str = 0; /* start with empty output buffer */ 09836 for (;;) 09837 { 09838 /* Wait for the first digit (up to specified ms). */ 09839 c = ast_waitfordigit(chan, ms); 09840 /* if timeout, hangup or error, return as such */ 09841 if (c < 1) 09842 return c; 09843 *str++ = c; 09844 *str = 0; 09845 if (strchr(term, c)) 09846 return 1; 09847 } 09848 }
static void my_handle_dchan_exception | ( | struct sig_pri_span * | pri, | |
int | index | |||
) | [static] |
Definition at line 3113 of file chan_dahdi.c.
References ast_log(), event2str(), sig_pri_span::fds, LOG_NOTICE, dahdi_pvt::pri, pri_event_alarm(), pri_event_noalarm(), sig_pri_is_alarm_ignored(), and sig_pri_span::span.
03114 { 03115 int x; 03116 03117 ioctl(pri->fds[index], DAHDI_GETEVENT, &x); 03118 switch (x) { 03119 case DAHDI_EVENT_NONE: 03120 break; 03121 case DAHDI_EVENT_ALARM: 03122 case DAHDI_EVENT_NOALARM: 03123 if (sig_pri_is_alarm_ignored(pri)) { 03124 break; 03125 } 03126 /* Fall through */ 03127 default: 03128 ast_log(LOG_NOTICE, "PRI got event: %s (%d) on D-channel of span %d\n", 03129 event2str(x), x, pri->span); 03130 break; 03131 } 03132 /* Keep track of alarm state */ 03133 switch (x) { 03134 case DAHDI_EVENT_ALARM: 03135 pri_event_alarm(pri, index, 0); 03136 break; 03137 case DAHDI_EVENT_NOALARM: 03138 pri_event_noalarm(pri, index, 0); 03139 break; 03140 default: 03141 break; 03142 } 03143 }
static void my_handle_dtmf | ( | void * | pvt, | |
struct ast_channel * | ast, | |||
enum analog_sub | analog_index, | |||
struct ast_frame ** | dest | |||
) | [static] |
Definition at line 2038 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.
02039 { 02040 struct ast_frame *f = *dest; 02041 struct dahdi_pvt *p = pvt; 02042 int idx = analogsub_to_dahdisub(analog_index); 02043 02044 ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n", 02045 f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End", 02046 f->subclass.integer, f->subclass.integer, ast->name); 02047 02048 if (f->subclass.integer == 'f') { 02049 if (f->frametype == AST_FRAME_DTMF_END) { 02050 /* Fax tone -- Handle and return NULL */ 02051 if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) { 02052 /* If faxbuffers are configured, use them for the fax transmission */ 02053 if (p->usefaxbuffers && !p->bufferoverrideinuse) { 02054 struct dahdi_bufferinfo bi = { 02055 .txbufpolicy = p->faxbuf_policy, 02056 .bufsize = p->bufsize, 02057 .numbufs = p->faxbuf_no 02058 }; 02059 int res; 02060 02061 if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 02062 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast->name, strerror(errno)); 02063 } else { 02064 p->bufferoverrideinuse = 1; 02065 } 02066 } 02067 p->faxhandled = 1; 02068 if (p->dsp) { 02069 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 02070 ast_dsp_set_features(p->dsp, p->dsp_features); 02071 ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast->name); 02072 } 02073 if (strcmp(ast->exten, "fax")) { 02074 const char *target_context = S_OR(ast->macrocontext, ast->context); 02075 02076 /* We need to unlock 'ast' here because ast_exists_extension has the 02077 * potential to start autoservice on the channel. Such action is prone 02078 * to deadlock. 02079 */ 02080 ast_mutex_unlock(&p->lock); 02081 ast_channel_unlock(ast); 02082 if (ast_exists_extension(ast, target_context, "fax", 1, 02083 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 02084 ast_channel_lock(ast); 02085 ast_mutex_lock(&p->lock); 02086 ast_verb(3, "Redirecting %s to fax extension\n", ast->name); 02087 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 02088 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 02089 if (ast_async_goto(ast, target_context, "fax", 1)) 02090 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 02091 } else { 02092 ast_channel_lock(ast); 02093 ast_mutex_lock(&p->lock); 02094 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 02095 } 02096 } else { 02097 ast_debug(1, "Already in a fax extension, not redirecting\n"); 02098 } 02099 } else { 02100 ast_debug(1, "Fax already handled\n"); 02101 } 02102 dahdi_confmute(p, 0); 02103 } 02104 p->subs[idx].f.frametype = AST_FRAME_NULL; 02105 p->subs[idx].f.subclass.integer = 0; 02106 *dest = &p->subs[idx].f; 02107 } 02108 }
static void my_handle_notify_message | ( | struct ast_channel * | chan, | |
void * | pvt, | |||
int | cid_flags, | |||
int | neon_mwievent | |||
) | [static] |
Definition at line 3632 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().
03633 { 03634 struct dahdi_pvt *p = pvt; 03635 03636 if (neon_mwievent > -1 && !p->mwimonitor_neon) 03637 return; 03638 03639 if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) { 03640 ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox); 03641 notify_message(p->mailbox, 1); 03642 } else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) { 03643 ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox); 03644 notify_message(p->mailbox, 0); 03645 } 03646 /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */ 03647 /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */ 03648 if (neon_mwievent == -1 && p->mwimonitor_rpas) { 03649 ast_hangup(chan); 03650 return; 03651 } 03652 }
static void my_hangup_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2967 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, dahdi_pvt::hanguponpolarityswitch, and my_set_polarity().
02968 { 02969 struct dahdi_pvt *p = pvt; 02970 02971 if (!p->hanguponpolarityswitch) { 02972 return; 02973 } 02974 02975 if (p->answeronpolarityswitch) { 02976 my_set_polarity(pvt, 0); 02977 } else { 02978 my_set_polarity(pvt, 1); 02979 } 02980 }
static int my_has_voicemail | ( | void * | pvt | ) | [static] |
Definition at line 2727 of file chan_dahdi.c.
References has_voicemail().
02728 { 02729 struct dahdi_pvt *p = pvt; 02730 02731 return has_voicemail(p); 02732 }
static int my_have_progressdetect | ( | void * | pvt | ) | [static] |
Definition at line 3654 of file chan_dahdi.c.
References dahdi_pvt::callprogress, CALLPROGRESS_PROGRESS, CANPROGRESSDETECT, dahdi_pvt::dsp, and dahdi_pvt::outgoing.
03655 { 03656 struct dahdi_pvt *p = pvt; 03657 03658 if ((p->callprogress & CALLPROGRESS_PROGRESS) 03659 && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 03660 return 1; 03661 } else { 03662 /* Don't have progress detection. */ 03663 return 0; 03664 } 03665 }
static void my_increase_ss_count | ( | void | ) | [static] |
Definition at line 2392 of file chan_dahdi.c.
References ast_mutex_lock, ast_mutex_unlock, ss_thread_count, and ss_thread_lock.
02393 { 02394 ast_mutex_lock(&ss_thread_lock); 02395 ss_thread_count++; 02396 ast_mutex_unlock(&ss_thread_lock); 02397 }
static int my_is_dialing | ( | void * | pvt, | |
enum analog_sub | sub | |||
) | [static] |
Definition at line 3032 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_log(), dahdi_subchannel::dfd, LOG_DEBUG, and dahdi_pvt::subs.
03033 { 03034 struct dahdi_pvt *p = pvt; 03035 int index; 03036 int x; 03037 03038 index = analogsub_to_dahdisub(sub); 03039 03040 if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) { 03041 ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed!\n"); 03042 return -1; 03043 } 03044 03045 return x; 03046 }
static int my_is_off_hook | ( | void * | pvt | ) | [static] |
Definition at line 2862 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.
02863 { 02864 struct dahdi_pvt *p = pvt; 02865 int res; 02866 struct dahdi_params par; 02867 02868 memset(&par, 0, sizeof(par)); 02869 02870 if (p->subs[SUB_REAL].dfd > -1) 02871 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par); 02872 else { 02873 /* Assume not off hook on CVRS */ 02874 res = 0; 02875 par.rxisoffhook = 0; 02876 } 02877 if (res) { 02878 ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno)); 02879 } 02880 02881 if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 02882 /* When "onhook" that means no battery on the line, and thus 02883 it is out of service..., if it's on a TDM card... If it's a channel 02884 bank, there is no telling... */ 02885 return (par.rxbits > -1) || par.rxisoffhook; 02886 } 02887 02888 return par.rxisoffhook; 02889 }
static void my_lock_private | ( | void * | pvt | ) | [static] |
Definition at line 2110 of file chan_dahdi.c.
References ast_mutex_lock, and dahdi_pvt::lock.
02111 { 02112 struct dahdi_pvt *p = pvt; 02113 ast_mutex_lock(&p->lock); 02114 }
static void my_module_ref | ( | void | ) | [static] |
Definition at line 3365 of file chan_dahdi.c.
References ast_module_ref().
03366 { 03367 ast_module_ref(ast_module_info->self); 03368 }
static void my_module_unref | ( | void | ) | [static] |
Definition at line 3379 of file chan_dahdi.c.
References ast_module_unref().
03380 { 03381 ast_module_unref(ast_module_info->self); 03382 }
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 2557 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_new(), and ast_channel::linkedid.
02558 { 02559 struct dahdi_pvt *p = pvt; 02560 int dsub = analogsub_to_dahdisub(sub); 02561 02562 return dahdi_new(p, state, startpbx, dsub, 0, requestor ? requestor->linkedid : ""); 02563 }
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 2577 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.
02578 { 02579 struct dahdi_pvt *p = pvt; 02580 int audio; 02581 int newlaw = -1; 02582 02583 switch (p->sig) { 02584 case SIG_PRI_LIB_HANDLE_CASES: 02585 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 02586 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */ 02587 break; 02588 } 02589 /* Fall through */ 02590 default: 02591 /* Set to audio mode at this point */ 02592 audio = 1; 02593 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1) { 02594 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", 02595 p->channel, audio, strerror(errno)); 02596 } 02597 break; 02598 } 02599 02600 if (law != SIG_PRI_DEFLAW) { 02601 dahdi_setlaw(p->subs[SUB_REAL].dfd, (law == SIG_PRI_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW); 02602 } 02603 02604 ast_copy_string(p->exten, exten, sizeof(p->exten)); 02605 02606 switch (law) { 02607 case SIG_PRI_DEFLAW: 02608 newlaw = 0; 02609 break; 02610 case SIG_PRI_ALAW: 02611 newlaw = DAHDI_LAW_ALAW; 02612 break; 02613 case SIG_PRI_ULAW: 02614 newlaw = DAHDI_LAW_MULAW; 02615 break; 02616 } 02617 return dahdi_new(p, state, 0, SUB_REAL, newlaw, requestor ? requestor->linkedid : ""); 02618 }
static int my_off_hook | ( | void * | pvt | ) | [static] |
Definition at line 2924 of file chan_dahdi.c.
References dahdi_set_hook(), SUB_REAL, and dahdi_pvt::subs.
02925 { 02926 struct dahdi_pvt *p = pvt; 02927 return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 02928 }
static int my_on_hook | ( | void * | pvt | ) | [static] |
Definition at line 3048 of file chan_dahdi.c.
References ANALOG_SUB_REAL, dahdi_set_hook(), and dahdi_pvt::subs.
03049 { 03050 struct dahdi_pvt *p = pvt; 03051 return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK); 03052 }
static int my_play_tone | ( | void * | pvt, | |
enum analog_sub | sub, | |||
enum analog_tone | tone | |||
) | [static] |
Definition at line 2734 of file chan_dahdi.c.
References analog_tone_to_dahditone(), analogsub_to_dahdisub(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
02735 { 02736 struct dahdi_pvt *p = pvt; 02737 int index; 02738 02739 index = analogsub_to_dahdisub(sub); 02740 02741 return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone)); 02742 }
static void my_pri_dial_digits | ( | void * | p, | |
const char * | dial_string | |||
) | [static] |
Definition at line 2687 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_pvt::channel, dahdi_pvt::dialing, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.
02688 { 02689 struct dahdi_dialoperation zo = { 02690 .op = DAHDI_DIAL_OP_APPEND, 02691 }; 02692 struct dahdi_pvt *pvt = p; 02693 int res; 02694 02695 snprintf(zo.dialstr, sizeof(zo.dialstr), "T%s", dial_string); 02696 ast_debug(1, "Channel %d: Sending '%s' to DAHDI_DIAL.\n", pvt->channel, zo.dialstr); 02697 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo); 02698 if (res) { 02699 ast_log(LOG_WARNING, "Channel %d: Couldn't dial '%s': %s\n", 02700 pvt->channel, dial_string, strerror(errno)); 02701 } else { 02702 pvt->dialing = 1; 02703 } 02704 }
static void my_pri_fixup_chans | ( | void * | chan_old, | |
void * | chan_new | |||
) | [static] |
Definition at line 3055 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.
03056 { 03057 struct dahdi_pvt *old_chan = chan_old; 03058 struct dahdi_pvt *new_chan = chan_new; 03059 03060 new_chan->owner = old_chan->owner; 03061 old_chan->owner = NULL; 03062 if (new_chan->owner) { 03063 new_chan->owner->tech_pvt = new_chan; 03064 new_chan->owner->fds[0] = new_chan->subs[SUB_REAL].dfd; 03065 new_chan->subs[SUB_REAL].owner = old_chan->subs[SUB_REAL].owner; 03066 old_chan->subs[SUB_REAL].owner = NULL; 03067 } 03068 /* Copy any DSP that may be present */ 03069 new_chan->dsp = old_chan->dsp; 03070 new_chan->dsp_features = old_chan->dsp_features; 03071 old_chan->dsp = NULL; 03072 old_chan->dsp_features = 0; 03073 03074 /* Transfer flags from the old channel. */ 03075 new_chan->dialing = old_chan->dialing; 03076 new_chan->digital = old_chan->digital; 03077 new_chan->outgoing = old_chan->outgoing; 03078 old_chan->dialing = 0; 03079 old_chan->digital = 0; 03080 old_chan->outgoing = 0; 03081 03082 /* More stuff to transfer to the new channel. */ 03083 new_chan->law = old_chan->law; 03084 strcpy(new_chan->dialstring, old_chan->dialstring); 03085 }
static void my_pri_init_config | ( | void * | priv, | |
struct sig_pri_span * | pri | |||
) | [static] |
Definition at line 13281 of file chan_dahdi.c.
References ast_copy_string(), sig_pri_span::ch_cfg, sig_pri_span::context, dahdi_pvt::context, sig_pri_span::hidecallerid, dahdi_pvt::hidecallerid, sig_pri_span::hidecalleridname, dahdi_pvt::hidecalleridname, sig_pri_span::immediate, dahdi_pvt::immediate, sig_pri_span::mohinterpret, dahdi_pvt::mohinterpret, dahdi_pvt::pri, sig_pri_span::priexclusive, dahdi_pvt::priexclusive, sig_pri_span::priindication_oob, dahdi_pvt::priindication_oob, sig_pri_span::stripmsd, dahdi_pvt::stripmsd, sig_pri_span::use_callerid, dahdi_pvt::use_callerid, sig_pri_span::use_callingpres, and dahdi_pvt::use_callingpres.
13282 { 13283 struct dahdi_pvt *pvt = priv; 13284 13285 pvt->stripmsd = pri->ch_cfg.stripmsd; 13286 pvt->hidecallerid = pri->ch_cfg.hidecallerid; 13287 pvt->hidecalleridname = pri->ch_cfg.hidecalleridname; 13288 pvt->immediate = pri->ch_cfg.immediate; 13289 pvt->priexclusive = pri->ch_cfg.priexclusive; 13290 pvt->priindication_oob = pri->ch_cfg.priindication_oob; 13291 pvt->use_callerid = pri->ch_cfg.use_callerid; 13292 pvt->use_callingpres = pri->ch_cfg.use_callingpres; 13293 ast_copy_string(pvt->context, pri->ch_cfg.context, sizeof(pvt->context)); 13294 ast_copy_string(pvt->mohinterpret, pri->ch_cfg.mohinterpret, sizeof(pvt->mohinterpret)); 13295 }
static void my_pri_make_cc_dialstring | ( | void * | priv, | |
char * | buf, | |||
size_t | buf_size | |||
) | [static] |
Definition at line 3254 of file chan_dahdi.c.
References args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_NONSTANDARD_APP_ARGS, and ast_strdupa.
03255 { 03256 char *dial; 03257 struct dahdi_pvt *pvt; 03258 AST_DECLARE_APP_ARGS(args, 03259 AST_APP_ARG(tech); /* channel technology token */ 03260 AST_APP_ARG(group); /* channel/group token */ 03261 //AST_APP_ARG(ext); /* extension token */ 03262 //AST_APP_ARG(opts); /* options token */ 03263 //AST_APP_ARG(other); /* Any remining unused arguments */ 03264 ); 03265 03266 pvt = priv; 03267 dial = ast_strdupa(pvt->dialstring); 03268 AST_NONSTANDARD_APP_ARGS(args, dial, '/'); 03269 if (!args.tech) { 03270 ast_copy_string(buf, pvt->dialstring, buf_size); 03271 return; 03272 } 03273 if (!args.group) { 03274 /* Append the ISDN span channel restriction to the dialstring. */ 03275 snprintf(buf, buf_size, "%s/i%d-", args.tech, pvt->pri->span); 03276 return; 03277 } 03278 if (isdigit(args.group[0]) || args.group[0] == 'i' || strchr(args.group, '!')) { 03279 /* The ISDN span channel restriction is not needed or already 03280 * in the dialstring. */ 03281 ast_copy_string(buf, pvt->dialstring, buf_size); 03282 return; 03283 } 03284 /* Insert the ISDN span channel restriction into the dialstring. */ 03285 snprintf(buf, buf_size, "%s/i%d-%s", args.tech, pvt->pri->span, args.group); 03286 }
static int my_pri_play_tone | ( | void * | pvt, | |
enum sig_pri_tone | tone | |||
) | [static] |
Definition at line 3147 of file chan_dahdi.c.
References sig_pri_tone_to_dahditone(), SUB_REAL, and dahdi_pvt::subs.
03148 { 03149 struct dahdi_pvt *p = pvt; 03150 03151 return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_pri_tone_to_dahditone(tone)); 03152 }
static void my_pri_ss7_open_media | ( | void * | p | ) | [static] |
Definition at line 2633 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.
02634 { 02635 struct dahdi_pvt *pvt = p; 02636 int res; 02637 int dfd; 02638 int set_val; 02639 02640 dfd = pvt->subs[SUB_REAL].dfd; 02641 02642 /* Open the media path. */ 02643 set_val = 1; 02644 res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val); 02645 if (res < 0) { 02646 ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", 02647 pvt->channel, strerror(errno)); 02648 } 02649 02650 /* Set correct companding law for this call. */ 02651 res = dahdi_setlaw(dfd, pvt->law); 02652 if (res < 0) { 02653 ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pvt->channel); 02654 } 02655 02656 /* Set correct gain for this call. */ 02657 if (pvt->digital) { 02658 res = set_actual_gain(dfd, 0, 0, pvt->rxdrc, pvt->txdrc, pvt->law); 02659 } else { 02660 res = set_actual_gain(dfd, pvt->rxgain, pvt->txgain, pvt->rxdrc, pvt->txdrc, 02661 pvt->law); 02662 } 02663 if (res < 0) { 02664 ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pvt->channel); 02665 } 02666 02667 if (pvt->dsp_features && pvt->dsp) { 02668 ast_dsp_set_features(pvt->dsp, pvt->dsp_features); 02669 pvt->dsp_features = 0; 02670 } 02671 }
static int my_ring | ( | void * | pvt | ) | [static] |
Definition at line 2908 of file chan_dahdi.c.
References dahdi_ring_phone().
02909 { 02910 struct dahdi_pvt *p = pvt; 02911 02912 return dahdi_ring_phone(p); 02913 }
static int my_send_callerid | ( | void * | pvt, | |
int | cwcid, | |||
struct ast_party_caller * | caller | |||
) | [static] |
Definition at line 1937 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.
01938 { 01939 struct dahdi_pvt *p = pvt; 01940 01941 ast_debug(2, "Starting cid spill\n"); 01942 01943 if (p->cidspill) { 01944 ast_log(LOG_WARNING, "cidspill already exists??\n"); 01945 ast_free(p->cidspill); 01946 } 01947 01948 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) { 01949 if (cwcid == 0) { 01950 p->cidlen = ast_callerid_generate(p->cidspill, 01951 caller->id.name.str, 01952 caller->id.number.str, 01953 AST_LAW(p)); 01954 } else { 01955 ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", 01956 caller->id.name.str, caller->id.number.str); 01957 p->callwaitcas = 0; 01958 p->cidcwexpire = 0; 01959 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, 01960 caller->id.name.str, 01961 caller->id.number.str, 01962 AST_LAW(p)); 01963 p->cidlen += READ_SIZE * 4; 01964 } 01965 p->cidpos = 0; 01966 p->cid_suppress_expire = 0; 01967 send_callerid(p); 01968 } 01969 return 0; 01970 }
static void my_set_alarm | ( | void * | pvt, | |
int | in_alarm | |||
) | [static] |
static void my_set_cadence | ( | void * | pvt, | |
int * | cid_rings, | |||
struct ast_channel * | ast | |||
) | [static] |
Definition at line 2233 of file chan_dahdi.c.
References ast_log(), cadences, cidrings, dahdi_pvt::distinctivering, errno, LOG_WARNING, ast_channel::name, num_cadence, dahdi_pvt::sendcalleridafter, SUB_REAL, and dahdi_pvt::subs.
02234 { 02235 struct dahdi_pvt *p = pvt; 02236 02237 /* Choose proper cadence */ 02238 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) { 02239 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1])) 02240 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno)); 02241 *cid_rings = cidrings[p->distinctivering - 1]; 02242 } else { 02243 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL)) 02244 ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno)); 02245 *cid_rings = p->sendcalleridafter; 02246 } 02247 }
static void my_set_callerid | ( | void * | pvt, | |
const struct ast_party_caller * | caller | |||
) | [static] |
Definition at line 3166 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.
03167 { 03168 struct dahdi_pvt *p = pvt; 03169 03170 ast_copy_string(p->cid_num, 03171 S_COR(caller->id.number.valid, caller->id.number.str, ""), 03172 sizeof(p->cid_num)); 03173 ast_copy_string(p->cid_name, 03174 S_COR(caller->id.name.valid, caller->id.name.str, ""), 03175 sizeof(p->cid_name)); 03176 ast_copy_string(p->cid_subaddr, 03177 S_COR(caller->id.subaddress.valid, caller->id.subaddress.str, ""), 03178 sizeof(p->cid_subaddr)); 03179 p->cid_ton = caller->id.number.plan; 03180 p->callingpres = ast_party_id_presentation(&caller->id); 03181 if (caller->id.tag) { 03182 ast_copy_string(p->cid_tag, caller->id.tag, sizeof(p->cid_tag)); 03183 } 03184 ast_copy_string(p->cid_ani, 03185 S_COR(caller->ani.number.valid, caller->ani.number.str, ""), 03186 sizeof(p->cid_ani)); 03187 p->cid_ani2 = caller->ani2; 03188 }
static void my_set_callwaiting | ( | void * | pvt, | |
int | callwaiting_enable | |||
) | [static] |
Definition at line 2350 of file chan_dahdi.c.
References dahdi_pvt::callwaiting.
02351 { 02352 struct dahdi_pvt *p = pvt; 02353 02354 p->callwaiting = callwaiting_enable; 02355 }
static void my_set_confirmanswer | ( | void * | pvt, | |
int | flag | |||
) | [static] |
Definition at line 2334 of file chan_dahdi.c.
References dahdi_pvt::confirmanswer.
02335 { 02336 struct dahdi_pvt *p = pvt; 02337 p->confirmanswer = flag; 02338 }
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 3202 of file chan_dahdi.c.
References ast_copy_string(), and dahdi_pvt::dnid.
03203 { 03204 struct dahdi_pvt *p = pvt; 03205 03206 ast_copy_string(p->dnid, dnid, sizeof(p->dnid)); 03207 }
static int my_set_echocanceller | ( | void * | pvt, | |
int | enable | |||
) | [static] |
Definition at line 2894 of file chan_dahdi.c.
References dahdi_disable_ec(), and dahdi_enable_ec().
02895 { 02896 struct dahdi_pvt *p = pvt; 02897 02898 if (enable) 02899 dahdi_enable_ec(p); 02900 else 02901 dahdi_disable_ec(p); 02902 02903 return 0; 02904 }
static void my_set_inthreeway | ( | void * | pvt, | |
enum analog_sub | sub, | |||
int | inthreeway | |||
) | [static] |
Definition at line 2198 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_subchannel::inthreeway, and dahdi_pvt::subs.
02199 { 02200 struct dahdi_pvt *p = pvt; 02201 int idx = analogsub_to_dahdisub(sub); 02202 02203 p->subs[idx].inthreeway = inthreeway; 02204 }
static int my_set_linear_mode | ( | void * | pvt, | |
enum analog_sub | sub, | |||
int | linear_mode | |||
) | [static] |
Definition at line 2186 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_setlinear(), dahdi_subchannel::dfd, dahdi_subchannel::linear, and dahdi_pvt::subs.
02187 { 02188 struct dahdi_pvt *p = pvt; 02189 int oldval; 02190 int idx = analogsub_to_dahdisub(sub); 02191 02192 dahdi_setlinear(p->subs[idx].dfd, linear_mode); 02193 oldval = p->subs[idx].linear; 02194 p->subs[idx].linear = linear_mode ? 1 : 0; 02195 return oldval; 02196 }
static void my_set_needringing | ( | void * | pvt, | |
int | value | |||
) | [static] |
Definition at line 2930 of file chan_dahdi.c.
References dahdi_subchannel::needringing, SUB_REAL, and dahdi_pvt::subs.
02931 { 02932 struct dahdi_pvt *p = pvt; 02933 p->subs[SUB_REAL].needringing = value; 02934 }
static void my_set_new_owner | ( | void * | pvt, | |
struct ast_channel * | new_owner | |||
) | [static] |
static void my_set_outgoing | ( | void * | pvt, | |
int | is_outgoing | |||
) | [static] |
static void my_set_polarity | ( | void * | pvt, | |
int | value | |||
) | [static] |
Definition at line 2936 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().
02937 { 02938 struct dahdi_pvt *p = pvt; 02939 02940 if (p->channel == CHAN_PSEUDO) { 02941 return; 02942 } 02943 p->polarity = value; 02944 ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETPOLARITY, &value); 02945 }
static void my_set_pulsedial | ( | void * | pvt, | |
int | flag | |||
) | [static] |
static void my_set_rdnis | ( | void * | pvt, | |
const char * | rdnis | |||
) | [static] |
Definition at line 3221 of file chan_dahdi.c.
References ast_copy_string(), and dahdi_pvt::rdnis.
03222 { 03223 struct dahdi_pvt *p = pvt; 03224 03225 ast_copy_string(p->rdnis, rdnis, sizeof(p->rdnis)); 03226 }
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 2312 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.
02313 { 02314 struct dahdi_pvt *p = pvt; 02315 02316 if (p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp) { 02317 ast_log(LOG_DEBUG, "Defer dialing for %dms or dialtone\n", p->waitfordialtone); 02318 gettimeofday(&p->waitingfordt, NULL); 02319 ast_setstate(ast, AST_STATE_OFFHOOK); 02320 } 02321 }
static int my_start | ( | void * | pvt | ) | [static] |
Definition at line 2982 of file chan_dahdi.c.
References SUB_REAL, and dahdi_pvt::subs.
02983 { 02984 struct dahdi_pvt *p = pvt; 02985 int x = DAHDI_START; 02986 02987 return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 02988 }
static int my_start_cid_detect | ( | void * | pvt, | |
int | cid_signalling | |||
) | [static] |
Definition at line 1666 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.
01667 { 01668 struct dahdi_pvt *p = pvt; 01669 int index = SUB_REAL; 01670 p->cs = callerid_new(cid_signalling); 01671 if (!p->cs) { 01672 ast_log(LOG_ERROR, "Unable to alloc callerid\n"); 01673 return -1; 01674 } 01675 bump_gains(p); 01676 dahdi_setlinear(p->subs[index].dfd, 0); 01677 01678 return 0; 01679 }
static void my_start_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2947 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, dahdi_pvt::hanguponpolarityswitch, and my_set_polarity().
02948 { 02949 struct dahdi_pvt *p = pvt; 02950 02951 if (p->answeronpolarityswitch || p->hanguponpolarityswitch) { 02952 my_set_polarity(pvt, 0); 02953 } 02954 }
static int my_stop_callwait | ( | void * | pvt | ) | [static] |
Definition at line 1890 of file chan_dahdi.c.
References dahdi_pvt::callwaitingrepeat, dahdi_pvt::cid_suppress_expire, and dahdi_pvt::cidcwexpire.
01891 { 01892 struct dahdi_pvt *p = pvt; 01893 p->callwaitingrepeat = 0; 01894 p->cidcwexpire = 0; 01895 p->cid_suppress_expire = 0; 01896 01897 return 0; 01898 }
static int my_stop_cid_detect | ( | void * | pvt | ) | [static] |
Definition at line 1681 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.
01682 { 01683 struct dahdi_pvt *p = pvt; 01684 int index = SUB_REAL; 01685 if (p->cs) 01686 callerid_free(p->cs); 01687 dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear); 01688 return 0; 01689 }
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 2523 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().
02524 { 02525 struct dahdi_pvt *p = pvt; 02526 int da, db; 02527 int tchan; 02528 int tinthreeway; 02529 02530 da = analogsub_to_dahdisub(a); 02531 db = analogsub_to_dahdisub(b); 02532 02533 tchan = p->subs[da].chan; 02534 p->subs[da].chan = p->subs[db].chan; 02535 p->subs[db].chan = tchan; 02536 02537 tinthreeway = p->subs[da].inthreeway; 02538 p->subs[da].inthreeway = p->subs[db].inthreeway; 02539 p->subs[db].inthreeway = tinthreeway; 02540 02541 p->subs[da].owner = ast_a; 02542 p->subs[db].owner = ast_b; 02543 02544 if (ast_a) 02545 ast_channel_set_fd(ast_a, 0, p->subs[da].dfd); 02546 if (ast_b) 02547 ast_channel_set_fd(ast_b, 0, p->subs[db].dfd); 02548 02549 wakeup_sub(p, a); 02550 wakeup_sub(p, b); 02551 02552 return; 02553 }
static int my_train_echocanceller | ( | void * | pvt | ) | [static] |
Definition at line 3023 of file chan_dahdi.c.
References dahdi_train_ec().
03024 { 03025 struct dahdi_pvt *p = pvt; 03026 03027 dahdi_train_ec(p); 03028 03029 return 0; 03030 }
static int my_unallocate_sub | ( | void * | pvt, | |
enum analog_sub | analogsub | |||
) | [static] |
Definition at line 2709 of file chan_dahdi.c.
References analogsub_to_dahdisub(), and unalloc_sub().
02710 { 02711 struct dahdi_pvt *p = pvt; 02712 02713 return unalloc_sub(p, analogsub_to_dahdisub(analogsub)); 02714 }
static void my_unlock_private | ( | void * | pvt | ) | [static] |
Definition at line 2116 of file chan_dahdi.c.
References ast_mutex_unlock, and dahdi_pvt::lock.
02117 { 02118 struct dahdi_pvt *p = pvt; 02119 ast_mutex_unlock(&p->lock); 02120 }
static int my_wait_event | ( | void * | pvt | ) | [static] |
Definition at line 2841 of file chan_dahdi.c.
References dahdi_wait_event(), SUB_REAL, and dahdi_pvt::subs.
02842 { 02843 struct dahdi_pvt *p = pvt; 02844 02845 return dahdi_wait_event(p->subs[SUB_REAL].dfd); 02846 }
static int my_wink | ( | void * | pvt, | |
enum analog_sub | sub | |||
) | [static] |
Definition at line 2022 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_log(), dahdi_wink(), LOG_ERROR, and SUB_REAL.
02023 { 02024 struct dahdi_pvt *p = pvt; 02025 int index = analogsub_to_dahdisub(sub); 02026 if (index != SUB_REAL) { 02027 ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n"); 02028 } 02029 return dahdi_wink(p, index); 02030 }
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 3603 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().
03604 { 03605 char s[sizeof(mwimonitornotify) + 80]; 03606 struct ast_event *event; 03607 char *mailbox, *context; 03608 03609 /* Strip off @default */ 03610 context = mailbox = ast_strdupa(mailbox_full); 03611 strsep(&context, "@"); 03612 if (ast_strlen_zero(context)) 03613 context = "default"; 03614 03615 if (!(event = ast_event_new(AST_EVENT_MWI, 03616 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 03617 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 03618 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot, 03619 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot, 03620 AST_EVENT_IE_END))) { 03621 return; 03622 } 03623 03624 ast_event_queue_and_cache(event); 03625 03626 if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) { 03627 snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot); 03628 ast_safe_system(s); 03629 } 03630 }
static int parse_buffers_policy | ( | const char * | parse, | |
int * | num_buffers, | |||
int * | policy | |||
) | [static] |
Definition at line 7047 of file chan_dahdi.c.
References ast_log(), and LOG_WARNING.
Referenced by dahdi_func_write().
07048 { 07049 int res; 07050 char policy_str[21] = ""; 07051 07052 if ((res = sscanf(parse, "%30d,%20s", num_buffers, policy_str)) != 2) { 07053 ast_log(LOG_WARNING, "Parsing buffer string '%s' failed.\n", parse); 07054 return 1; 07055 } 07056 if (*num_buffers < 0) { 07057 ast_log(LOG_WARNING, "Invalid buffer count given '%d'.\n", *num_buffers); 07058 return -1; 07059 } 07060 if (!strcasecmp(policy_str, "full")) { 07061 *policy = DAHDI_POLICY_WHEN_FULL; 07062 } else if (!strcasecmp(policy_str, "immediate")) { 07063 *policy = DAHDI_POLICY_IMMEDIATE; 07064 #if defined(HAVE_DAHDI_HALF_FULL) 07065 } else if (!strcasecmp(policy_str, "half")) { 07066 *policy = DAHDI_POLICY_HALF_FULL; 07067 #endif 07068 } else { 07069 ast_log(LOG_WARNING, "Invalid policy name given '%s'.\n", policy_str); 07070 return -1; 07071 } 07072 07073 return 0; 07074 }
static char* parse_spanchan | ( | char * | chanstr, | |
char ** | subdir | |||
) | [static] |
Definition at line 16816 of file chan_dahdi.c.
References string_replace().
Referenced by build_channels().
16817 { 16818 char *p; 16819 16820 if ((p = strrchr(chanstr, '!')) == NULL) { 16821 *subdir = NULL; 16822 return chanstr; 16823 } 16824 *p++ = '\0'; 16825 string_replace(chanstr, '!', '/'); 16826 *subdir = chanstr; 16827 return p; 16828 }
static int prepare_pri | ( | struct dahdi_pri * | pri | ) | [static] |
Definition at line 14187 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().
14188 { 14189 int i, res, x; 14190 struct dahdi_params p; 14191 struct dahdi_bufferinfo bi; 14192 struct dahdi_spaninfo si; 14193 14194 pri->pri.calls = &dahdi_pri_callbacks; 14195 14196 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) { 14197 if (!pri->dchannels[i]) 14198 break; 14199 pri->pri.fds[i] = open("/dev/dahdi/channel", O_RDWR); 14200 x = pri->dchannels[i]; 14201 if ((pri->pri.fds[i] < 0) || (ioctl(pri->pri.fds[i],DAHDI_SPECIFY,&x) == -1)) { 14202 ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno)); 14203 return -1; 14204 } 14205 memset(&p, 0, sizeof(p)); 14206 res = ioctl(pri->pri.fds[i], DAHDI_GET_PARAMS, &p); 14207 if (res) { 14208 dahdi_close_pri_fd(pri, i); 14209 ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno)); 14210 return -1; 14211 } 14212 if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC)) { 14213 dahdi_close_pri_fd(pri, i); 14214 ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.\n", x); 14215 return -1; 14216 } 14217 memset(&si, 0, sizeof(si)); 14218 res = ioctl(pri->pri.fds[i], DAHDI_SPANSTAT, &si); 14219 if (res) { 14220 dahdi_close_pri_fd(pri, i); 14221 ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno)); 14222 } 14223 if (!si.alarms) { 14224 pri_event_noalarm(&pri->pri, i, 1); 14225 } else { 14226 pri_event_alarm(&pri->pri, i, 1); 14227 } 14228 memset(&bi, 0, sizeof(bi)); 14229 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; 14230 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; 14231 bi.numbufs = 32; 14232 bi.bufsize = 1024; 14233 if (ioctl(pri->pri.fds[i], DAHDI_SET_BUFINFO, &bi)) { 14234 ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d: %s\n", x, strerror(errno)); 14235 dahdi_close_pri_fd(pri, i); 14236 return -1; 14237 } 14238 pri->pri.dchan_logical_span[i] = pris[p.spanno - 1].prilogicalspan; 14239 } 14240 return 0; 14241 }
static int pri_create_spanmap | ( | int | span, | |
int | trunkgroup, | |||
int | logicalspan | |||
) | [static] |
Definition at line 12099 of file chan_dahdi.c.
References ast_log(), dahdi_pri::mastertrunkgroup, dahdi_pri::prilogicalspan, and pris.
Referenced by setup_dahdi_int().
12100 { 12101 if (pris[span].mastertrunkgroup) { 12102 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); 12103 return -1; 12104 } 12105 pris[span].mastertrunkgroup = trunkgroup; 12106 pris[span].prilogicalspan = logicalspan; 12107 return 0; 12108 }
static int pri_create_trunkgroup | ( | int | trunkgroup, | |
int * | channels | |||
) | [static] |
Definition at line 12036 of file chan_dahdi.c.
References ast_log(), NUM_SPANS, and pris.
Referenced by setup_dahdi_int().
12037 { 12038 struct dahdi_spaninfo si; 12039 struct dahdi_params p; 12040 int fd; 12041 int span; 12042 int ospan=0; 12043 int x,y; 12044 for (x = 0; x < NUM_SPANS; x++) { 12045 if (pris[x].pri.trunkgroup == trunkgroup) { 12046 ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]); 12047 return -1; 12048 } 12049 } 12050 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 12051 if (!channels[y]) 12052 break; 12053 memset(&si, 0, sizeof(si)); 12054 memset(&p, 0, sizeof(p)); 12055 fd = open("/dev/dahdi/channel", O_RDWR); 12056 if (fd < 0) { 12057 ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno)); 12058 return -1; 12059 } 12060 x = channels[y]; 12061 if (ioctl(fd, DAHDI_SPECIFY, &x)) { 12062 ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno)); 12063 close(fd); 12064 return -1; 12065 } 12066 if (ioctl(fd, DAHDI_GET_PARAMS, &p)) { 12067 ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno)); 12068 return -1; 12069 } 12070 if (ioctl(fd, DAHDI_SPANSTAT, &si)) { 12071 ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d): %s\n", channels[y], p.spanno, strerror(errno)); 12072 close(fd); 12073 return -1; 12074 } 12075 span = p.spanno - 1; 12076 if (pris[span].pri.trunkgroup) { 12077 ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].pri.trunkgroup); 12078 close(fd); 12079 return -1; 12080 } 12081 if (pris[span].pri.pvts[0]) { 12082 ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1); 12083 close(fd); 12084 return -1; 12085 } 12086 if (!y) { 12087 pris[span].pri.trunkgroup = trunkgroup; 12088 ospan = span; 12089 } 12090 pris[ospan].dchannels[y] = channels[y]; 12091 pris[span].pri.span = span + 1; 12092 close(fd); 12093 } 12094 return 0; 12095 }
static int pri_resolve_span | ( | int * | span, | |
int | channel, | |||
int | offset, | |||
struct dahdi_spaninfo * | si | |||
) | [static] |
Definition at line 11990 of file chan_dahdi.c.
References ast_log(), dahdi_pri::mastertrunkgroup, NUM_SPANS, dahdi_pvt::pri, pris, and sig_pri_span::trunkgroup.
11991 { 11992 int x; 11993 int trunkgroup; 11994 /* Get appropriate trunk group if there is one */ 11995 trunkgroup = pris[*span].mastertrunkgroup; 11996 if (trunkgroup) { 11997 /* Select a specific trunk group */ 11998 for (x = 0; x < NUM_SPANS; x++) { 11999 if (pris[x].pri.trunkgroup == trunkgroup) { 12000 *span = x; 12001 return 0; 12002 } 12003 } 12004 ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup); 12005 *span = -1; 12006 } else { 12007 if (pris[*span].pri.trunkgroup) { 12008 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); 12009 *span = -1; 12010 } else if (pris[*span].mastertrunkgroup) { 12011 ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup); 12012 *span = -1; 12013 } else { 12014 if (si->totalchans == 31) { 12015 /* E1 */ 12016 pris[*span].dchannels[0] = 16 + offset; 12017 } else if (si->totalchans == 24) { 12018 /* T1 or J1 */ 12019 pris[*span].dchannels[0] = 24 + offset; 12020 } else if (si->totalchans == 3) { 12021 /* BRI */ 12022 pris[*span].dchannels[0] = 3 + offset; 12023 } else { 12024 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); 12025 *span = -1; 12026 return 0; 12027 } 12028 pris[*span].pri.span = *span + 1; 12029 } 12030 } 12031 return 0; 12032 }
static int process_dahdi | ( | struct dahdi_chan_conf * | confp, | |
const char * | cat, | |||
struct ast_variable * | v, | |||
int | reload, | |||
int | options | |||
) | [static] |
Definition at line 16959 of file chan_dahdi.c.
References ast_jb_read_conf(), ast_log(), build_channels(), global_jbconf, ast_variable::lineno, ast_variable::name, ast_variable::next, PROC_DAHDI_OPT_NOCHAN, and ast_variable::value.
Referenced by setup_dahdi_int().
16960 { 16961 struct dahdi_pvt *tmp; 16962 int y; 16963 int found_pseudo = 0; 16964 struct ast_variable *dahdichan = NULL; 16965 16966 for (; v; v = v->next) { 16967 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 16968 continue; 16969 16970 /* Create the interface list */ 16971 if (!strcasecmp(v->name, "channel") || !strcasecmp(v->name, "channels")) { 16972 if (options & PROC_DAHDI_OPT_NOCHAN) { 16973 ast_log(LOG_WARNING, "Channel '%s' ignored.\n", v->value); 16974 continue; 16975 } 16976 if (build_channels(confp, v->value, reload, v->lineno, &found_pseudo)) { 16977 if (confp->ignore_failed_channels) { 16978 ast_log(LOG_WARNING, "Channel '%s' failure ignored: ignore_failed_channels.\n", v->value); 16979 continue; 16980 } else { 16981 return -1; 16982 } 16983 } 16984 ast_log(LOG_DEBUG, "Channel '%s' configured.\n", v->value); 16985 } else if (!strcasecmp(v->name, "ignore_failed_channels")) { 16986 confp->ignore_failed_channels = ast_true(v->value); 16987 } else if (!strcasecmp(v->name, "buffers")) { 16988 if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) { 16989 ast_log(LOG_WARNING, "Using default buffer policy.\n"); 16990 confp->chan.buf_no = numbufs; 16991 confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE; 16992 } 16993 } else if (!strcasecmp(v->name, "faxbuffers")) { 16994 if (!parse_buffers_policy(v->value, &confp->chan.faxbuf_no, &confp->chan.faxbuf_policy)) { 16995 confp->chan.usefaxbuffers = 1; 16996 } 16997 } else if (!strcasecmp(v->name, "dahdichan")) { 16998 /* Only process the last dahdichan value. */ 16999 dahdichan = v; 17000 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 17001 usedistinctiveringdetection = ast_true(v->value); 17002 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) { 17003 distinctiveringaftercid = ast_true(v->value); 17004 } else if (!strcasecmp(v->name, "dring1context")) { 17005 ast_copy_string(confp->chan.drings.ringContext[0].contextData,v->value,sizeof(confp->chan.drings.ringContext[0].contextData)); 17006 } else if (!strcasecmp(v->name, "dring2context")) { 17007 ast_copy_string(confp->chan.drings.ringContext[1].contextData,v->value,sizeof(confp->chan.drings.ringContext[1].contextData)); 17008 } else if (!strcasecmp(v->name, "dring3context")) { 17009 ast_copy_string(confp->chan.drings.ringContext[2].contextData,v->value,sizeof(confp->chan.drings.ringContext[2].contextData)); 17010 } else if (!strcasecmp(v->name, "dring1range")) { 17011 confp->chan.drings.ringnum[0].range = atoi(v->value); 17012 } else if (!strcasecmp(v->name, "dring2range")) { 17013 confp->chan.drings.ringnum[1].range = atoi(v->value); 17014 } else if (!strcasecmp(v->name, "dring3range")) { 17015 confp->chan.drings.ringnum[2].range = atoi(v->value); 17016 } else if (!strcasecmp(v->name, "dring1")) { 17017 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]); 17018 } else if (!strcasecmp(v->name, "dring2")) { 17019 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]); 17020 } else if (!strcasecmp(v->name, "dring3")) { 17021 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]); 17022 } else if (!strcasecmp(v->name, "usecallerid")) { 17023 confp->chan.use_callerid = ast_true(v->value); 17024 } else if (!strcasecmp(v->name, "cidsignalling")) { 17025 if (!strcasecmp(v->value, "bell")) 17026 confp->chan.cid_signalling = CID_SIG_BELL; 17027 else if (!strcasecmp(v->value, "v23")) 17028 confp->chan.cid_signalling = CID_SIG_V23; 17029 else if (!strcasecmp(v->value, "dtmf")) 17030 confp->chan.cid_signalling = CID_SIG_DTMF; 17031 else if (!strcasecmp(v->value, "smdi")) 17032 confp->chan.cid_signalling = CID_SIG_SMDI; 17033 else if (!strcasecmp(v->value, "v23_jp")) 17034 confp->chan.cid_signalling = CID_SIG_V23_JP; 17035 else if (ast_true(v->value)) 17036 confp->chan.cid_signalling = CID_SIG_BELL; 17037 } else if (!strcasecmp(v->name, "cidstart")) { 17038 if (!strcasecmp(v->value, "ring")) 17039 confp->chan.cid_start = CID_START_RING; 17040 else if (!strcasecmp(v->value, "polarity_in")) 17041 confp->chan.cid_start = CID_START_POLARITY_IN; 17042 else if (!strcasecmp(v->value, "polarity")) 17043 confp->chan.cid_start = CID_START_POLARITY; 17044 else if (!strcasecmp(v->value, "dtmf")) 17045 confp->chan.cid_start = CID_START_DTMF_NOALERT; 17046 else if (ast_true(v->value)) 17047 confp->chan.cid_start = CID_START_RING; 17048 } else if (!strcasecmp(v->name, "threewaycalling")) { 17049 confp->chan.threewaycalling = ast_true(v->value); 17050 } else if (!strcasecmp(v->name, "cancallforward")) { 17051 confp->chan.cancallforward = ast_true(v->value); 17052 } else if (!strcasecmp(v->name, "relaxdtmf")) { 17053 if (ast_true(v->value)) 17054 confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 17055 else 17056 confp->chan.dtmfrelax = 0; 17057 } else if (!strcasecmp(v->name, "mailbox")) { 17058 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox)); 17059 } else if (!strcasecmp(v->name, "hasvoicemail")) { 17060 if (ast_true(v->value) && ast_strlen_zero(confp->chan.mailbox)) { 17061 ast_copy_string(confp->chan.mailbox, cat, sizeof(confp->chan.mailbox)); 17062 } 17063 } else if (!strcasecmp(v->name, "adsi")) { 17064 confp->chan.adsi = ast_true(v->value); 17065 } else if (!strcasecmp(v->name, "usesmdi")) { 17066 confp->chan.use_smdi = ast_true(v->value); 17067 } else if (!strcasecmp(v->name, "smdiport")) { 17068 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port)); 17069 } else if (!strcasecmp(v->name, "transfer")) { 17070 confp->chan.transfer = ast_true(v->value); 17071 } else if (!strcasecmp(v->name, "canpark")) { 17072 confp->chan.canpark = ast_true(v->value); 17073 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 17074 confp->chan.echocanbridged = ast_true(v->value); 17075 } else if (!strcasecmp(v->name, "busydetect")) { 17076 confp->chan.busydetect = ast_true(v->value); 17077 } else if (!strcasecmp(v->name, "busycount")) { 17078 confp->chan.busycount = atoi(v->value); 17079 } else if (!strcasecmp(v->name, "silencethreshold")) { 17080 confp->chan.silencethreshold = atoi(v->value); 17081 } else if (!strcasecmp(v->name, "busycompare")) { 17082 confp->chan.busycompare = ast_true(v->value); 17083 } else if (!strcasecmp(v->name, "busypattern")) { 17084 if (sscanf(v->value, "%30d,%30d", &confp->chan.busytonelength, &confp->chan.busyquietlength) != 2) { 17085 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength at line %d.\n", v->lineno); 17086 } 17087 int count = sscanf(v->value, "%d,%d", &confp->chan.busytonelength, &confp->chan.busyquietlength); 17088 if (count == 1) 17089 confp->chan.busyquietlength = 0; 17090 else if (count < 1) 17091 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength[,quietlength] at line %d.\n", v->lineno); 17092 } else if (!strcasecmp(v->name, "busyfuzziness")) { 17093 confp->chan.busyfuzziness = atoi(v->value); 17094 } else if (!strcasecmp(v->name, "callprogress")) { 17095 confp->chan.callprogress &= ~CALLPROGRESS_PROGRESS; 17096 if (ast_true(v->value)) 17097 confp->chan.callprogress |= CALLPROGRESS_PROGRESS; 17098 } else if (!strcasecmp(v->name, "waitfordialtone")) { 17099 confp->chan.waitfordialtone = atoi(v->value); 17100 } else if (!strcasecmp(v->name, "faxdetect")) { 17101 confp->chan.callprogress &= ~CALLPROGRESS_FAX; 17102 if (!strcasecmp(v->value, "incoming")) { 17103 confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING; 17104 } else if (!strcasecmp(v->value, "outgoing")) { 17105 confp->chan.callprogress |= CALLPROGRESS_FAX_OUTGOING; 17106 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 17107 confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING; 17108 } else if (!strcasecmp(v->name, "echocancel")) { 17109 process_echocancel(confp, v->value, v->lineno); 17110 } else if (!strcasecmp(v->name, "echotraining")) { 17111 if (sscanf(v->value, "%30d", &y) == 1) { 17112 if ((y < 10) || (y > 4000)) { 17113 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d.\n", v->lineno); 17114 } else { 17115 confp->chan.echotraining = y; 17116 } 17117 } else if (ast_true(v->value)) { 17118 confp->chan.echotraining = 400; 17119 } else 17120 confp->chan.echotraining = 0; 17121 } else if (!strcasecmp(v->name, "hidecallerid")) { 17122 confp->chan.hidecallerid = ast_true(v->value); 17123 } else if (!strcasecmp(v->name, "hidecalleridname")) { 17124 confp->chan.hidecalleridname = ast_true(v->value); 17125 } else if (!strcasecmp(v->name, "pulsedial")) { 17126 confp->chan.pulse = ast_true(v->value); 17127 } else if (!strcasecmp(v->name, "callreturn")) { 17128 confp->chan.callreturn = ast_true(v->value); 17129 } else if (!strcasecmp(v->name, "callwaiting")) { 17130 confp->chan.callwaiting = ast_true(v->value); 17131 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 17132 confp->chan.callwaitingcallerid = ast_true(v->value); 17133 } else if (!strcasecmp(v->name, "context")) { 17134 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context)); 17135 } else if (!strcasecmp(v->name, "language")) { 17136 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language)); 17137 } else if (!strcasecmp(v->name, "progzone")) { 17138 ast_copy_string(progzone, v->value, sizeof(progzone)); 17139 } else if (!strcasecmp(v->name, "mohinterpret") 17140 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) { 17141 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret)); 17142 } else if (!strcasecmp(v->name, "mohsuggest")) { 17143 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest)); 17144 } else if (!strcasecmp(v->name, "parkinglot")) { 17145 ast_copy_string(confp->chan.parkinglot, v->value, sizeof(confp->chan.parkinglot)); 17146 } else if (!strcasecmp(v->name, "stripmsd")) { 17147 ast_log(LOG_NOTICE, "Configuration option \"%s\" has been deprecated. Please use dialplan instead\n", v->name); 17148 confp->chan.stripmsd = atoi(v->value); 17149 } else if (!strcasecmp(v->name, "jitterbuffers")) { 17150 numbufs = atoi(v->value); 17151 } else if (!strcasecmp(v->name, "group")) { 17152 confp->chan.group = ast_get_group(v->value); 17153 } else if (!strcasecmp(v->name, "callgroup")) { 17154 if (!strcasecmp(v->value, "none")) 17155 confp->chan.callgroup = 0; 17156 else 17157 confp->chan.callgroup = ast_get_group(v->value); 17158 } else if (!strcasecmp(v->name, "pickupgroup")) { 17159 if (!strcasecmp(v->value, "none")) 17160 confp->chan.pickupgroup = 0; 17161 else 17162 confp->chan.pickupgroup = ast_get_group(v->value); 17163 } else if (!strcasecmp(v->name, "setvar")) { 17164 char *varname = ast_strdupa(v->value), *varval = NULL; 17165 struct ast_variable *tmpvar; 17166 if (varname && (varval = strchr(varname, '='))) { 17167 *varval++ = '\0'; 17168 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 17169 tmpvar->next = confp->chan.vars; 17170 confp->chan.vars = tmpvar; 17171 } 17172 } 17173 } else if (!strcasecmp(v->name, "immediate")) { 17174 confp->chan.immediate = ast_true(v->value); 17175 } else if (!strcasecmp(v->name, "transfertobusy")) { 17176 confp->chan.transfertobusy = ast_true(v->value); 17177 } else if (!strcasecmp(v->name, "mwimonitor")) { 17178 confp->chan.mwimonitor_neon = 0; 17179 confp->chan.mwimonitor_fsk = 0; 17180 confp->chan.mwimonitor_rpas = 0; 17181 if (strcasestr(v->value, "fsk")) { 17182 confp->chan.mwimonitor_fsk = 1; 17183 } 17184 if (strcasestr(v->value, "rpas")) { 17185 confp->chan.mwimonitor_rpas = 1; 17186 } 17187 if (strcasestr(v->value, "neon")) { 17188 confp->chan.mwimonitor_neon = 1; 17189 } 17190 /* If set to true or yes, assume that simple fsk is desired */ 17191 if (ast_true(v->value)) { 17192 confp->chan.mwimonitor_fsk = 1; 17193 } 17194 } else if (!strcasecmp(v->name, "cid_rxgain")) { 17195 if (sscanf(v->value, "%30f", &confp->chan.cid_rxgain) != 1) { 17196 ast_log(LOG_WARNING, "Invalid cid_rxgain: %s at line %d.\n", v->value, v->lineno); 17197 } 17198 } else if (!strcasecmp(v->name, "rxgain")) { 17199 if (sscanf(v->value, "%30f", &confp->chan.rxgain) != 1) { 17200 ast_log(LOG_WARNING, "Invalid rxgain: %s at line %d.\n", v->value, v->lineno); 17201 } 17202 } else if (!strcasecmp(v->name, "txgain")) { 17203 if (sscanf(v->value, "%30f", &confp->chan.txgain) != 1) { 17204 ast_log(LOG_WARNING, "Invalid txgain: %s at line %d.\n", v->value, v->lineno); 17205 } 17206 } else if (!strcasecmp(v->name, "txdrc")) { 17207 if (sscanf(v->value, "%f", &confp->chan.txdrc) != 1) { 17208 ast_log(LOG_WARNING, "Invalid txdrc: %s\n", v->value); 17209 } 17210 } else if (!strcasecmp(v->name, "rxdrc")) { 17211 if (sscanf(v->value, "%f", &confp->chan.rxdrc) != 1) { 17212 ast_log(LOG_WARNING, "Invalid rxdrc: %s\n", v->value); 17213 } 17214 } else if (!strcasecmp(v->name, "tonezone")) { 17215 if (sscanf(v->value, "%30d", &confp->chan.tonezone) != 1) { 17216 ast_log(LOG_WARNING, "Invalid tonezone: %s at line %d.\n", v->value, v->lineno); 17217 } 17218 } else if (!strcasecmp(v->name, "callerid")) { 17219 if (!strcasecmp(v->value, "asreceived")) { 17220 confp->chan.cid_num[0] = '\0'; 17221 confp->chan.cid_name[0] = '\0'; 17222 } else { 17223 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num)); 17224 } 17225 } else if (!strcasecmp(v->name, "fullname")) { 17226 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name)); 17227 } else if (!strcasecmp(v->name, "cid_number")) { 17228 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num)); 17229 } else if (!strcasecmp(v->name, "cid_tag")) { 17230 ast_copy_string(confp->chan.cid_tag, v->value, sizeof(confp->chan.cid_tag)); 17231 } else if (!strcasecmp(v->name, "useincomingcalleridondahditransfer")) { 17232 confp->chan.dahditrcallerid = ast_true(v->value); 17233 } else if (!strcasecmp(v->name, "restrictcid")) { 17234 confp->chan.restrictcid = ast_true(v->value); 17235 } else if (!strcasecmp(v->name, "usecallingpres")) { 17236 confp->chan.use_callingpres = ast_true(v->value); 17237 } else if (!strcasecmp(v->name, "accountcode")) { 17238 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode)); 17239 } else if (!strcasecmp(v->name, "amaflags")) { 17240 y = ast_cdr_amaflags2int(v->value); 17241 if (y < 0) 17242 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d.\n", v->value, v->lineno); 17243 else 17244 confp->chan.amaflags = y; 17245 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 17246 confp->chan.polarityonanswerdelay = atoi(v->value); 17247 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 17248 confp->chan.answeronpolarityswitch = ast_true(v->value); 17249 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 17250 confp->chan.hanguponpolarityswitch = ast_true(v->value); 17251 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 17252 confp->chan.sendcalleridafter = atoi(v->value); 17253 } else if (!strcasecmp(v->name, "mwimonitornotify")) { 17254 ast_copy_string(mwimonitornotify, v->value, sizeof(mwimonitornotify)); 17255 } else if (ast_cc_is_config_param(v->name)) { 17256 ast_cc_set_param(confp->chan.cc_params, v->name, v->value); 17257 } else if (!strcasecmp(v->name, "mwisendtype")) { 17258 #ifndef HAVE_DAHDI_LINEREVERSE_VMWI /* backward compatibility for older dahdi VMWI implementation */ 17259 if (!strcasecmp(v->value, "rpas")) { /* Ring Pulse Alert Signal */ 17260 mwisend_rpas = 1; 17261 } else { 17262 mwisend_rpas = 0; 17263 } 17264 #else 17265 /* Default is fsk, to turn it off you must specify nofsk */ 17266 memset(&confp->chan.mwisend_setting, 0, sizeof(confp->chan.mwisend_setting)); 17267 if (strcasestr(v->value, "nofsk")) { /* NoFSK */ 17268 confp->chan.mwisend_fsk = 0; 17269 } else { /* Default FSK */ 17270 confp->chan.mwisend_fsk = 1; 17271 } 17272 if (strcasestr(v->value, "rpas")) { /* Ring Pulse Alert Signal, normally followed by FSK */ 17273 confp->chan.mwisend_rpas = 1; 17274 } else { 17275 confp->chan.mwisend_rpas = 0; 17276 } 17277 if (strcasestr(v->value, "lrev")) { /* Line Reversal */ 17278 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV; 17279 } 17280 if (strcasestr(v->value, "hvdc")) { /* HV 90VDC */ 17281 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC; 17282 } 17283 if ( (strcasestr(v->value, "neon")) || (strcasestr(v->value, "hvac")) ){ /* 90V DC pulses */ 17284 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC; 17285 } 17286 #endif 17287 } else if (reload != 1) { 17288 if (!strcasecmp(v->name, "signalling") || !strcasecmp(v->name, "signaling")) { 17289 int orig_radio = confp->chan.radio; 17290 int orig_outsigmod = confp->chan.outsigmod; 17291 int orig_auto = confp->is_sig_auto; 17292 17293 confp->chan.radio = 0; 17294 confp->chan.outsigmod = -1; 17295 confp->is_sig_auto = 0; 17296 if (!strcasecmp(v->value, "em")) { 17297 confp->chan.sig = SIG_EM; 17298 } else if (!strcasecmp(v->value, "em_e1")) { 17299 confp->chan.sig = SIG_EM_E1; 17300 } else if (!strcasecmp(v->value, "em_w")) { 17301 confp->chan.sig = SIG_EMWINK; 17302 } else if (!strcasecmp(v->value, "fxs_ls")) { 17303 confp->chan.sig = SIG_FXSLS; 17304 } else if (!strcasecmp(v->value, "fxs_gs")) { 17305 confp->chan.sig = SIG_FXSGS; 17306 } else if (!strcasecmp(v->value, "fxs_ks")) { 17307 confp->chan.sig = SIG_FXSKS; 17308 } else if (!strcasecmp(v->value, "fxo_ls")) { 17309 confp->chan.sig = SIG_FXOLS; 17310 } else if (!strcasecmp(v->value, "fxo_gs")) { 17311 confp->chan.sig = SIG_FXOGS; 17312 } else if (!strcasecmp(v->value, "fxo_ks")) { 17313 confp->chan.sig = SIG_FXOKS; 17314 } else if (!strcasecmp(v->value, "fxs_rx")) { 17315 confp->chan.sig = SIG_FXSKS; 17316 confp->chan.radio = 1; 17317 } else if (!strcasecmp(v->value, "fxo_rx")) { 17318 confp->chan.sig = SIG_FXOLS; 17319 confp->chan.radio = 1; 17320 } else if (!strcasecmp(v->value, "fxs_tx")) { 17321 confp->chan.sig = SIG_FXSLS; 17322 confp->chan.radio = 1; 17323 } else if (!strcasecmp(v->value, "fxo_tx")) { 17324 confp->chan.sig = SIG_FXOGS; 17325 confp->chan.radio = 1; 17326 } else if (!strcasecmp(v->value, "em_rx")) { 17327 confp->chan.sig = SIG_EM; 17328 confp->chan.radio = 1; 17329 } else if (!strcasecmp(v->value, "em_tx")) { 17330 confp->chan.sig = SIG_EM; 17331 confp->chan.radio = 1; 17332 } else if (!strcasecmp(v->value, "em_rxtx")) { 17333 confp->chan.sig = SIG_EM; 17334 confp->chan.radio = 2; 17335 } else if (!strcasecmp(v->value, "em_txrx")) { 17336 confp->chan.sig = SIG_EM; 17337 confp->chan.radio = 2; 17338 } else if (!strcasecmp(v->value, "sf")) { 17339 confp->chan.sig = SIG_SF; 17340 } else if (!strcasecmp(v->value, "sf_w")) { 17341 confp->chan.sig = SIG_SFWINK; 17342 } else if (!strcasecmp(v->value, "sf_featd")) { 17343 confp->chan.sig = SIG_FEATD; 17344 } else if (!strcasecmp(v->value, "sf_featdmf")) { 17345 confp->chan.sig = SIG_FEATDMF; 17346 } else if (!strcasecmp(v->value, "sf_featb")) { 17347 confp->chan.sig = SIG_SF_FEATB; 17348 } else if (!strcasecmp(v->value, "sf")) { 17349 confp->chan.sig = SIG_SF; 17350 } else if (!strcasecmp(v->value, "sf_rx")) { 17351 confp->chan.sig = SIG_SF; 17352 confp->chan.radio = 1; 17353 } else if (!strcasecmp(v->value, "sf_tx")) { 17354 confp->chan.sig = SIG_SF; 17355 confp->chan.radio = 1; 17356 } else if (!strcasecmp(v->value, "sf_rxtx")) { 17357 confp->chan.sig = SIG_SF; 17358 confp->chan.radio = 2; 17359 } else if (!strcasecmp(v->value, "sf_txrx")) { 17360 confp->chan.sig = SIG_SF; 17361 confp->chan.radio = 2; 17362 } else if (!strcasecmp(v->value, "featd")) { 17363 confp->chan.sig = SIG_FEATD; 17364 } else if (!strcasecmp(v->value, "featdmf")) { 17365 confp->chan.sig = SIG_FEATDMF; 17366 } else if (!strcasecmp(v->value, "featdmf_ta")) { 17367 confp->chan.sig = SIG_FEATDMF_TA; 17368 } else if (!strcasecmp(v->value, "e911")) { 17369 confp->chan.sig = SIG_E911; 17370 } else if (!strcasecmp(v->value, "fgccama")) { 17371 confp->chan.sig = SIG_FGC_CAMA; 17372 } else if (!strcasecmp(v->value, "fgccamamf")) { 17373 confp->chan.sig = SIG_FGC_CAMAMF; 17374 } else if (!strcasecmp(v->value, "featb")) { 17375 confp->chan.sig = SIG_FEATB; 17376 #ifdef HAVE_PRI 17377 } else if (!strcasecmp(v->value, "pri_net")) { 17378 confp->chan.sig = SIG_PRI; 17379 confp->pri.pri.nodetype = PRI_NETWORK; 17380 } else if (!strcasecmp(v->value, "pri_cpe")) { 17381 confp->chan.sig = SIG_PRI; 17382 confp->pri.pri.nodetype = PRI_CPE; 17383 } else if (!strcasecmp(v->value, "bri_cpe")) { 17384 confp->chan.sig = SIG_BRI; 17385 confp->pri.pri.nodetype = PRI_CPE; 17386 } else if (!strcasecmp(v->value, "bri_net")) { 17387 confp->chan.sig = SIG_BRI; 17388 confp->pri.pri.nodetype = PRI_NETWORK; 17389 } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) { 17390 confp->chan.sig = SIG_BRI_PTMP; 17391 confp->pri.pri.nodetype = PRI_CPE; 17392 } else if (!strcasecmp(v->value, "bri_net_ptmp")) { 17393 #if defined(HAVE_PRI_CALL_HOLD) 17394 confp->chan.sig = SIG_BRI_PTMP; 17395 confp->pri.pri.nodetype = PRI_NETWORK; 17396 #else 17397 ast_log(LOG_WARNING, "How cool would it be if someone implemented this mode! For now, sucks for you. (line %d)\n", v->lineno); 17398 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 17399 #endif 17400 #if defined(HAVE_SS7) 17401 } else if (!strcasecmp(v->value, "ss7")) { 17402 confp->chan.sig = SIG_SS7; 17403 #endif /* defined(HAVE_SS7) */ 17404 #ifdef HAVE_OPENR2 17405 } else if (!strcasecmp(v->value, "mfcr2")) { 17406 confp->chan.sig = SIG_MFCR2; 17407 #endif 17408 } else if (!strcasecmp(v->value, "auto")) { 17409 confp->is_sig_auto = 1; 17410 } else { 17411 confp->chan.outsigmod = orig_outsigmod; 17412 confp->chan.radio = orig_radio; 17413 confp->is_sig_auto = orig_auto; 17414 ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno); 17415 } 17416 } else if (!strcasecmp(v->name, "outsignalling") || !strcasecmp(v->name, "outsignaling")) { 17417 if (!strcasecmp(v->value, "em")) { 17418 confp->chan.outsigmod = SIG_EM; 17419 } else if (!strcasecmp(v->value, "em_e1")) { 17420 confp->chan.outsigmod = SIG_EM_E1; 17421 } else if (!strcasecmp(v->value, "em_w")) { 17422 confp->chan.outsigmod = SIG_EMWINK; 17423 } else if (!strcasecmp(v->value, "sf")) { 17424 confp->chan.outsigmod = SIG_SF; 17425 } else if (!strcasecmp(v->value, "sf_w")) { 17426 confp->chan.outsigmod = SIG_SFWINK; 17427 } else if (!strcasecmp(v->value, "sf_featd")) { 17428 confp->chan.outsigmod = SIG_FEATD; 17429 } else if (!strcasecmp(v->value, "sf_featdmf")) { 17430 confp->chan.outsigmod = SIG_FEATDMF; 17431 } else if (!strcasecmp(v->value, "sf_featb")) { 17432 confp->chan.outsigmod = SIG_SF_FEATB; 17433 } else if (!strcasecmp(v->value, "sf")) { 17434 confp->chan.outsigmod = SIG_SF; 17435 } else if (!strcasecmp(v->value, "featd")) { 17436 confp->chan.outsigmod = SIG_FEATD; 17437 } else if (!strcasecmp(v->value, "featdmf")) { 17438 confp->chan.outsigmod = SIG_FEATDMF; 17439 } else if (!strcasecmp(v->value, "featdmf_ta")) { 17440 confp->chan.outsigmod = SIG_FEATDMF_TA; 17441 } else if (!strcasecmp(v->value, "e911")) { 17442 confp->chan.outsigmod = SIG_E911; 17443 } else if (!strcasecmp(v->value, "fgccama")) { 17444 confp->chan.outsigmod = SIG_FGC_CAMA; 17445 } else if (!strcasecmp(v->value, "fgccamamf")) { 17446 confp->chan.outsigmod = SIG_FGC_CAMAMF; 17447 } else if (!strcasecmp(v->value, "featb")) { 17448 confp->chan.outsigmod = SIG_FEATB; 17449 } else { 17450 ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno); 17451 } 17452 #ifdef HAVE_PRI 17453 } else if (!strcasecmp(v->name, "pridialplan")) { 17454 if (!strcasecmp(v->value, "national")) { 17455 confp->pri.pri.dialplan = PRI_NATIONAL_ISDN + 1; 17456 } else if (!strcasecmp(v->value, "unknown")) { 17457 confp->pri.pri.dialplan = PRI_UNKNOWN + 1; 17458 } else if (!strcasecmp(v->value, "private")) { 17459 confp->pri.pri.dialplan = PRI_PRIVATE + 1; 17460 } else if (!strcasecmp(v->value, "international")) { 17461 confp->pri.pri.dialplan = PRI_INTERNATIONAL_ISDN + 1; 17462 } else if (!strcasecmp(v->value, "local")) { 17463 confp->pri.pri.dialplan = PRI_LOCAL_ISDN + 1; 17464 } else if (!strcasecmp(v->value, "dynamic")) { 17465 confp->pri.pri.dialplan = -1; 17466 } else if (!strcasecmp(v->value, "redundant")) { 17467 confp->pri.pri.dialplan = -2; 17468 } else { 17469 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 17470 } 17471 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 17472 if (!strcasecmp(v->value, "national")) { 17473 confp->pri.pri.localdialplan = PRI_NATIONAL_ISDN + 1; 17474 } else if (!strcasecmp(v->value, "unknown")) { 17475 confp->pri.pri.localdialplan = PRI_UNKNOWN + 1; 17476 } else if (!strcasecmp(v->value, "private")) { 17477 confp->pri.pri.localdialplan = PRI_PRIVATE + 1; 17478 } else if (!strcasecmp(v->value, "international")) { 17479 confp->pri.pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1; 17480 } else if (!strcasecmp(v->value, "local")) { 17481 confp->pri.pri.localdialplan = PRI_LOCAL_ISDN + 1; 17482 } else if (!strcasecmp(v->value, "dynamic")) { 17483 confp->pri.pri.localdialplan = -1; 17484 } else if (!strcasecmp(v->value, "redundant")) { 17485 confp->pri.pri.localdialplan = -2; 17486 } else { 17487 ast_log(LOG_WARNING, "Unknown PRI localdialplan '%s' at line %d.\n", v->value, v->lineno); 17488 } 17489 } else if (!strcasecmp(v->name, "switchtype")) { 17490 if (!strcasecmp(v->value, "national")) 17491 confp->pri.pri.switchtype = PRI_SWITCH_NI2; 17492 else if (!strcasecmp(v->value, "ni1")) 17493 confp->pri.pri.switchtype = PRI_SWITCH_NI1; 17494 else if (!strcasecmp(v->value, "dms100")) 17495 confp->pri.pri.switchtype = PRI_SWITCH_DMS100; 17496 else if (!strcasecmp(v->value, "4ess")) 17497 confp->pri.pri.switchtype = PRI_SWITCH_ATT4ESS; 17498 else if (!strcasecmp(v->value, "5ess")) 17499 confp->pri.pri.switchtype = PRI_SWITCH_LUCENT5E; 17500 else if (!strcasecmp(v->value, "euroisdn")) 17501 confp->pri.pri.switchtype = PRI_SWITCH_EUROISDN_E1; 17502 else if (!strcasecmp(v->value, "qsig")) 17503 confp->pri.pri.switchtype = PRI_SWITCH_QSIG; 17504 else { 17505 ast_log(LOG_ERROR, "Unknown switchtype '%s' at line %d.\n", v->value, v->lineno); 17506 return -1; 17507 } 17508 } else if (!strcasecmp(v->name, "msn")) { 17509 ast_copy_string(confp->pri.pri.msn_list, v->value, 17510 sizeof(confp->pri.pri.msn_list)); 17511 } else if (!strcasecmp(v->name, "nsf")) { 17512 if (!strcasecmp(v->value, "sdn")) 17513 confp->pri.pri.nsf = PRI_NSF_SDN; 17514 else if (!strcasecmp(v->value, "megacom")) 17515 confp->pri.pri.nsf = PRI_NSF_MEGACOM; 17516 else if (!strcasecmp(v->value, "tollfreemegacom")) 17517 confp->pri.pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM; 17518 else if (!strcasecmp(v->value, "accunet")) 17519 confp->pri.pri.nsf = PRI_NSF_ACCUNET; 17520 else if (!strcasecmp(v->value, "none")) 17521 confp->pri.pri.nsf = PRI_NSF_NONE; 17522 else { 17523 ast_log(LOG_WARNING, "Unknown network-specific facility '%s' at line %d.\n", v->value, v->lineno); 17524 confp->pri.pri.nsf = PRI_NSF_NONE; 17525 } 17526 } else if (!strcasecmp(v->name, "priindication")) { 17527 if (!strcasecmp(v->value, "outofband")) 17528 confp->chan.priindication_oob = 1; 17529 else if (!strcasecmp(v->value, "inband")) 17530 confp->chan.priindication_oob = 0; 17531 else 17532 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d.\n", 17533 v->value, v->lineno); 17534 } else if (!strcasecmp(v->name, "priexclusive")) { 17535 confp->chan.priexclusive = ast_true(v->value); 17536 } else if (!strcasecmp(v->name, "internationalprefix")) { 17537 ast_copy_string(confp->pri.pri.internationalprefix, v->value, sizeof(confp->pri.pri.internationalprefix)); 17538 } else if (!strcasecmp(v->name, "nationalprefix")) { 17539 ast_copy_string(confp->pri.pri.nationalprefix, v->value, sizeof(confp->pri.pri.nationalprefix)); 17540 } else if (!strcasecmp(v->name, "localprefix")) { 17541 ast_copy_string(confp->pri.pri.localprefix, v->value, sizeof(confp->pri.pri.localprefix)); 17542 } else if (!strcasecmp(v->name, "privateprefix")) { 17543 ast_copy_string(confp->pri.pri.privateprefix, v->value, sizeof(confp->pri.pri.privateprefix)); 17544 } else if (!strcasecmp(v->name, "unknownprefix")) { 17545 ast_copy_string(confp->pri.pri.unknownprefix, v->value, sizeof(confp->pri.pri.unknownprefix)); 17546 } else if (!strcasecmp(v->name, "resetinterval")) { 17547 if (!strcasecmp(v->value, "never")) 17548 confp->pri.pri.resetinterval = -1; 17549 else if (atoi(v->value) >= 60) 17550 confp->pri.pri.resetinterval = atoi(v->value); 17551 else 17552 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n", 17553 v->value, v->lineno); 17554 } else if (!strcasecmp(v->name, "minunused")) { 17555 confp->pri.pri.minunused = atoi(v->value); 17556 } else if (!strcasecmp(v->name, "minidle")) { 17557 confp->pri.pri.minidle = atoi(v->value); 17558 } else if (!strcasecmp(v->name, "idleext")) { 17559 ast_copy_string(confp->pri.pri.idleext, v->value, sizeof(confp->pri.pri.idleext)); 17560 } else if (!strcasecmp(v->name, "idledial")) { 17561 ast_copy_string(confp->pri.pri.idledial, v->value, sizeof(confp->pri.pri.idledial)); 17562 } else if (!strcasecmp(v->name, "overlapdial")) { 17563 if (ast_true(v->value)) { 17564 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH; 17565 } else if (!strcasecmp(v->value, "incoming")) { 17566 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_INCOMING; 17567 } else if (!strcasecmp(v->value, "outgoing")) { 17568 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_OUTGOING; 17569 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) { 17570 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH; 17571 } else { 17572 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_NONE; 17573 } 17574 #ifdef HAVE_PRI_PROG_W_CAUSE 17575 } else if (!strcasecmp(v->name, "qsigchannelmapping")) { 17576 if (!strcasecmp(v->value, "logical")) { 17577 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_LOGICAL; 17578 } else if (!strcasecmp(v->value, "physical")) { 17579 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL; 17580 } else { 17581 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL; 17582 } 17583 #endif 17584 } else if (!strcasecmp(v->name, "discardremoteholdretrieval")) { 17585 confp->pri.pri.discardremoteholdretrieval = ast_true(v->value); 17586 #if defined(HAVE_PRI_SERVICE_MESSAGES) 17587 } else if (!strcasecmp(v->name, "service_message_support")) { 17588 /* assuming switchtype for this channel group has been configured already */ 17589 if ((confp->pri.pri.switchtype == PRI_SWITCH_ATT4ESS 17590 || confp->pri.pri.switchtype == PRI_SWITCH_LUCENT5E 17591 || confp->pri.pri.switchtype == PRI_SWITCH_NI2) && ast_true(v->value)) { 17592 confp->pri.pri.enable_service_message_support = 1; 17593 } else { 17594 confp->pri.pri.enable_service_message_support = 0; 17595 } 17596 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 17597 #ifdef HAVE_PRI_INBANDDISCONNECT 17598 } else if (!strcasecmp(v->name, "inbanddisconnect")) { 17599 confp->pri.pri.inbanddisconnect = ast_true(v->value); 17600 #endif 17601 } else if (!strcasecmp(v->name, "pritimer")) { 17602 #ifdef PRI_GETSET_TIMERS 17603 char tmp[20]; 17604 char *timerc; 17605 char *c; 17606 int timer; 17607 int timeridx; 17608 17609 ast_copy_string(tmp, v->value, sizeof(tmp)); 17610 c = tmp; 17611 timerc = strsep(&c, ","); 17612 if (!ast_strlen_zero(timerc) && !ast_strlen_zero(c)) { 17613 timeridx = pri_timer2idx(timerc); 17614 timer = atoi(c); 17615 if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) { 17616 ast_log(LOG_WARNING, 17617 "'%s' is not a valid ISDN timer at line %d.\n", timerc, 17618 v->lineno); 17619 } else if (!timer) { 17620 ast_log(LOG_WARNING, 17621 "'%s' is not a valid value for ISDN timer '%s' at line %d.\n", 17622 c, timerc, v->lineno); 17623 } else { 17624 confp->pri.pri.pritimers[timeridx] = timer; 17625 } 17626 } else { 17627 ast_log(LOG_WARNING, 17628 "'%s' is not a valid ISDN timer configuration string at line %d.\n", 17629 v->value, v->lineno); 17630 } 17631 #endif /* PRI_GETSET_TIMERS */ 17632 } else if (!strcasecmp(v->name, "facilityenable")) { 17633 confp->pri.pri.facilityenable = ast_true(v->value); 17634 #if defined(HAVE_PRI_AOC_EVENTS) 17635 } else if (!strcasecmp(v->name, "aoc_enable")) { 17636 confp->pri.pri.aoc_passthrough_flag = 0; 17637 if (strchr(v->value, 's') || strchr(v->value, 'S')) { 17638 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_S; 17639 } 17640 if (strchr(v->value, 'd') || strchr(v->value, 'D')) { 17641 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_D; 17642 } 17643 if (strchr(v->value, 'e') || strchr(v->value, 'E')) { 17644 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_E; 17645 } 17646 } else if (!strcasecmp(v->name, "aoce_delayhangup")) { 17647 confp->pri.pri.aoce_delayhangup = ast_true(v->value); 17648 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 17649 #if defined(HAVE_PRI_CALL_HOLD) 17650 } else if (!strcasecmp(v->name, "hold_disconnect_transfer")) { 17651 confp->pri.pri.hold_disconnect_transfer = ast_true(v->value); 17652 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 17653 #if defined(HAVE_PRI_CCSS) 17654 } else if (!strcasecmp(v->name, "cc_ptmp_recall_mode")) { 17655 if (!strcasecmp(v->value, "global")) { 17656 confp->pri.pri.cc_ptmp_recall_mode = 0;/* globalRecall */ 17657 } else if (!strcasecmp(v->value, "specific")) { 17658 confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */ 17659 } else { 17660 confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */ 17661 } 17662 } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_req")) { 17663 if (!strcasecmp(v->value, "release")) { 17664 confp->pri.pri.cc_qsig_signaling_link_req = 0;/* release */ 17665 } else if (!strcasecmp(v->value, "retain")) { 17666 confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */ 17667 } else if (!strcasecmp(v->value, "do_not_care")) { 17668 confp->pri.pri.cc_qsig_signaling_link_req = 2;/* do-not-care */ 17669 } else { 17670 confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */ 17671 } 17672 } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_rsp")) { 17673 if (!strcasecmp(v->value, "release")) { 17674 confp->pri.pri.cc_qsig_signaling_link_rsp = 0;/* release */ 17675 } else if (!strcasecmp(v->value, "retain")) { 17676 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */ 17677 } else { 17678 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */ 17679 } 17680 #endif /* defined(HAVE_PRI_CCSS) */ 17681 #if defined(HAVE_PRI_CALL_WAITING) 17682 } else if (!strcasecmp(v->name, "max_call_waiting_calls")) { 17683 confp->pri.pri.max_call_waiting_calls = atoi(v->value); 17684 if (confp->pri.pri.max_call_waiting_calls < 0) { 17685 /* Negative values are not allowed. */ 17686 confp->pri.pri.max_call_waiting_calls = 0; 17687 } 17688 } else if (!strcasecmp(v->name, "allow_call_waiting_calls")) { 17689 confp->pri.pri.allow_call_waiting_calls = ast_true(v->value); 17690 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 17691 #if defined(HAVE_PRI_MWI) 17692 } else if (!strcasecmp(v->name, "mwi_mailboxes")) { 17693 ast_copy_string(confp->pri.pri.mwi_mailboxes, v->value, 17694 sizeof(confp->pri.pri.mwi_mailboxes)); 17695 #endif /* defined(HAVE_PRI_MWI) */ 17696 } else if (!strcasecmp(v->name, "append_msn_to_cid_tag")) { 17697 confp->pri.pri.append_msn_to_user_tag = ast_true(v->value); 17698 } else if (!strcasecmp(v->name, "layer1_presence")) { 17699 if (!strcasecmp(v->value, "required")) { 17700 confp->pri.pri.layer1_ignored = 0; 17701 } else if (!strcasecmp(v->value, "ignore")) { 17702 confp->pri.pri.layer1_ignored = 1; 17703 } else { 17704 /* Default */ 17705 confp->pri.pri.layer1_ignored = 0; 17706 } 17707 #if defined(HAVE_PRI_L2_PERSISTENCE) 17708 } else if (!strcasecmp(v->name, "layer2_persistence")) { 17709 if (!strcasecmp(v->value, "keep_up")) { 17710 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_KEEP_UP; 17711 } else if (!strcasecmp(v->value, "leave_down")) { 17712 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_LEAVE_DOWN; 17713 } else { 17714 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_DEFAULT; 17715 } 17716 #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */ 17717 #endif /* HAVE_PRI */ 17718 #if defined(HAVE_SS7) 17719 } else if (!strcasecmp(v->name, "ss7type")) { 17720 if (!strcasecmp(v->value, "itu")) { 17721 cur_ss7type = SS7_ITU; 17722 } else if (!strcasecmp(v->value, "ansi")) { 17723 cur_ss7type = SS7_ANSI; 17724 } else 17725 ast_log(LOG_WARNING, "'%s' is an unknown ss7 switch type at line %d.!\n", v->value, v->lineno); 17726 } else if (!strcasecmp(v->name, "linkset")) { 17727 cur_linkset = atoi(v->value); 17728 } else if (!strcasecmp(v->name, "pointcode")) { 17729 cur_pointcode = parse_pointcode(v->value); 17730 } else if (!strcasecmp(v->name, "adjpointcode")) { 17731 cur_adjpointcode = parse_pointcode(v->value); 17732 } else if (!strcasecmp(v->name, "defaultdpc")) { 17733 cur_defaultdpc = parse_pointcode(v->value); 17734 } else if (!strcasecmp(v->name, "cicbeginswith")) { 17735 cur_cicbeginswith = atoi(v->value); 17736 } else if (!strcasecmp(v->name, "networkindicator")) { 17737 if (!strcasecmp(v->value, "national")) 17738 cur_networkindicator = SS7_NI_NAT; 17739 else if (!strcasecmp(v->value, "national_spare")) 17740 cur_networkindicator = SS7_NI_NAT_SPARE; 17741 else if (!strcasecmp(v->value, "international")) 17742 cur_networkindicator = SS7_NI_INT; 17743 else if (!strcasecmp(v->value, "international_spare")) 17744 cur_networkindicator = SS7_NI_INT_SPARE; 17745 else 17746 cur_networkindicator = -1; 17747 } else if (!strcasecmp(v->name, "ss7_internationalprefix")) { 17748 ast_copy_string(confp->ss7.ss7.internationalprefix, v->value, sizeof(confp->ss7.ss7.internationalprefix)); 17749 } else if (!strcasecmp(v->name, "ss7_nationalprefix")) { 17750 ast_copy_string(confp->ss7.ss7.nationalprefix, v->value, sizeof(confp->ss7.ss7.nationalprefix)); 17751 } else if (!strcasecmp(v->name, "ss7_subscriberprefix")) { 17752 ast_copy_string(confp->ss7.ss7.subscriberprefix, v->value, sizeof(confp->ss7.ss7.subscriberprefix)); 17753 } else if (!strcasecmp(v->name, "ss7_unknownprefix")) { 17754 ast_copy_string(confp->ss7.ss7.unknownprefix, v->value, sizeof(confp->ss7.ss7.unknownprefix)); 17755 } else if (!strcasecmp(v->name, "ss7_called_nai")) { 17756 if (!strcasecmp(v->value, "national")) { 17757 confp->ss7.ss7.called_nai = SS7_NAI_NATIONAL; 17758 } else if (!strcasecmp(v->value, "international")) { 17759 confp->ss7.ss7.called_nai = SS7_NAI_INTERNATIONAL; 17760 } else if (!strcasecmp(v->value, "subscriber")) { 17761 confp->ss7.ss7.called_nai = SS7_NAI_SUBSCRIBER; 17762 } else if (!strcasecmp(v->value, "unknown")) { 17763 confp->ss7.ss7.called_nai = SS7_NAI_UNKNOWN; 17764 } else if (!strcasecmp(v->value, "dynamic")) { 17765 confp->ss7.ss7.called_nai = SS7_NAI_DYNAMIC; 17766 } else { 17767 ast_log(LOG_WARNING, "Unknown SS7 called_nai '%s' at line %d.\n", v->value, v->lineno); 17768 } 17769 } else if (!strcasecmp(v->name, "ss7_calling_nai")) { 17770 if (!strcasecmp(v->value, "national")) { 17771 confp->ss7.ss7.calling_nai = SS7_NAI_NATIONAL; 17772 } else if (!strcasecmp(v->value, "international")) { 17773 confp->ss7.ss7.calling_nai = SS7_NAI_INTERNATIONAL; 17774 } else if (!strcasecmp(v->value, "subscriber")) { 17775 confp->ss7.ss7.calling_nai = SS7_NAI_SUBSCRIBER; 17776 } else if (!strcasecmp(v->value, "unknown")) { 17777 confp->ss7.ss7.calling_nai = SS7_NAI_UNKNOWN; 17778 } else if (!strcasecmp(v->value, "dynamic")) { 17779 confp->ss7.ss7.calling_nai = SS7_NAI_DYNAMIC; 17780 } else { 17781 ast_log(LOG_WARNING, "Unknown SS7 calling_nai '%s' at line %d.\n", v->value, v->lineno); 17782 } 17783 } else if (!strcasecmp(v->name, "sigchan")) { 17784 int sigchan, res; 17785 sigchan = atoi(v->value); 17786 res = linkset_addsigchan(sigchan); 17787 if (res < 0) 17788 return -1; 17789 17790 } else if (!strcasecmp(v->name, "ss7_explicitacm")) { 17791 struct dahdi_ss7 *link; 17792 link = ss7_resolve_linkset(cur_linkset); 17793 if (!link) { 17794 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1); 17795 return -1; 17796 } 17797 if (ast_true(v->value)) 17798 link->ss7.flags |= LINKSET_FLAG_EXPLICITACM; 17799 #endif /* defined(HAVE_SS7) */ 17800 #ifdef HAVE_OPENR2 17801 } else if (!strcasecmp(v->name, "mfcr2_advanced_protocol_file")) { 17802 ast_copy_string(confp->mfcr2.r2proto_file, v->value, sizeof(confp->mfcr2.r2proto_file)); 17803 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); 17804 } else if (!strcasecmp(v->name, "mfcr2_logdir")) { 17805 ast_copy_string(confp->mfcr2.logdir, v->value, sizeof(confp->mfcr2.logdir)); 17806 } else if (!strcasecmp(v->name, "mfcr2_variant")) { 17807 confp->mfcr2.variant = openr2_proto_get_variant(v->value); 17808 if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) { 17809 ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d, defaulting to ITU.\n", v->value, v->lineno); 17810 confp->mfcr2.variant = OR2_VAR_ITU; 17811 } 17812 } else if (!strcasecmp(v->name, "mfcr2_mfback_timeout")) { 17813 confp->mfcr2.mfback_timeout = atoi(v->value); 17814 if (!confp->mfcr2.mfback_timeout) { 17815 ast_log(LOG_WARNING, "MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n"); 17816 confp->mfcr2.mfback_timeout = -1; 17817 } else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) { 17818 ast_log(LOG_WARNING, "MF timeout less than 500ms is not recommended, you have been warned!\n"); 17819 } 17820 } else if (!strcasecmp(v->name, "mfcr2_metering_pulse_timeout")) { 17821 confp->mfcr2.metering_pulse_timeout = atoi(v->value); 17822 if (confp->mfcr2.metering_pulse_timeout > 500) { 17823 ast_log(LOG_WARNING, "Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n"); 17824 } 17825 } else if (!strcasecmp(v->name, "mfcr2_get_ani_first")) { 17826 confp->mfcr2.get_ani_first = ast_true(v->value) ? 1 : 0; 17827 } else if (!strcasecmp(v->name, "mfcr2_double_answer")) { 17828 confp->mfcr2.double_answer = ast_true(v->value) ? 1 : 0; 17829 } else if (!strcasecmp(v->name, "mfcr2_charge_calls")) { 17830 confp->mfcr2.charge_calls = ast_true(v->value) ? 1 : 0; 17831 } else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) { 17832 confp->mfcr2.accept_on_offer = ast_true(v->value) ? 1 : 0; 17833 } else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) { 17834 confp->mfcr2.allow_collect_calls = ast_true(v->value) ? 1 : 0; 17835 } else if (!strcasecmp(v->name, "mfcr2_forced_release")) { 17836 confp->mfcr2.forced_release = ast_true(v->value) ? 1 : 0; 17837 } else if (!strcasecmp(v->name, "mfcr2_immediate_accept")) { 17838 confp->mfcr2.immediate_accept = ast_true(v->value) ? 1 : 0; 17839 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 17840 } else if (!strcasecmp(v->name, "mfcr2_skip_category")) { 17841 confp->mfcr2.skip_category_request = ast_true(v->value) ? 1 : 0; 17842 #endif 17843 } else if (!strcasecmp(v->name, "mfcr2_call_files")) { 17844 confp->mfcr2.call_files = ast_true(v->value) ? 1 : 0; 17845 } else if (!strcasecmp(v->name, "mfcr2_max_ani")) { 17846 confp->mfcr2.max_ani = atoi(v->value); 17847 if (confp->mfcr2.max_ani >= AST_MAX_EXTENSION){ 17848 confp->mfcr2.max_ani = AST_MAX_EXTENSION - 1; 17849 } 17850 } else if (!strcasecmp(v->name, "mfcr2_max_dnis")) { 17851 confp->mfcr2.max_dnis = atoi(v->value); 17852 if (confp->mfcr2.max_dnis >= AST_MAX_EXTENSION){ 17853 confp->mfcr2.max_dnis = AST_MAX_EXTENSION - 1; 17854 } 17855 } else if (!strcasecmp(v->name, "mfcr2_category")) { 17856 confp->mfcr2.category = openr2_proto_get_category(v->value); 17857 if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) { 17858 confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER; 17859 ast_log(LOG_WARNING, "Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n", 17860 v->value, v->lineno); 17861 } 17862 } else if (!strcasecmp(v->name, "mfcr2_logging")) { 17863 openr2_log_level_t tmplevel; 17864 char *clevel; 17865 char *logval = ast_strdupa(v->value); 17866 while (logval) { 17867 clevel = strsep(&logval,","); 17868 if (-1 == (tmplevel = openr2_log_get_level(clevel))) { 17869 ast_log(LOG_WARNING, "Ignoring invalid logging level: '%s' at line %d.\n", clevel, v->lineno); 17870 continue; 17871 } 17872 confp->mfcr2.loglevel |= tmplevel; 17873 } 17874 #endif /* HAVE_OPENR2 */ 17875 } else if (!strcasecmp(v->name, "cadence")) { 17876 /* setup to scan our argument */ 17877 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 17878 int i; 17879 struct dahdi_ring_cadence new_cadence; 17880 int cid_location = -1; 17881 int firstcadencepos = 0; 17882 char original_args[80]; 17883 int cadence_is_ok = 1; 17884 17885 ast_copy_string(original_args, v->value, sizeof(original_args)); 17886 /* 16 cadences allowed (8 pairs) */ 17887 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]); 17888 17889 /* Cadence must be even (on/off) */ 17890 if (element_count % 2 == 1) { 17891 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s at line %d.\n", original_args, v->lineno); 17892 cadence_is_ok = 0; 17893 } 17894 17895 /* Ring cadences cannot be negative */ 17896 for (i = 0; i < element_count; i++) { 17897 if (c[i] == 0) { 17898 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s at line %d.\n", original_args, v->lineno); 17899 cadence_is_ok = 0; 17900 break; 17901 } else if (c[i] < 0) { 17902 if (i % 2 == 1) { 17903 /* Silence duration, negative possibly okay */ 17904 if (cid_location == -1) { 17905 cid_location = i; 17906 c[i] *= -1; 17907 } else { 17908 ast_log(LOG_ERROR, "CID location specified twice: %s at line %d.\n", original_args, v->lineno); 17909 cadence_is_ok = 0; 17910 break; 17911 } 17912 } else { 17913 if (firstcadencepos == 0) { 17914 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 17915 /* duration will be passed negative to the DAHDI driver */ 17916 } else { 17917 ast_log(LOG_ERROR, "First cadence position specified twice: %s at line %d.\n", original_args, v->lineno); 17918 cadence_is_ok = 0; 17919 break; 17920 } 17921 } 17922 } 17923 } 17924 17925 /* Substitute our scanned cadence */ 17926 for (i = 0; i < 16; i++) { 17927 new_cadence.ringcadence[i] = c[i]; 17928 } 17929 17930 if (cadence_is_ok) { 17931 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 17932 if (element_count < 2) { 17933 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s at line %d.\n", original_args, v->lineno); 17934 } else { 17935 if (cid_location == -1) { 17936 /* user didn't say; default to first pause */ 17937 cid_location = 1; 17938 } else { 17939 /* convert element_index to cidrings value */ 17940 cid_location = (cid_location + 1) / 2; 17941 } 17942 /* ---we like their cadence; try to install it--- */ 17943 if (!user_has_defined_cadences++) 17944 /* this is the first user-defined cadence; clear the default user cadences */ 17945 num_cadence = 0; 17946 if ((num_cadence+1) >= NUM_CADENCE_MAX) 17947 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s at line %d.\n", NUM_CADENCE_MAX, original_args, v->lineno); 17948 else { 17949 cadences[num_cadence] = new_cadence; 17950 cidrings[num_cadence++] = cid_location; 17951 ast_verb(3, "cadence 'r%d' added: %s\n",num_cadence,original_args); 17952 } 17953 } 17954 } 17955 } else if (!strcasecmp(v->name, "ringtimeout")) { 17956 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 17957 } else if (!strcasecmp(v->name, "prewink")) { 17958 confp->timing.prewinktime = atoi(v->value); 17959 } else if (!strcasecmp(v->name, "preflash")) { 17960 confp->timing.preflashtime = atoi(v->value); 17961 } else if (!strcasecmp(v->name, "wink")) { 17962 confp->timing.winktime = atoi(v->value); 17963 } else if (!strcasecmp(v->name, "flash")) { 17964 confp->timing.flashtime = atoi(v->value); 17965 } else if (!strcasecmp(v->name, "start")) { 17966 confp->timing.starttime = atoi(v->value); 17967 } else if (!strcasecmp(v->name, "rxwink")) { 17968 confp->timing.rxwinktime = atoi(v->value); 17969 } else if (!strcasecmp(v->name, "rxflash")) { 17970 confp->timing.rxflashtime = atoi(v->value); 17971 } else if (!strcasecmp(v->name, "debounce")) { 17972 confp->timing.debouncetime = atoi(v->value); 17973 } else if (!strcasecmp(v->name, "toneduration")) { 17974 int toneduration; 17975 int ctlfd; 17976 int res; 17977 struct dahdi_dialparams dps; 17978 17979 ctlfd = open("/dev/dahdi/ctl", O_RDWR); 17980 if (ctlfd == -1) { 17981 ast_log(LOG_ERROR, "Unable to open /dev/dahdi/ctl to set toneduration at line %d.\n", v->lineno); 17982 return -1; 17983 } 17984 17985 toneduration = atoi(v->value); 17986 if (toneduration > -1) { 17987 memset(&dps, 0, sizeof(dps)); 17988 17989 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 17990 res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps); 17991 if (res < 0) { 17992 ast_log(LOG_ERROR, "Invalid tone duration: %d ms at line %d: %s\n", toneduration, v->lineno, strerror(errno)); 17993 close(ctlfd); 17994 return -1; 17995 } 17996 } 17997 close(ctlfd); 17998 } else if (!strcasecmp(v->name, "defaultcic")) { 17999 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 18000 } else if (!strcasecmp(v->name, "defaultozz")) { 18001 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 18002 } else if (!strcasecmp(v->name, "mwilevel")) { 18003 mwilevel = atoi(v->value); 18004 } else if (!strcasecmp(v->name, "dtmfcidlevel")) { 18005 dtmfcid_level = atoi(v->value); 18006 } else if (!strcasecmp(v->name, "reportalarms")) { 18007 if (!strcasecmp(v->value, "all")) 18008 report_alarms = REPORT_CHANNEL_ALARMS | REPORT_SPAN_ALARMS; 18009 if (!strcasecmp(v->value, "none")) 18010 report_alarms = 0; 18011 else if (!strcasecmp(v->value, "channels")) 18012 report_alarms = REPORT_CHANNEL_ALARMS; 18013 else if (!strcasecmp(v->value, "spans")) 18014 report_alarms = REPORT_SPAN_ALARMS; 18015 } 18016 } else if (!(options & PROC_DAHDI_OPT_NOWARN) ) 18017 ast_log(LOG_WARNING, "Ignoring any changes to '%s' (on reload) at line %d.\n", v->name, v->lineno); 18018 } 18019 18020 /* Since confp has already filled invidual dahdi_pvt objects with channels at this point, clear the variables in confp's pvt. */ 18021 if (confp->chan.vars) { 18022 ast_variables_destroy(confp->chan.vars); 18023 confp->chan.vars = NULL; 18024 } 18025 18026 if (dahdichan) { 18027 /* Process the deferred dahdichan value. */ 18028 if (build_channels(confp, dahdichan->value, reload, dahdichan->lineno, 18029 &found_pseudo)) { 18030 if (confp->ignore_failed_channels) { 18031 ast_log(LOG_WARNING, 18032 "Dahdichan '%s' failure ignored: ignore_failed_channels.\n", 18033 dahdichan->value); 18034 } else { 18035 return -1; 18036 } 18037 } 18038 } 18039 18040 /* mark the first channels of each DAHDI span to watch for their span alarms */ 18041 for (tmp = iflist, y=-1; tmp; tmp = tmp->next) { 18042 if (!tmp->destroy && tmp->span != y) { 18043 tmp->manages_span_alarms = 1; 18044 y = tmp->span; 18045 } else { 18046 tmp->manages_span_alarms = 0; 18047 } 18048 } 18049 18050 /*< \todo why check for the pseudo in the per-channel section. 18051 * Any actual use for manual setup of the pseudo channel? */ 18052 if (!found_pseudo && reload != 1 && !(options & PROC_DAHDI_OPT_NOCHAN)) { 18053 /* use the default configuration for a channel, so 18054 that any settings from real configured channels 18055 don't "leak" into the pseudo channel config 18056 */ 18057 struct dahdi_chan_conf conf = dahdi_chan_conf_default(); 18058 18059 if (conf.chan.cc_params) { 18060 tmp = mkintf(CHAN_PSEUDO, &conf, reload); 18061 } else { 18062 tmp = NULL; 18063 } 18064 if (tmp) { 18065 ast_verb(3, "Automatically generated pseudo channel\n"); 18066 } else { 18067 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 18068 } 18069 ast_cc_config_params_destroy(conf.chan.cc_params); 18070 } 18071 return 0; 18072 }
static void process_echocancel | ( | struct dahdi_chan_conf * | confp, | |
const char * | data, | |||
unsigned int | line | |||
) | [static] |
Definition at line 16903 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.
16904 { 16905 char *parse = ast_strdupa(data); 16906 char *params[DAHDI_MAX_ECHOCANPARAMS + 1]; 16907 unsigned int param_count; 16908 unsigned int x; 16909 16910 if (!(param_count = ast_app_separate_args(parse, ',', params, ARRAY_LEN(params)))) 16911 return; 16912 16913 memset(&confp->chan.echocancel, 0, sizeof(confp->chan.echocancel)); 16914 16915 /* first parameter is tap length, process it here */ 16916 16917 x = ast_strlen_zero(params[0]) ? 0 : atoi(params[0]); 16918 16919 if ((x == 32) || (x == 64) || (x == 128) || (x == 256) || (x == 512) || (x == 1024)) 16920 confp->chan.echocancel.head.tap_length = x; 16921 else if ((confp->chan.echocancel.head.tap_length = ast_true(params[0]))) 16922 confp->chan.echocancel.head.tap_length = 128; 16923 16924 /* now process any remaining parameters */ 16925 16926 for (x = 1; x < param_count; x++) { 16927 struct { 16928 char *name; 16929 char *value; 16930 } param; 16931 16932 if (ast_app_separate_args(params[x], '=', (char **) ¶m, 2) < 1) { 16933 ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %d: '%s'\n", line, params[x]); 16934 continue; 16935 } 16936 16937 if (ast_strlen_zero(param.name) || (strlen(param.name) > sizeof(confp->chan.echocancel.params[0].name)-1)) { 16938 ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %d: '%s'\n", line, param.name); 16939 continue; 16940 } 16941 16942 strcpy(confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].name, param.name); 16943 16944 if (param.value) { 16945 if (sscanf(param.value, "%30d", &confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].value) != 1) { 16946 ast_log(LOG_WARNING, "Invalid echocancel parameter value supplied at line %d: '%s'\n", line, param.value); 16947 continue; 16948 } 16949 } 16950 confp->chan.echocancel.head.param_count++; 16951 } 16952 }
static int reload | ( | void | ) | [static] |
Definition at line 18750 of file chan_dahdi.c.
References ast_log(), and setup_dahdi().
18751 { 18752 int res = 0; 18753 18754 res = setup_dahdi(1); 18755 if (res) { 18756 ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n"); 18757 return -1; 18758 } 18759 return 0; 18760 }
static int reset_conf | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4828 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().
04829 { 04830 p->confno = -1; 04831 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf)); 04832 if (p->subs[SUB_REAL].dfd > -1) { 04833 struct dahdi_confinfo zi; 04834 04835 memset(&zi, 0, sizeof(zi)); 04836 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi)) 04837 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno)); 04838 } 04839 return 0; 04840 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 11963 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().
11964 { 11965 /* If we're supposed to be stopped -- stay stopped */ 11966 if (monitor_thread == AST_PTHREADT_STOP) 11967 return 0; 11968 ast_mutex_lock(&monlock); 11969 if (monitor_thread == pthread_self()) { 11970 ast_mutex_unlock(&monlock); 11971 ast_log(LOG_WARNING, "Cannot kill myself\n"); 11972 return -1; 11973 } 11974 if (monitor_thread != AST_PTHREADT_NULL) { 11975 /* Wake up the thread */ 11976 pthread_kill(monitor_thread, SIGURG); 11977 } else { 11978 /* Start a new monitor */ 11979 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 11980 ast_mutex_unlock(&monlock); 11981 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 11982 return -1; 11983 } 11984 } 11985 ast_mutex_unlock(&monlock); 11986 return 0; 11987 }
static int restore_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5241 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().
05242 { 05243 int res; 05244 if (p->saveconf.confmode) { 05245 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf); 05246 p->saveconf.confmode = 0; 05247 if (res) { 05248 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno)); 05249 return -1; 05250 } 05251 ast_debug(1, "Restored conferencing\n"); 05252 } 05253 return 0; 05254 }
static int restore_gains | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5148 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().
05149 { 05150 int res; 05151 05152 res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law); 05153 if (res) { 05154 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno)); 05155 return -1; 05156 } 05157 05158 return 0; 05159 }
static int revert_fax_buffers | ( | struct dahdi_pvt * | p, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 6138 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().
06139 { 06140 if (p->bufferoverrideinuse) { 06141 /* faxbuffers are in use, revert them */ 06142 struct dahdi_bufferinfo bi = { 06143 .txbufpolicy = p->buf_policy, 06144 .rxbufpolicy = p->buf_policy, 06145 .bufsize = p->bufsize, 06146 .numbufs = p->buf_no 06147 }; 06148 int bpres; 06149 06150 if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 06151 ast_log(LOG_WARNING, "Channel '%s' unable to revert buffer policy: %s\n", ast->name, strerror(errno)); 06152 } 06153 p->bufferoverrideinuse = 0; 06154 return bpres; 06155 } 06156 06157 return -1; 06158 }
static int save_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5215 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().
05216 { 05217 struct dahdi_confinfo c; 05218 int res; 05219 if (p->saveconf.confmode) { 05220 ast_log(LOG_WARNING, "Can't save conference -- already in use\n"); 05221 return -1; 05222 } 05223 p->saveconf.chan = 0; 05224 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf); 05225 if (res) { 05226 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno)); 05227 p->saveconf.confmode = 0; 05228 return -1; 05229 } 05230 memset(&c, 0, sizeof(c)); 05231 c.confmode = DAHDI_CONF_NORMAL; 05232 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c); 05233 if (res) { 05234 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno)); 05235 return -1; 05236 } 05237 ast_debug(1, "Disabled conferencing\n"); 05238 return 0; 05239 }
static int send_callerid | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5299 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().
05300 { 05301 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */ 05302 int res; 05303 /* Take out of linear mode if necessary */ 05304 if (p->subs[SUB_REAL].linear) { 05305 p->subs[SUB_REAL].linear = 0; 05306 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 05307 } 05308 while (p->cidpos < p->cidlen) { 05309 res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos); 05310 ast_debug(4, "writing callerid at pos %d of %d, res = %d\n", p->cidpos, p->cidlen, res); 05311 if (res < 0) { 05312 if (errno == EAGAIN) 05313 return 0; 05314 else { 05315 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 05316 return -1; 05317 } 05318 } 05319 if (!res) 05320 return 0; 05321 p->cidpos += res; 05322 } 05323 p->cid_suppress_expire = CALLWAITING_SUPPRESS_SAMPLES; 05324 ast_free(p->cidspill); 05325 p->cidspill = NULL; 05326 if (p->callwaitcas) { 05327 /* Wait for CID/CW to expire */ 05328 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES; 05329 p->cid_suppress_expire = p->cidcwexpire; 05330 } else 05331 restore_conference(p); 05332 return 0; 05333 }
static int send_cwcidspill | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5256 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().
05257 { 05258 p->callwaitcas = 0; 05259 p->cidcwexpire = 0; 05260 p->cid_suppress_expire = 0; 05261 if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) 05262 return -1; 05263 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p)); 05264 /* Make sure we account for the end */ 05265 p->cidlen += READ_SIZE * 4; 05266 p->cidpos = 0; 05267 send_callerid(p); 05268 ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num); 05269 return 0; 05270 }
static int set_actual_gain | ( | int | fd, | |
float | rxgain, | |||
float | txgain, | |||
float | rxdrc, | |||
float | txdrc, | |||
int | law | |||
) | [static] |
Definition at line 5129 of file chan_dahdi.c.
References set_actual_rxgain(), and set_actual_txgain().
Referenced by bump_gains(), dahdi_call(), my_pri_ss7_open_media(), and restore_gains().
05130 { 05131 return set_actual_txgain(fd, txgain, txdrc, law) | set_actual_rxgain(fd, rxgain, rxdrc, law); 05132 }
static int set_actual_rxgain | ( | int | fd, | |
float | gain, | |||
float | drc, | |||
int | law | |||
) | [static] |
Definition at line 5112 of file chan_dahdi.c.
References ast_debug, errno, and fill_rxgain().
Referenced by dahdi_set_swgain(), dahdi_setoption(), and set_actual_gain().
05113 { 05114 struct dahdi_gains g; 05115 int res; 05116 05117 memset(&g, 0, sizeof(g)); 05118 res = ioctl(fd, DAHDI_GETGAINS, &g); 05119 if (res) { 05120 ast_debug(1, "Failed to read gains: %s\n", strerror(errno)); 05121 return res; 05122 } 05123 05124 fill_rxgain(&g, gain, drc, law); 05125 05126 return ioctl(fd, DAHDI_SETGAINS, &g); 05127 }
static int set_actual_txgain | ( | int | fd, | |
float | gain, | |||
float | drc, | |||
int | law | |||
) | [static] |
Definition at line 5095 of file chan_dahdi.c.
References ast_debug, errno, and fill_txgain().
Referenced by dahdi_set_swgain(), dahdi_setoption(), and set_actual_gain().
05096 { 05097 struct dahdi_gains g; 05098 int res; 05099 05100 memset(&g, 0, sizeof(g)); 05101 res = ioctl(fd, DAHDI_GETGAINS, &g); 05102 if (res) { 05103 ast_debug(1, "Failed to read gains: %s\n", strerror(errno)); 05104 return res; 05105 } 05106 05107 fill_txgain(&g, gain, drc, law); 05108 05109 return ioctl(fd, DAHDI_SETGAINS, &g); 05110 }
static int setup_dahdi | ( | int | reload | ) | [static] |
Definition at line 18393 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().
18394 { 18395 int res; 18396 struct dahdi_chan_conf default_conf = dahdi_chan_conf_default(); 18397 struct dahdi_chan_conf base_conf = dahdi_chan_conf_default(); 18398 struct dahdi_chan_conf conf = dahdi_chan_conf_default(); 18399 18400 if (default_conf.chan.cc_params && base_conf.chan.cc_params && conf.chan.cc_params) { 18401 res = setup_dahdi_int(reload, &default_conf, &base_conf, &conf); 18402 } else { 18403 res = -1; 18404 } 18405 ast_cc_config_params_destroy(default_conf.chan.cc_params); 18406 ast_cc_config_params_destroy(base_conf.chan.cc_params); 18407 ast_cc_config_params_destroy(conf.chan.cc_params); 18408 18409 return res; 18410 }
static int setup_dahdi_int | ( | int | reload, | |
struct dahdi_chan_conf * | default_conf, | |||
struct dahdi_chan_conf * | base_conf, | |||
struct dahdi_chan_conf * | conf | |||
) | [static] |
Definition at line 18106 of file chan_dahdi.c.
References ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_config_new(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, config, CONFIG_FLAG_FILEUNCHANGED, 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_NOWARN, process_dahdi(), sig_pri_start_pri(), and ast_variable::value.
Referenced by setup_dahdi().
18107 { 18108 struct ast_config *cfg; 18109 struct ast_config *ucfg; 18110 struct ast_variable *v; 18111 struct ast_flags config_flags = { reload == 1 ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 18112 const char *chans; 18113 const char *cat; 18114 int res; 18115 18116 #ifdef HAVE_PRI 18117 char *c; 18118 int spanno; 18119 int i; 18120 int logicalspan; 18121 int trunkgroup; 18122 int dchannels[SIG_PRI_NUM_DCHANS]; 18123 #endif 18124 int have_cfg_now; 18125 static int had_cfg_before = 1;/* So initial load will complain if we don't have cfg. */ 18126 18127 cfg = ast_config_load(config, config_flags); 18128 have_cfg_now = !!cfg; 18129 if (!cfg) { 18130 /* Error if we have no config file */ 18131 if (had_cfg_before) { 18132 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 18133 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 18134 } 18135 cfg = ast_config_new();/* Dummy config */ 18136 if (!cfg) { 18137 return 0; 18138 } 18139 ucfg = ast_config_load("users.conf", config_flags); 18140 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 18141 ast_config_destroy(cfg); 18142 return 0; 18143 } 18144 if (ucfg == CONFIG_STATUS_FILEINVALID) { 18145 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n"); 18146 ast_config_destroy(cfg); 18147 return 0; 18148 } 18149 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 18150 ucfg = ast_config_load("users.conf", config_flags); 18151 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 18152 return 0; 18153 } 18154 if (ucfg == CONFIG_STATUS_FILEINVALID) { 18155 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n"); 18156 return 0; 18157 } 18158 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 18159 cfg = ast_config_load(config, config_flags); 18160 have_cfg_now = !!cfg; 18161 if (!cfg) { 18162 if (had_cfg_before) { 18163 /* We should have been able to load the config. */ 18164 ast_log(LOG_ERROR, "Bad. Unable to load config %s\n", config); 18165 ast_config_destroy(ucfg); 18166 return 0; 18167 } 18168 cfg = ast_config_new();/* Dummy config */ 18169 if (!cfg) { 18170 ast_config_destroy(ucfg); 18171 return 0; 18172 } 18173 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 18174 ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config); 18175 ast_config_destroy(ucfg); 18176 return 0; 18177 } 18178 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 18179 ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config); 18180 return 0; 18181 } else { 18182 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 18183 ucfg = ast_config_load("users.conf", config_flags); 18184 if (ucfg == CONFIG_STATUS_FILEINVALID) { 18185 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n"); 18186 ast_config_destroy(cfg); 18187 return 0; 18188 } 18189 } 18190 had_cfg_before = have_cfg_now; 18191 18192 /* It's a little silly to lock it, but we might as well just to be sure */ 18193 ast_mutex_lock(&iflock); 18194 #ifdef HAVE_PRI 18195 if (reload != 1) { 18196 /* Process trunkgroups first */ 18197 v = ast_variable_browse(cfg, "trunkgroups"); 18198 while (v) { 18199 if (!strcasecmp(v->name, "trunkgroup")) { 18200 trunkgroup = atoi(v->value); 18201 if (trunkgroup > 0) { 18202 if ((c = strchr(v->value, ','))) { 18203 i = 0; 18204 memset(dchannels, 0, sizeof(dchannels)); 18205 while (c && (i < SIG_PRI_NUM_DCHANS)) { 18206 dchannels[i] = atoi(c + 1); 18207 if (dchannels[i] < 0) { 18208 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); 18209 } else 18210 i++; 18211 c = strchr(c + 1, ','); 18212 } 18213 if (i) { 18214 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 18215 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); 18216 } else 18217 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"); 18218 } else 18219 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno); 18220 } else 18221 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno); 18222 } else 18223 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->lineno); 18224 } else if (!strcasecmp(v->name, "spanmap")) { 18225 spanno = atoi(v->value); 18226 if (spanno > 0) { 18227 if ((c = strchr(v->value, ','))) { 18228 trunkgroup = atoi(c + 1); 18229 if (trunkgroup > 0) { 18230 if ((c = strchr(c + 1, ','))) 18231 logicalspan = atoi(c + 1); 18232 else 18233 logicalspan = 0; 18234 if (logicalspan >= 0) { 18235 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 18236 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 18237 } else 18238 ast_verb(2, "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 18239 } else 18240 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); 18241 } else 18242 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of chan_dahdi.conf\n", v->lineno); 18243 } else 18244 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of chan_dahdi.conf\n", v->lineno); 18245 } else 18246 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of chan_dahdi.conf\n", v->lineno); 18247 } else { 18248 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 18249 } 18250 v = v->next; 18251 } 18252 } 18253 #endif 18254 18255 /* Copy the default jb config over global_jbconf */ 18256 memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf)); 18257 18258 mwimonitornotify[0] = '\0'; 18259 18260 v = ast_variable_browse(cfg, "channels"); 18261 if ((res = process_dahdi(base_conf, 18262 "" /* Must be empty for the channels category. Silly voicemail mailbox. */, 18263 v, reload, 0))) { 18264 ast_mutex_unlock(&iflock); 18265 ast_config_destroy(cfg); 18266 if (ucfg) { 18267 ast_config_destroy(ucfg); 18268 } 18269 return res; 18270 } 18271 18272 /* Now get configuration from all normal sections in chan_dahdi.conf: */ 18273 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 18274 /* [channels] and [trunkgroups] are used. Let's also reserve 18275 * [globals] and [general] for future use 18276 */ 18277 if (!strcasecmp(cat, "general") || 18278 !strcasecmp(cat, "trunkgroups") || 18279 !strcasecmp(cat, "globals") || 18280 !strcasecmp(cat, "channels")) { 18281 continue; 18282 } 18283 18284 chans = ast_variable_retrieve(cfg, cat, "dahdichan"); 18285 if (ast_strlen_zero(chans)) { 18286 /* Section is useless without a dahdichan value present. */ 18287 continue; 18288 } 18289 18290 /* Copy base_conf to conf. */ 18291 deep_copy_dahdi_chan_conf(conf, base_conf); 18292 18293 if ((res = process_dahdi(conf, cat, ast_variable_browse(cfg, cat), reload, PROC_DAHDI_OPT_NOCHAN))) { 18294 ast_mutex_unlock(&iflock); 18295 ast_config_destroy(cfg); 18296 if (ucfg) { 18297 ast_config_destroy(ucfg); 18298 } 18299 return res; 18300 } 18301 } 18302 18303 ast_config_destroy(cfg); 18304 18305 if (ucfg) { 18306 /* Reset base_conf, so things don't leak from chan_dahdi.conf */ 18307 deep_copy_dahdi_chan_conf(base_conf, default_conf); 18308 process_dahdi(base_conf, 18309 "" /* Must be empty for the general category. Silly voicemail mailbox. */, 18310 ast_variable_browse(ucfg, "general"), 1, 0); 18311 18312 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 18313 if (!strcasecmp(cat, "general")) { 18314 continue; 18315 } 18316 18317 chans = ast_variable_retrieve(ucfg, cat, "dahdichan"); 18318 if (ast_strlen_zero(chans)) { 18319 /* Section is useless without a dahdichan value present. */ 18320 continue; 18321 } 18322 18323 /* Copy base_conf to conf. */ 18324 deep_copy_dahdi_chan_conf(conf, base_conf); 18325 18326 if ((res = process_dahdi(conf, cat, ast_variable_browse(ucfg, cat), reload, PROC_DAHDI_OPT_NOCHAN | PROC_DAHDI_OPT_NOWARN))) { 18327 ast_config_destroy(ucfg); 18328 ast_mutex_unlock(&iflock); 18329 return res; 18330 } 18331 } 18332 ast_config_destroy(ucfg); 18333 } 18334 ast_mutex_unlock(&iflock); 18335 18336 #ifdef HAVE_PRI 18337 if (reload != 1) { 18338 int x; 18339 for (x = 0; x < NUM_SPANS; x++) { 18340 if (pris[x].pri.pvts[0]) { 18341 prepare_pri(pris + x); 18342 if (sig_pri_start_pri(&pris[x].pri)) { 18343 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 18344 return -1; 18345 } else 18346 ast_verb(2, "Starting D-Channel on span %d\n", x + 1); 18347 } 18348 } 18349 } 18350 #endif 18351 #if defined(HAVE_SS7) 18352 if (reload != 1) { 18353 int x; 18354 for (x = 0; x < NUM_SPANS; x++) { 18355 if (linksets[x].ss7.ss7) { 18356 linksets[x].ss7.calls = &dahdi_ss7_callbacks; 18357 if (ast_pthread_create(&linksets[x].ss7.master, NULL, ss7_linkset, &linksets[x].ss7)) { 18358 ast_log(LOG_ERROR, "Unable to start SS7 linkset on span %d\n", x + 1); 18359 return -1; 18360 } else 18361 ast_verb(2, "Starting SS7 linkset on span %d\n", x + 1); 18362 } 18363 } 18364 } 18365 #endif /* defined(HAVE_SS7) */ 18366 #ifdef HAVE_OPENR2 18367 if (reload != 1) { 18368 int x; 18369 for (x = 0; x < r2links_count; x++) { 18370 if (ast_pthread_create(&r2links[x]->r2master, NULL, mfcr2_monitor, r2links[x])) { 18371 ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1); 18372 return -1; 18373 } else { 18374 ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1); 18375 } 18376 } 18377 } 18378 #endif 18379 /* And start the monitor for the first time */ 18380 restart_monitor(); 18381 return 0; 18382 }
static int sig_pri_tone_to_dahditone | ( | enum sig_pri_tone | tone | ) | [static] |
Definition at line 3089 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().
03090 { 03091 switch (tone) { 03092 case SIG_PRI_TONE_RINGTONE: 03093 return DAHDI_TONE_RINGTONE; 03094 case SIG_PRI_TONE_STUTTER: 03095 return DAHDI_TONE_STUTTER; 03096 case SIG_PRI_TONE_CONGESTION: 03097 return DAHDI_TONE_CONGESTION; 03098 case SIG_PRI_TONE_DIALTONE: 03099 return DAHDI_TONE_DIALTONE; 03100 case SIG_PRI_TONE_DIALRECALL: 03101 return DAHDI_TONE_DIALRECALL; 03102 case SIG_PRI_TONE_INFO: 03103 return DAHDI_TONE_INFO; 03104 case SIG_PRI_TONE_BUSY: 03105 return DAHDI_TONE_BUSY; 03106 default: 03107 return -1; 03108 } 03109 }
static int sigtype_to_signalling | ( | int | sigtype | ) | [static] |
static void string_replace | ( | char * | str, | |
int | char1, | |||
int | char2 | |||
) | [static] |
Definition at line 16807 of file chan_dahdi.c.
Referenced by parse_spanchan().
16808 { 16809 for (; *str; str++) { 16810 if (*str == char1) { 16811 *str = char2; 16812 } 16813 } 16814 }
static void swap_subs | ( | struct dahdi_pvt * | p, | |
int | a, | |||
int | b | |||
) | [static] |
Definition at line 4284 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().
04285 { 04286 int tchan; 04287 int tinthreeway; 04288 struct ast_channel *towner; 04289 04290 ast_debug(1, "Swapping %d and %d\n", a, b); 04291 04292 tchan = p->subs[a].chan; 04293 towner = p->subs[a].owner; 04294 tinthreeway = p->subs[a].inthreeway; 04295 04296 p->subs[a].chan = p->subs[b].chan; 04297 p->subs[a].owner = p->subs[b].owner; 04298 p->subs[a].inthreeway = p->subs[b].inthreeway; 04299 04300 p->subs[b].chan = tchan; 04301 p->subs[b].owner = towner; 04302 p->subs[b].inthreeway = tinthreeway; 04303 04304 if (p->subs[a].owner) 04305 ast_channel_set_fd(p->subs[a].owner, 0, p->subs[a].dfd); 04306 if (p->subs[b].owner) 04307 ast_channel_set_fd(p->subs[b].owner, 0, p->subs[b].dfd); 04308 wakeup_sub(p, a); 04309 wakeup_sub(p, b); 04310 }
static int unalloc_sub | ( | struct dahdi_pvt * | p, | |
int | x | |||
) | [static] |
Definition at line 4430 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().
04431 { 04432 if (!x) { 04433 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel); 04434 return -1; 04435 } 04436 ast_debug(1, "Released sub %d of channel %d\n", x, p->channel); 04437 dahdi_close_sub(p, x); 04438 p->subs[x].linear = 0; 04439 p->subs[x].chan = 0; 04440 p->subs[x].owner = NULL; 04441 p->subs[x].inthreeway = 0; 04442 p->polarity = POLARITY_IDLE; 04443 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf)); 04444 return 0; 04445 }
static int unload_module | ( | void | ) | [static] |
Definition at line 16791 of file chan_dahdi.c.
References __unload_module(), ast_mutex_destroy, sig_ss7_linkset::lock, sig_pri_span::lock, and dahdi_pvt::pri.
16792 { 16793 #if defined(HAVE_PRI) || defined(HAVE_SS7) 16794 int y; 16795 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 16796 #ifdef HAVE_PRI 16797 for (y = 0; y < NUM_SPANS; y++) 16798 ast_mutex_destroy(&pris[y].pri.lock); 16799 #endif 16800 #if defined(HAVE_SS7) 16801 for (y = 0; y < NUM_SPANS; y++) 16802 ast_mutex_destroy(&linksets[y].ss7.lock); 16803 #endif /* defined(HAVE_SS7) */ 16804 return __unload_module(); 16805 }
static int update_conf | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4842 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().
04843 { 04844 int needconf = 0; 04845 int x; 04846 int useslavenative; 04847 struct dahdi_pvt *slave = NULL; 04848 04849 useslavenative = isslavenative(p, &slave); 04850 /* Start with the obvious, general stuff */ 04851 for (x = 0; x < 3; x++) { 04852 /* Look for three way calls */ 04853 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) { 04854 conf_add(p, &p->subs[x], x, 0); 04855 needconf++; 04856 } else { 04857 conf_del(p, &p->subs[x], x); 04858 } 04859 } 04860 /* If we have a slave, add him to our conference now. or DAX 04861 if this is slave native */ 04862 for (x = 0; x < MAX_SLAVES; x++) { 04863 if (p->slaves[x]) { 04864 if (useslavenative) 04865 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 04866 else { 04867 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 04868 needconf++; 04869 } 04870 } 04871 } 04872 /* If we're supposed to be in there, do so now */ 04873 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 04874 if (useslavenative) 04875 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 04876 else { 04877 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 04878 needconf++; 04879 } 04880 } 04881 /* If we have a master, add ourselves to his conference */ 04882 if (p->master) { 04883 if (isslavenative(p->master, NULL)) { 04884 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 04885 } else { 04886 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 04887 } 04888 } 04889 if (!needconf) { 04890 /* Nobody is left (or should be left) in our conference. 04891 Kill it. */ 04892 p->confno = -1; 04893 } 04894 ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 04895 return 0; 04896 }
static void wakeup_sub | ( | struct dahdi_pvt * | p, | |
int | a | |||
) | [static] |
Definition at line 3791 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().
03792 { 03793 dahdi_lock_sub_owner(p, a); 03794 if (p->subs[a].owner) { 03795 ast_queue_frame(p->subs[a].owner, &ast_null_frame); 03796 ast_channel_unlock(p->subs[a].owner); 03797 } 03798 }
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_smdi", } [static] |
Definition at line 18772 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 18772 of file chan_dahdi.c.
struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] [static] |
Definition at line 387 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 398 of file chan_dahdi.c.
Referenced by handle_dahdi_show_cadences(), and my_set_cadence().
const char config[] = "chan_dahdi.conf" [static] |
Definition at line 341 of file chan_dahdi.c.
const char* const dahdi_accept_r2_call_app = "DAHDIAcceptR2Call" [static] |
Definition at line 5996 of file chan_dahdi.c.
struct analog_callback dahdi_analog_callbacks [static] |
Definition at line 3667 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 18553 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 18563 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_cc_agent_callbacks dahdi_pri_cc_agent_callbacks [static] |
struct ast_cc_monitor_callbacks dahdi_pri_cc_monitor_callbacks [static] |
const char dahdi_pri_cc_type[] = "DAHDI/PRI" [static] |
DAHDI PRI CCSS agent and monitor type name.
Definition at line 599 of file chan_dahdi.c.
Referenced by dahdi_queryoption(), and load_module().
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 4246 of file chan_dahdi.c.
openr2_transcoder_interface_t dahdi_r2_transcode_iface [static] |
Initial value:
Definition at line 4277 of file chan_dahdi.c.
char* dahdi_send_callrerouting_facility_app = "DAHDISendCallreroutingFacility" [static] |
Definition at line 5926 of file chan_dahdi.c.
char* dahdi_send_keypad_facility_app = "DAHDISendKeypadFacility" [static] |
Definition at line 5899 of file chan_dahdi.c.
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 18548 of file chan_dahdi.c.
struct ast_channel_tech dahdi_tech [static] |
Definition at line 1512 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 18558 of file chan_dahdi.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 290 of file chan_dahdi.c.
char defaultcic[64] = "" [static] |
Definition at line 414 of file chan_dahdi.c.
char defaultozz[64] = "" [static] |
Definition at line 415 of file chan_dahdi.c.
int distinctiveringaftercid = 0 [static] |
Definition at line 426 of file chan_dahdi.c.
int dtmfcid_level = 256 [static] |
Definition at line 431 of file chan_dahdi.c.
const char* const events[] [static] |
Definition at line 4557 of file chan_dahdi.c.
int firstdigittimeout = 16000 [static] |
Wait up to 16 seconds for first digit (FXO logic).
Definition at line 443 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 446 of file chan_dahdi.c.
Referenced by analog_ss_thread(), and mgcp_ss().
struct ast_jb_conf global_jbconf [static] |
Definition at line 298 of file chan_dahdi.c.
int ifcount = 0 [static] |
Definition at line 455 of file chan_dahdi.c.
Referenced by destroy_all_channels(), and do_monitor().
Main interface list end
Definition at line 1316 of file chan_dahdi.c.
Referenced by dahdi_iflist_extract(), dahdi_request(), and determine_starting_point().
Main interface list start
Definition at line 1315 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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Protect the interface list (of dahdi_pvt's).
Definition at line 452 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 277 of file chan_dahdi.c.
Referenced by dahdi_show_status(), and dahdi_status_data_provider_get().
int matchdigittimeout = 3000 [static] |
How long to wait for an extra digit, if there is an ambiguous match.
Definition at line 449 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 467 of file chan_dahdi.c.
Referenced by __sip_reliable_xmit(), __unload_module(), restart_monitor(), and unload_module().
ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [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 463 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 418 of file chan_dahdi.c.
Referenced by notify_message(), and setup_dahdi_int().
char* name |
Definition at line 4581 of file chan_dahdi.c.
int num_cadence = 4 [static] |
Definition at line 384 of file chan_dahdi.c.
Referenced by handle_dahdi_show_cadences(), and my_set_cadence().
int num_restart_pending = 0 [static] |
Definition at line 472 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 428 of file chan_dahdi.c.
int pridebugfd = -1 [static] |
ast_mutex_t pridebugfdlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
char pridebugfilename[1024] = "" [static] |
Definition at line 595 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_channels(), 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 580 of file chan_dahdi.c.
Referenced by dahdi_r2_destroy_links(), and dahdi_r2_get_link().
int r2links_count = 0 [static] |
Definition at line 582 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 435 of file chan_dahdi.c.
Referenced by handle_alarms(), and handle_clear_alarms().
ast_mutex_t restart_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
int ringt_base = DEFAULT_RINGT [static] |
Configured ring timeout base.
Definition at line 528 of file chan_dahdi.c.
struct dahdi_pvt* round_robin[32] [static] |
Round robin search locations.
Definition at line 3738 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 468 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 471 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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 469 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 628 of file chan_dahdi.c.
Referenced by alloc_sub(), dahdi_bridge(), and dahdi_new().
const char tdesc[] [static] |
Definition at line 320 of file chan_dahdi.c.
int usedistinctiveringdetection = 0 [static] |
Definition at line 425 of file chan_dahdi.c.
int user_has_defined_cadences = 0 [static] |
Definition at line 385 of file chan_dahdi.c.