DAHDI for Pseudo TDM. More...
#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 "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_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 | CIDCW_EXPIRE_SAMPLES ((500 * 8) / READ_SIZE) |
| #define | CONF_USER_REAL (1 << 0) |
| #define | CONF_USER_THIRDCALL (1 << 1) |
| #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 %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" |
| #define | FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n" |
| #define | FORMAT2 "%7s %-15.15s %-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 | 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_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 } |
| 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 int | __unload_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) | |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, tdesc,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DRIVER,.nonoptreq="res_smdi",) | |
| AST_MUTEX_DEFINE_STATIC (restart_lock) | |
| AST_MUTEX_DEFINE_STATIC (ss_thread_lock) | |
| AST_MUTEX_DEFINE_STATIC (monlock) | |
| Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
| AST_MUTEX_DEFINE_STATIC (iflock) | |
| Protect the interface list (of dahdi_pvt's). | |
| 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 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) |
| static void | dahdi_ami_channel_event (struct dahdi_pvt *p, struct ast_channel *chan) |
| static int | dahdi_answer (struct ast_channel *ast) |
| 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_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_open (char *fn) |
| 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 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_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_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 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 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 struct dahdi_pvt * | mkintf (int channel, const struct dahdi_chan_conf *conf, int reloading) |
| static void | monitor_pfds_clean (void *arg) |
| static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
| static int | mwi_send_init (struct dahdi_pvt *pvt) |
| static int | mwi_send_process_buffer (struct dahdi_pvt *pvt, int num_read) |
| static int | mwi_send_process_event (struct dahdi_pvt *pvt, int event) |
| static void * | mwi_thread (void *data) |
| static void | my_all_subchannels_hungup (void *pvt) |
| static int | my_allocate_sub (void *pvt, enum analog_sub analogsub) |
| static void | my_answer_polarityswitch (void *pvt) |
| static int | my_callwait (void *pvt) |
| static void | my_cancel_cidspill (void *pvt) |
| static int | my_check_confirmanswer (void *pvt) |
| static int | my_check_for_conference (void *pvt) |
| static int | my_check_waitingfordt (void *pvt) |
| static int | my_complete_conference_update (void *pvt, int needconference) |
| static int | my_conf_add (void *pvt, enum analog_sub sub) |
| static int | my_conf_del (void *pvt, enum analog_sub sub) |
| static int | my_confmute (void *pvt, int mute) |
| static int | my_dahdi_write (struct dahdi_pvt *p, unsigned char *buf, int len, int idx, int linear) |
| static void | my_deadlock_avoidance_private (void *pvt) |
| static void | my_decrease_ss_count (void) |
| static int | my_dial_digits (void *pvt, enum analog_sub sub, struct analog_dialoperation *dop) |
| static int | my_distinctive_ring (struct ast_channel *chan, void *pvt, int idx, int *ringdata) |
| static int | my_dsp_reset_and_flush_digits (void *pvt) |
| static int | my_dsp_set_digitmode (void *pvt, enum analog_dsp_digitmode mode) |
| static int | my_flash (void *pvt) |
| static void | my_get_and_handle_alarms (void *pvt) |
| static int | my_get_callerid (void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout) |
| static int | my_get_event (void *pvt) |
| static const char * | my_get_orig_dialstring (void *pvt) |
| static void * | my_get_sigpvt_bridged_channel (struct ast_channel *chan) |
| static int | my_get_sub_fd (void *pvt, enum analog_sub sub) |
| static int | my_getsigstr (struct ast_channel *chan, char *str, const char *term, int ms) |
| static void | my_handle_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 struct ast_channel * | my_new_analog_ast_channel (void *pvt, int state, int startpbx, enum analog_sub sub, 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 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_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 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_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 | 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 | 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 | |
| struct { | |
| int alarm | |
| char * name | |
| } | alarms [] |
| static struct dahdi_ring_cadence | AS_RP_cadence = {{250, 10000}} |
| 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 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_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 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 int | mwilevel = 512 |
| static char | mwimonitornotify [PATH_MAX] = "" |
| static int | mwisend_rpas = 0 |
| static int | num_cadence = 4 |
| static int | num_restart_pending = 0 |
| static int | numbufs = 4 |
| static char | progzone [10] = "" |
| static int | report_alarms = REPORT_CHANNEL_ALARMS |
| 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 const char *const | subnames [] |
| static const char | tdesc [] = "DAHDI Telephony Driver" |
| static int | usedistinctiveringdetection = 0 |
| static int | user_has_defined_cadences = 0 |
DAHDI for Pseudo TDM.
Connects to the DAHDI telephony library as well as libpri. Libpri is optional and needed only if you are going to use ISDN connections.
You need to install libraries before you attempt to compile and install the 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 320 of file chan_dahdi.c.
Referenced by analog_ss_thread(), dahdi_callwait(), dahdi_sendtext(), do_monitor(), 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 387 of file chan_dahdi.c.
Referenced by dahdi_handle_dtmf(), my_handle_dtmf(), and process_dahdi().
| #define CALLPROGRESS_FAX_INCOMING 4 |
Definition at line 386 of file chan_dahdi.c.
Referenced by dahdi_new(), and process_dahdi().
| #define CALLPROGRESS_FAX_OUTGOING 2 |
Definition at line 385 of file chan_dahdi.c.
Referenced by dahdi_new(), and process_dahdi().
| #define CALLPROGRESS_PROGRESS 1 |
Definition at line 384 of file chan_dahdi.c.
Referenced by dahdi_handle_event(), dahdi_new(), my_have_progressdetect(), and process_dahdi().
| #define CALLWAITING_REPEAT_SAMPLES ((10000 * 8) / READ_SIZE) |
10,000 ms
Definition at line 522 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 521 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) */) |
Definition at line 417 of file chan_dahdi.c.
Referenced by dahdi_new().
| #define CANPROGRESSDETECT | ( | p | ) | (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */) |
Definition at line 418 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 382 of file chan_dahdi.c.
Referenced by build_channels(), create_channel_name(), dahdi_ami_channel_event(), dahdi_new(), dahdi_request(), determine_starting_point(), enable_dtmf_detect(), mkintf(), my_dsp_set_digitmode(), my_set_polarity(), and process_dahdi().
| #define CIDCW_EXPIRE_SAMPLES ((500 * 8) / READ_SIZE) |
| #define CONF_USER_REAL (1 << 0) |
Definition at line 659 of file chan_dahdi.c.
| #define CONF_USER_THIRDCALL (1 << 1) |
Definition at line 660 of file chan_dahdi.c.
| #define dahdi_get_index | ( | ast, | |||
| p, | |||||
| nullok | ) | _dahdi_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__) |
Definition at line 3771 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 1236 of file chan_dahdi.c.
| #define DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID.
Definition at line 318 of file chan_dahdi.c.
Referenced by dahdi_chan_conf_default().
| #define DEFAULT_RINGT ((8000 * 8) / READ_SIZE) |
8,000 ms
Definition at line 526 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 %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" |
Referenced by __iax2_show_peers(), alias_show(), dahdi_show_channels(), 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_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 %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" |
Referenced by __iax2_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) |
Definition at line 1525 of file chan_dahdi.c.
Referenced by my_complete_conference_update(), and update_conf().
| #define HANGUP 1 |
Definition at line 15910 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 | ) |
Definition at line 414 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 518 of file chan_dahdi.c.
| #define MASK_INUSE (1 << 1) |
Channel currently in use
Definition at line 519 of file chan_dahdi.c.
| #define MAX_CHANLIST_LEN 80 |
The length of the parameters list of 'dahdichan'.
Definition at line 16938 of file chan_dahdi.c.
| #define MAX_SLAVES 4 |
Definition at line 662 of file chan_dahdi.c.
Referenced by dahdi_link(), dahdi_show_channel(), dahdi_unlink(), isslavenative(), my_complete_conference_update(), and update_conf().
| #define MIN_MS_SINCE_FLASH ((2000) ) |
2000 ms
Definition at line 525 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 324 of file chan_dahdi.c.
Referenced by analog_ss_thread(), and dahdi_new().
| #define NUM_CADENCE_MAX 25 |
Definition at line 389 of file chan_dahdi.c.
Referenced by process_dahdi().
| #define NUM_SPANS 32 |
Definition at line 379 of file chan_dahdi.c.
Referenced by destroy_all_channels().
| #define POLARITY_IDLE 0 |
Definition at line 619 of file chan_dahdi.c.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_hangup(), analog_ss_thread(), dahdi_handle_event(), dahdi_hangup(), and unalloc_sub().
| #define POLARITY_REV 1 |
Definition at line 620 of file chan_dahdi.c.
Referenced by __analog_handle_event(), __analog_ss_thread(), analog_handle_init_event(), analog_ss_thread(), dahdi_handle_event(), and handle_init_event().
| #define PROC_DAHDI_OPT_NOCHAN (1 << 0) |
process_dahdi() - ignore keyword 'channel' and similar
Definition at line 16992 of file chan_dahdi.c.
Referenced by process_dahdi(), and setup_dahdi_int().
| #define PROC_DAHDI_OPT_NOWARN (1 << 1) |
process_dahdi() - No warnings on non-existing cofiguration keywords
Definition at line 16994 of file chan_dahdi.c.
Referenced by process_dahdi(), and setup_dahdi_int().
| #define READ_SIZE 160 |
Chunk size to read -- we use 20ms chunks to make things happy.
Definition at line 516 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(), process_dahdi(), and send_cwcidspill().
| #define REPORT_CHANNEL_ALARMS 1 |
Definition at line 439 of file chan_dahdi.c.
Referenced by handle_alarms(), handle_clear_alarms(), and process_dahdi().
| #define REPORT_SPAN_ALARMS 2 |
Definition at line 440 of file chan_dahdi.c.
Referenced by handle_alarms(), handle_clear_alarms(), and process_dahdi().
| #define sig2str dahdi_sig2str |
Definition at line 4706 of file chan_dahdi.c.
Referenced by action_dahdishowchannels(), analog_ss_thread(), build_channels(), dahdi_handle_event(), dahdi_show_channel(), handle_init_event(), and mkintf().
| #define SIG_BRI (0x2000000 | DAHDI_SIG_CLEAR) |
Definition at line 365 of file chan_dahdi.c.
Referenced by dahdi_sig2str(), and process_dahdi().
| #define SIG_BRI_PTMP (0X4000000 | DAHDI_SIG_CLEAR) |
Definition at line 366 of file chan_dahdi.c.
Referenced by dahdi_sig2str(), mkintf(), and process_dahdi().
| #define SIG_E911 (0x1000000 | DAHDI_SIG_EM) |
Definition at line 354 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_EM 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(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_EM_E1 DAHDI_SIG_EM_E1 |
Definition at line 374 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_EMWINK (0x0100000 | 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(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_FEATB (0x0800000 | DAHDI_SIG_EM) |
Definition at line 353 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_FEATD (0x0200000 | 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(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_FEATDMF (0x0400000 | DAHDI_SIG_EM) |
Definition at line 352 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_FEATDMF_TA (0x2000000 | DAHDI_SIG_EM) |
Definition at line 355 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_FGC_CAMA (0x4000000 | DAHDI_SIG_EM) |
Definition at line 356 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_FGC_CAMAMF (0x8000000 | DAHDI_SIG_EM) |
Definition at line 357 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_FXOGS DAHDI_SIG_FXOGS |
Definition at line 362 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(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_FXOKS DAHDI_SIG_FXOKS |
Definition at line 363 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(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_FXOLS DAHDI_SIG_FXOLS |
Definition at line 361 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(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_FXSGS DAHDI_SIG_FXSGS |
Definition at line 359 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(), my_is_off_hook(), and process_dahdi().
| #define SIG_FXSKS DAHDI_SIG_FXSKS |
Definition at line 360 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(), mkintf(), my_is_off_hook(), and process_dahdi().
| #define SIG_FXSLS DAHDI_SIG_FXSLS |
Definition at line 358 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(), mkintf(), and process_dahdi().
| #define SIG_MFCR2 DAHDI_SIG_CAS |
Definition at line 368 of file chan_dahdi.c.
Referenced by dahdi_answer(), dahdi_call(), dahdi_func_read(), dahdi_handle_event(), dahdi_hangup(), dahdi_sig2str(), do_monitor(), mkintf(), and process_dahdi().
| #define SIG_PRI DAHDI_SIG_CLEAR |
Definition at line 364 of file chan_dahdi.c.
Referenced by dahdi_indicate(), dahdi_sig2str(), mkintf(), and process_dahdi().
| #define SIG_PRI_LIB_HANDLE_CASES |
SIG_PRI: \ case SIG_BRI: \ case SIG_BRI_PTMP
Definition at line 1527 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_sig_pri_lib_handles(), destroy_dahdi_pvt(), handle_init_event(), and mkintf().
| #define SIG_SF DAHDI_SIG_SF |
Definition at line 369 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_SF_FEATB (0x0800000 | DAHDI_SIG_SF) |
Definition at line 373 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_SF_FEATD (0x0200000 | DAHDI_SIG_SF) |
Definition at line 371 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), and mkintf().
| #define SIG_SF_FEATDMF (0x0400000 | DAHDI_SIG_SF) |
Definition at line 372 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), and mkintf().
| #define SIG_SFWINK (0x0100000 | DAHDI_SIG_SF) |
Definition at line 370 of file chan_dahdi.c.
Referenced by analog_lib_handles(), analog_ss_thread(), dahdi_handle_event(), dahdi_sig2str(), dahdisig_to_analogsig(), handle_init_event(), mkintf(), and process_dahdi().
| #define SIG_SS7 (0x1000000 | DAHDI_SIG_CLEAR) |
Definition at line 367 of file chan_dahdi.c.
Referenced by available(), dahdi_answer(), dahdi_call(), dahdi_confmute(), dahdi_enable_ec(), dahdi_fixup(), dahdi_func_read(), dahdi_handle_event(), dahdi_hangup(), dahdi_indicate(), dahdi_new(), dahdi_request(), dahdi_sig2str(), destroy_dahdi_pvt(), handle_init_event(), mkintf(), and process_dahdi().
| #define SMDI_MD_WAIT_TIMEOUT 1500 |
Definition at line 281 of file chan_dahdi.c.
Referenced by analog_ss_thread().
| #define SUB_CALLWAIT 1 |
Call-Waiting call on hold
Definition at line 615 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 614 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_read(), dahdi_request(), dahdi_restart(), 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(), mkintf(), 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_off_hook(), 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(), unistim_senddigit_end(), and update_conf().
| #define SUB_THREEWAY 2 |
Three-way call
Definition at line 616 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 15909 of file chan_dahdi.c.
Referenced by action_transfer(), dahdi_fake_event(), send_agent_complete(), and try_calling().
| 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 |
Definition at line 683 of file chan_dahdi.c.
00683 { 00684 DAHDI_IFLIST_NONE, /*!< The dahdi_pvt is not in any list. */ 00685 DAHDI_IFLIST_MAIN, /*!< The dahdi_pvt is in the main interface list */ 00686 #if defined(HAVE_PRI) 00687 DAHDI_IFLIST_NO_B_CHAN, /*!< The dahdi_pvt is in a no B channel interface list */ 00688 #endif /* defined(HAVE_PRI) */ 00689 };
| 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 667 of file chan_dahdi.c.
00667 { 00668 MWI_SEND_NULL = 0, 00669 MWI_SEND_SA, 00670 MWI_SEND_SA_WAIT, 00671 MWI_SEND_PAUSE, 00672 MWI_SEND_SPILL, 00673 MWI_SEND_CLEANUP, 00674 MWI_SEND_DONE, 00675 } mwisend_states;
| static struct ast_frame* __dahdi_exception | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 8793 of file chan_dahdi.c.
References ast_channel::_state, 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::callwaitingrepeat, dahdi_pvt::channel, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cidcwexpire, 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, dahdi_subchannel::dfd, dahdi_pvt::dialing, event2str(), dahdi_subchannel::f, dahdi_pvt::fake_event, ast_channel::fds, dahdi_pvt::flashtime, ast_frame::frametype, ast_frame_subclass::integer, dahdi_pvt::lock, LOG_WARNING, ast_frame::mallocd, name, dahdi_subchannel::needanswer, 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().
08794 { 08795 int res; 08796 int idx; 08797 struct ast_frame *f; 08798 int usedindex = -1; 08799 struct dahdi_pvt *p = ast->tech_pvt; 08800 08801 if ((idx = dahdi_get_index(ast, p, 0)) < 0) { 08802 idx = SUB_REAL; 08803 } 08804 08805 p->subs[idx].f.frametype = AST_FRAME_NULL; 08806 p->subs[idx].f.datalen = 0; 08807 p->subs[idx].f.samples = 0; 08808 p->subs[idx].f.mallocd = 0; 08809 p->subs[idx].f.offset = 0; 08810 p->subs[idx].f.subclass.integer = 0; 08811 p->subs[idx].f.delivery = ast_tv(0,0); 08812 p->subs[idx].f.src = "dahdi_exception"; 08813 p->subs[idx].f.data.ptr = NULL; 08814 08815 08816 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) { 08817 /* If nobody owns us, absorb the event appropriately, otherwise 08818 we loop indefinitely. This occurs when, during call waiting, the 08819 other end hangs up our channel so that it no longer exists, but we 08820 have neither FLASH'd nor ONHOOK'd to signify our desire to 08821 change to the other channel. */ 08822 if (p->fake_event) { 08823 res = p->fake_event; 08824 p->fake_event = 0; 08825 } else 08826 res = dahdi_get_event(p->subs[SUB_REAL].dfd); 08827 /* Switch to real if there is one and this isn't something really silly... */ 08828 if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) && 08829 (res != DAHDI_EVENT_HOOKCOMPLETE)) { 08830 ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res); 08831 p->owner = p->subs[SUB_REAL].owner; 08832 if (p->owner && ast_bridged_channel(p->owner)) 08833 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08834 p->subs[SUB_REAL].needunhold = 1; 08835 } 08836 switch (res) { 08837 case DAHDI_EVENT_ONHOOK: 08838 dahdi_disable_ec(p); 08839 if (p->owner) { 08840 ast_verb(3, "Channel %s still has call, ringing phone\n", p->owner->name); 08841 dahdi_ring_phone(p); 08842 p->callwaitingrepeat = 0; 08843 p->cidcwexpire = 0; 08844 p->cid_suppress_expire = 0; 08845 } else 08846 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 08847 update_conf(p); 08848 break; 08849 case DAHDI_EVENT_RINGOFFHOOK: 08850 dahdi_enable_ec(p); 08851 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 08852 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 08853 p->subs[SUB_REAL].needanswer = 1; 08854 p->dialing = 0; 08855 } 08856 break; 08857 case DAHDI_EVENT_HOOKCOMPLETE: 08858 case DAHDI_EVENT_RINGERON: 08859 case DAHDI_EVENT_RINGEROFF: 08860 /* Do nothing */ 08861 break; 08862 case DAHDI_EVENT_WINKFLASH: 08863 p->flashtime = ast_tvnow(); 08864 if (p->owner) { 08865 ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); 08866 if (p->owner->_state != AST_STATE_UP) { 08867 /* Answer if necessary */ 08868 usedindex = dahdi_get_index(p->owner, p, 0); 08869 if (usedindex > -1) { 08870 p->subs[usedindex].needanswer = 1; 08871 } 08872 ast_setstate(p->owner, AST_STATE_UP); 08873 } 08874 p->callwaitingrepeat = 0; 08875 p->cidcwexpire = 0; 08876 p->cid_suppress_expire = 0; 08877 if (ast_bridged_channel(p->owner)) 08878 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08879 p->subs[SUB_REAL].needunhold = 1; 08880 } else 08881 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 08882 update_conf(p); 08883 break; 08884 default: 08885 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 08886 } 08887 f = &p->subs[idx].f; 08888 return f; 08889 } 08890 if (!(p->radio || (p->oprmode < 0))) 08891 ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 08892 /* If it's not us, return NULL immediately */ 08893 if (ast != p->owner) { 08894 if (p->owner) { 08895 ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name); 08896 } 08897 f = &p->subs[idx].f; 08898 return f; 08899 } 08900 08901 f = dahdi_handle_event(ast); 08902 if (!f) { 08903 const char *name = ast_strdupa(ast->name); 08904 08905 /* Tell the CDR this DAHDI device hung up */ 08906 ast_mutex_unlock(&p->lock); 08907 ast_channel_unlock(ast); 08908 ast_set_hangupsource(ast, name, 0); 08909 ast_channel_lock(ast); 08910 ast_mutex_lock(&p->lock); 08911 } 08912 return f; 08913 }
| static int __unload_module | ( | void | ) | [static] |
Definition at line 16732 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(), destroy_all_channels(), sig_ss7_linkset::master, dahdi_pvt::next, dahdi_pvt::owner, sig_pri_stop_pri(), sig_pri_unload(), and SIG_SS7_NUM_DCHANS.
Referenced by load_module(), and unload_module().
16733 { 16734 struct dahdi_pvt *p; 16735 #if defined(HAVE_PRI) || defined(HAVE_SS7) 16736 int i, j; 16737 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 16738 16739 #ifdef HAVE_PRI 16740 for (i = 0; i < NUM_SPANS; i++) { 16741 if (pris[i].pri.master != AST_PTHREADT_NULL) { 16742 pthread_cancel(pris[i].pri.master); 16743 pthread_kill(pris[i].pri.master, SIGURG); 16744 } 16745 } 16746 ast_cli_unregister_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli)); 16747 ast_unregister_application(dahdi_send_keypad_facility_app); 16748 #ifdef HAVE_PRI_PROG_W_CAUSE 16749 ast_unregister_application(dahdi_send_callrerouting_facility_app); 16750 #endif 16751 #endif 16752 #if defined(HAVE_SS7) 16753 for (i = 0; i < NUM_SPANS; i++) { 16754 if (linksets[i].ss7.master != AST_PTHREADT_NULL) { 16755 pthread_cancel(linksets[i].ss7.master); 16756 pthread_kill(linksets[i].ss7.master, SIGURG); 16757 } 16758 } 16759 ast_cli_unregister_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli)); 16760 #endif /* defined(HAVE_SS7) */ 16761 #if defined(HAVE_OPENR2) 16762 dahdi_r2_destroy_links(); 16763 ast_cli_unregister_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli)); 16764 ast_unregister_application(dahdi_accept_r2_call_app); 16765 #endif 16766 16767 ast_cli_unregister_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli)); 16768 ast_manager_unregister("DAHDIDialOffhook"); 16769 ast_manager_unregister("DAHDIHangup"); 16770 ast_manager_unregister("DAHDITransfer"); 16771 ast_manager_unregister("DAHDIDNDoff"); 16772 ast_manager_unregister("DAHDIDNDon"); 16773 ast_manager_unregister("DAHDIShowChannels"); 16774 ast_manager_unregister("DAHDIRestart"); 16775 ast_data_unregister(NULL); 16776 ast_channel_unregister(&dahdi_tech); 16777 16778 /* Hangup all interfaces if they have an owner */ 16779 ast_mutex_lock(&iflock); 16780 for (p = iflist; p; p = p->next) { 16781 if (p->owner) 16782 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 16783 } 16784 ast_mutex_unlock(&iflock); 16785 16786 ast_mutex_lock(&monlock); 16787 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 16788 pthread_cancel(monitor_thread); 16789 pthread_kill(monitor_thread, SIGURG); 16790 pthread_join(monitor_thread, NULL); 16791 } 16792 monitor_thread = AST_PTHREADT_STOP; 16793 ast_mutex_unlock(&monlock); 16794 16795 destroy_all_channels(); 16796 16797 #if defined(HAVE_PRI) 16798 for (i = 0; i < NUM_SPANS; i++) { 16799 if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) { 16800 pthread_join(pris[i].pri.master, NULL); 16801 } 16802 for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) { 16803 dahdi_close_pri_fd(&(pris[i]), j); 16804 } 16805 sig_pri_stop_pri(&pris[i].pri); 16806 } 16807 #if defined(HAVE_PRI_CCSS) 16808 ast_cc_agent_unregister(&dahdi_pri_cc_agent_callbacks); 16809 ast_cc_monitor_unregister(&dahdi_pri_cc_monitor_callbacks); 16810 #endif /* defined(HAVE_PRI_CCSS) */ 16811 sig_pri_unload(); 16812 #endif 16813 16814 #if defined(HAVE_SS7) 16815 for (i = 0; i < NUM_SPANS; i++) { 16816 if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) { 16817 pthread_join(linksets[i].ss7.master, NULL); 16818 } 16819 for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) { 16820 dahdi_close_ss7_fd(&(linksets[i]), j); 16821 } 16822 } 16823 #endif /* defined(HAVE_SS7) */ 16824 ast_cond_destroy(&ss_thread_complete); 16825 return 0; 16826 }
| 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 3772 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, LOG_WARNING, dahdi_subchannel::owner, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, and dahdi_pvt::subs.
03773 { 03774 int res; 03775 if (p->subs[SUB_REAL].owner == ast) 03776 res = 0; 03777 else if (p->subs[SUB_CALLWAIT].owner == ast) 03778 res = 1; 03779 else if (p->subs[SUB_THREEWAY].owner == ast) 03780 res = 2; 03781 else { 03782 res = -1; 03783 if (!nullok) 03784 ast_log(LOG_WARNING, 03785 "Unable to get index for '%s' on channel %d (%s(), line %lu)\n", 03786 ast ? ast->name : "", p->channel, fname, line); 03787 } 03788 return res; 03789 }
| static int action_dahdidialoffhook | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 16047 of file chan_dahdi.c.
References AST_FRAME_DTMF, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_queue_frame(), find_channel_from_str(), and dahdi_pvt::owner.
Referenced by load_module().
16048 { 16049 struct dahdi_pvt *p; 16050 const char *channel = astman_get_header(m, "DAHDIChannel"); 16051 const char *number = astman_get_header(m, "Number"); 16052 int i; 16053 16054 if (ast_strlen_zero(channel)) { 16055 astman_send_error(s, m, "No channel specified"); 16056 return 0; 16057 } 16058 if (ast_strlen_zero(number)) { 16059 astman_send_error(s, m, "No number specified"); 16060 return 0; 16061 } 16062 p = find_channel_from_str(channel); 16063 if (!p) { 16064 astman_send_error(s, m, "No such channel"); 16065 return 0; 16066 } 16067 if (!p->owner) { 16068 astman_send_error(s, m, "Channel does not have it's owner"); 16069 return 0; 16070 } 16071 for (i = 0; i < strlen(number); i++) { 16072 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = number[i] }; 16073 dahdi_queue_frame(p, &f); 16074 } 16075 astman_send_ack(s, m, "DAHDIDialOffhook"); 16076 return 0; 16077 }
| static int action_dahdidndoff | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 15982 of file chan_dahdi.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_dnd(), and find_channel_from_str().
Referenced by load_module().
15983 { 15984 struct dahdi_pvt *p; 15985 const char *channel = astman_get_header(m, "DAHDIChannel"); 15986 15987 if (ast_strlen_zero(channel)) { 15988 astman_send_error(s, m, "No channel specified"); 15989 return 0; 15990 } 15991 p = find_channel_from_str(channel); 15992 if (!p) { 15993 astman_send_error(s, m, "No such channel"); 15994 return 0; 15995 } 15996 dahdi_dnd(p, 0); 15997 astman_send_ack(s, m, "DND Disabled"); 15998 return 0; 15999 }
| static int action_dahdidndon | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 15963 of file chan_dahdi.c.
References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_dnd(), and find_channel_from_str().
Referenced by load_module().
15964 { 15965 struct dahdi_pvt *p; 15966 const char *channel = astman_get_header(m, "DAHDIChannel"); 15967 15968 if (ast_strlen_zero(channel)) { 15969 astman_send_error(s, m, "No channel specified"); 15970 return 0; 15971 } 15972 p = find_channel_from_str(channel); 15973 if (!p) { 15974 astman_send_error(s, m, "No such channel"); 15975 return 0; 15976 } 15977 dahdi_dnd(p, 1); 15978 astman_send_ack(s, m, "DND Enabled"); 15979 return 0; 15980 }
| static int action_dahdirestart | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 15252 of file chan_dahdi.c.
References astman_send_ack(), astman_send_error(), and dahdi_restart().
Referenced by load_module().
15253 { 15254 if (dahdi_restart() != 0) { 15255 astman_send_error(s, m, "Failed rereading DAHDI configuration"); 15256 return 1; 15257 } 15258 astman_send_ack(s, m, "DAHDIRestart: Success"); 15259 return 0; 15260 }
| static int action_dahdishowchannels | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 16079 of file chan_dahdi.c.
References alarm2str(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), dahdi_pvt::channel, dahdi_pvt::context, dahdi_dnd(), get_alarms(), dahdi_pvt::next, dahdi_pvt::owner, dahdi_pvt::sig, and sig2str.
Referenced by load_module().
16080 { 16081 struct dahdi_pvt *tmp = NULL; 16082 const char *id = astman_get_header(m, "ActionID"); 16083 const char *dahdichannel = astman_get_header(m, "DAHDIChannel"); 16084 char idText[256] = ""; 16085 int channels = 0; 16086 int dahdichanquery; 16087 16088 if (!dahdichannel || sscanf(dahdichannel, "%30d", &dahdichanquery) != 1) { 16089 /* Not numeric string. */ 16090 dahdichanquery = -1; 16091 } 16092 16093 astman_send_ack(s, m, "DAHDI channel status will follow"); 16094 if (!ast_strlen_zero(id)) 16095 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 16096 16097 ast_mutex_lock(&iflock); 16098 16099 for (tmp = iflist; tmp; tmp = tmp->next) { 16100 if (tmp->channel > 0) { 16101 int alm; 16102 16103 /* If a specific channel is queried for, only deliver status for that channel */ 16104 if (dahdichanquery > 0 && tmp->channel != dahdichanquery) 16105 continue; 16106 16107 alm = get_alarms(tmp); 16108 channels++; 16109 if (tmp->owner) { 16110 /* Add data if we have a current call */ 16111 astman_append(s, 16112 "Event: DAHDIShowChannels\r\n" 16113 "DAHDIChannel: %d\r\n" 16114 "Channel: %s\r\n" 16115 "Uniqueid: %s\r\n" 16116 "AccountCode: %s\r\n" 16117 "Signalling: %s\r\n" 16118 "SignallingCode: %d\r\n" 16119 "Context: %s\r\n" 16120 "DND: %s\r\n" 16121 "Alarm: %s\r\n" 16122 "%s" 16123 "\r\n", 16124 tmp->channel, 16125 tmp->owner->name, 16126 tmp->owner->uniqueid, 16127 tmp->owner->accountcode, 16128 sig2str(tmp->sig), 16129 tmp->sig, 16130 tmp->context, 16131 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled", 16132 alarm2str(alm), idText); 16133 } else { 16134 astman_append(s, 16135 "Event: DAHDIShowChannels\r\n" 16136 "DAHDIChannel: %d\r\n" 16137 "Signalling: %s\r\n" 16138 "SignallingCode: %d\r\n" 16139 "Context: %s\r\n" 16140 "DND: %s\r\n" 16141 "Alarm: %s\r\n" 16142 "%s" 16143 "\r\n", 16144 tmp->channel, sig2str(tmp->sig), tmp->sig, 16145 tmp->context, 16146 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled", 16147 alarm2str(alm), idText); 16148 } 16149 } 16150 } 16151 16152 ast_mutex_unlock(&iflock); 16153 16154 astman_append(s, 16155 "Event: DAHDIShowChannelsComplete\r\n" 16156 "%s" 16157 "Items: %d\r\n" 16158 "\r\n", 16159 idText, 16160 channels); 16161 return 0; 16162 }
| static int action_transfer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 16001 of file chan_dahdi.c.
References analog_lib_handles(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_fake_event(), find_channel_from_str(), dahdi_pvt::sig, and TRANSFER.
Referenced by load_module().
16002 { 16003 struct dahdi_pvt *p; 16004 const char *channel = astman_get_header(m, "DAHDIChannel"); 16005 16006 if (ast_strlen_zero(channel)) { 16007 astman_send_error(s, m, "No channel specified"); 16008 return 0; 16009 } 16010 p = find_channel_from_str(channel); 16011 if (!p) { 16012 astman_send_error(s, m, "No such channel"); 16013 return 0; 16014 } 16015 if (!analog_lib_handles(p->sig, 0, 0)) { 16016 astman_send_error(s, m, "Channel signaling is not analog"); 16017 return 0; 16018 } 16019 dahdi_fake_event(p,TRANSFER); 16020 astman_send_ack(s, m, "DAHDITransfer"); 16021 return 0; 16022 }
| static int action_transferhangup | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 16024 of file chan_dahdi.c.
References analog_lib_handles(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_fake_event(), find_channel_from_str(), HANGUP, and dahdi_pvt::sig.
Referenced by load_module().
16025 { 16026 struct dahdi_pvt *p; 16027 const char *channel = astman_get_header(m, "DAHDIChannel"); 16028 16029 if (ast_strlen_zero(channel)) { 16030 astman_send_error(s, m, "No channel specified"); 16031 return 0; 16032 } 16033 p = find_channel_from_str(channel); 16034 if (!p) { 16035 astman_send_error(s, m, "No such channel"); 16036 return 0; 16037 } 16038 if (!analog_lib_handles(p->sig, 0, 0)) { 16039 astman_send_error(s, m, "Channel signaling is not analog"); 16040 return 0; 16041 } 16042 dahdi_fake_event(p,HANGUP); 16043 astman_send_ack(s, m, "DAHDIHangup"); 16044 return 0; 16045 }
| static char* alarm2str | ( | int | alm | ) | [static] |
Definition at line 4623 of file chan_dahdi.c.
References alarms, and ARRAY_LEN.
Referenced by action_dahdishowchannels(), and handle_alarms().
| static int alloc_sub | ( | struct dahdi_pvt * | p, | |
| int | x | |||
| ) | [static] |
Definition at line 4424 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, and dahdi_pvt::subs.
Referenced by analog_ss_thread(), dahdi_handle_event(), and my_allocate_sub().
04425 { 04426 struct dahdi_bufferinfo bi; 04427 int res; 04428 if (p->subs[x].dfd >= 0) { 04429 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel); 04430 return -1; 04431 } 04432 04433 p->subs[x].dfd = dahdi_open("/dev/dahdi/pseudo"); 04434 if (p->subs[x].dfd <= -1) { 04435 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 04436 return -1; 04437 } 04438 04439 res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi); 04440 if (!res) { 04441 bi.txbufpolicy = p->buf_policy; 04442 bi.rxbufpolicy = p->buf_policy; 04443 bi.numbufs = p->buf_no; 04444 res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi); 04445 if (res < 0) { 04446 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno)); 04447 } 04448 } else 04449 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno)); 04450 04451 if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) { 04452 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno)); 04453 dahdi_close_sub(p, x); 04454 p->subs[x].dfd = -1; 04455 return -1; 04456 } 04457 ast_debug(1, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan); 04458 return 0; 04459 }
| static int analog_lib_handles | ( | int | signalling, | |
| int | radio, | |||
| int | oprmode | |||
| ) | [static] |
Definition at line 1557 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_fixup(), dahdi_hangup(), dahdi_new(), dahdi_read(), dahdi_request(), destroy_dahdi_pvt(), do_monitor(), mkintf(), mwi_thread(), and my_get_sigpvt_bridged_channel().
01558 { 01559 switch (signalling) { 01560 case SIG_FXOLS: 01561 case SIG_FXOGS: 01562 case SIG_FXOKS: 01563 case SIG_FXSLS: 01564 case SIG_FXSGS: 01565 case SIG_FXSKS: 01566 case SIG_EMWINK: 01567 case SIG_EM: 01568 case SIG_EM_E1: 01569 case SIG_FEATD: 01570 case SIG_FEATDMF: 01571 case SIG_E911: 01572 case SIG_FGC_CAMA: 01573 case SIG_FGC_CAMAMF: 01574 case SIG_FEATB: 01575 case SIG_SFWINK: 01576 case SIG_SF: 01577 case SIG_SF_FEATD: 01578 case SIG_SF_FEATDMF: 01579 case SIG_FEATDMF_TA: 01580 case SIG_SF_FEATB: 01581 break; 01582 default: 01583 /* The rest of the function should cover the remainder of signalling types */ 01584 return 0; 01585 } 01586 01587 if (radio) { 01588 return 0; 01589 } 01590 01591 if (oprmode) { 01592 return 0; 01593 } 01594 01595 return 1; 01596 }
| static void * analog_ss_thread | ( | void * | data | ) | [static] |
Definition at line 9939 of file chan_dahdi.c.
References ast_channel::_state, alloc_sub(), ARRAY_LEN, ast_bridged_channel(), ast_canmatch_extension(), ast_clear_flag, ast_cond_signal, 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_remaining_ms(), ast_safe_sleep(), ast_set_callerid(), ast_set_flag, ast_setstate(), ast_shrink_phone_number(), ast_smdi_md_message_destroy(), ast_smdi_md_message_wait(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_streamfile(), ast_strlen_zero(), ast_tvnow(), ast_verb, ast_waitfor(), ast_waitfordigit(), ast_waitstream(), ASTOBJ_UNREF, 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, CID_START_RING, dahdi_pvt::context, ast_channel::context, ringContextData::contextData, dahdi_dnd(), dahdi_enable_ec(), dahdi_get_event(), dahdi_get_index, dahdi_set_hook(), dahdi_setlinear(), 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, ast_frame::frametype, ast_smdi_md_message::fwd_st, dahdi_pvt::hanguponpolarityswitch, dahdi_pvt::hardwaredtmf, dahdi_pvt::hidecallerid, ast_party_caller::id, dahdi_pvt::immediate, dahdi_pvt::inalarm, ast_frame_subclass::integer, ISTRUNK, len(), dahdi_subchannel::linear, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, my_getsigstr(), my_handle_notify_message(), ast_party_id::name, name, NEED_MFDETECT, ast_party_id::number, dahdi_pvt::owner, dahdi_subchannel::owner, pbx_builtin_setvar_helper(), dahdi_pvt::polarity, POLARITY_IDLE, POLARITY_REV, distRingData::range, restore_gains(), distRingData::ring, dahdi_distRings::ringContext, dahdi_distRings::ringnum, ast_channel::rings, dahdi_pvt::ringt, dahdi_pvt::ringt_base, S_COR, S_OR, 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_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, dahdi_pvt::smdi_iface, SMDI_MD_WAIT_TIMEOUT, ast_party_number::str, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, 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(), do_monitor(), handle_init_event(), and mwi_thread().
09940 { 09941 struct ast_channel *chan = data; 09942 struct dahdi_pvt *p = chan->tech_pvt; 09943 char exten[AST_MAX_EXTENSION] = ""; 09944 char exten2[AST_MAX_EXTENSION] = ""; 09945 unsigned char buf[256]; 09946 char dtmfcid[300]; 09947 char dtmfbuf[300]; 09948 struct callerid_state *cs = NULL; 09949 char *name = NULL, *number = NULL; 09950 int distMatches; 09951 int curRingData[3]; 09952 int receivedRingT; 09953 int counter1; 09954 int counter; 09955 int samples = 0; 09956 struct ast_smdi_md_message *smdi_msg = NULL; 09957 int flags = 0; 09958 int i; 09959 int timeout; 09960 int getforward = 0; 09961 char *s1, *s2; 09962 int len = 0; 09963 int res; 09964 int idx; 09965 09966 ast_mutex_lock(&ss_thread_lock); 09967 ss_thread_count++; 09968 ast_mutex_unlock(&ss_thread_lock); 09969 /* in the bizarre case where the channel has become a zombie before we 09970 even get started here, abort safely 09971 */ 09972 if (!p) { 09973 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name); 09974 ast_hangup(chan); 09975 goto quit; 09976 } 09977 ast_verb(3, "Starting simple switch on '%s'\n", chan->name); 09978 idx = dahdi_get_index(chan, p, 1); 09979 if (idx < 0) { 09980 ast_log(LOG_WARNING, "Huh?\n"); 09981 ast_hangup(chan); 09982 goto quit; 09983 } 09984 if (p->dsp) 09985 ast_dsp_digitreset(p->dsp); 09986 switch (p->sig) { 09987 case SIG_FEATD: 09988 case SIG_FEATDMF: 09989 case SIG_FEATDMF_TA: 09990 case SIG_E911: 09991 case SIG_FGC_CAMAMF: 09992 case SIG_FEATB: 09993 case SIG_EMWINK: 09994 case SIG_SF_FEATD: 09995 case SIG_SF_FEATDMF: 09996 case SIG_SF_FEATB: 09997 case SIG_SFWINK: 09998 if (dahdi_wink(p, idx)) 09999 goto quit; 10000 /* Fall through */ 10001 case SIG_EM: 10002 case SIG_EM_E1: 10003 case SIG_SF: 10004 case SIG_FGC_CAMA: 10005 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 10006 if (p->dsp) 10007 ast_dsp_digitreset(p->dsp); 10008 /* set digit mode appropriately */ 10009 if (p->dsp) { 10010 if (NEED_MFDETECT(p)) 10011 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 10012 else 10013 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 10014 } 10015 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 10016 /* Wait for the first digit only if immediate=no */ 10017 if (!p->immediate) 10018 /* Wait for the first digit (up to 5 seconds). */ 10019 res = ast_waitfordigit(chan, 5000); 10020 else 10021 res = 0; 10022 if (res > 0) { 10023 /* save first char */ 10024 dtmfbuf[0] = res; 10025 switch (p->sig) { 10026 case SIG_FEATD: 10027 case SIG_SF_FEATD: 10028 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 10029 if (res > 0) 10030 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 10031 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10032 break; 10033 case SIG_FEATDMF_TA: 10034 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10035 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10036 if (dahdi_wink(p, idx)) goto quit; 10037 dtmfbuf[0] = 0; 10038 /* Wait for the first digit (up to 5 seconds). */ 10039 res = ast_waitfordigit(chan, 5000); 10040 if (res <= 0) break; 10041 dtmfbuf[0] = res; 10042 /* fall through intentionally */ 10043 case SIG_FEATDMF: 10044 case SIG_E911: 10045 case SIG_FGC_CAMAMF: 10046 case SIG_SF_FEATDMF: 10047 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10048 /* if international caca, do it again to get real ANO */ 10049 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14)) 10050 { 10051 if (dahdi_wink(p, idx)) goto quit; 10052 dtmfbuf[0] = 0; 10053 /* Wait for the first digit (up to 5 seconds). */ 10054 res = ast_waitfordigit(chan, 5000); 10055 if (res <= 0) break; 10056 dtmfbuf[0] = res; 10057 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10058 } 10059 if (res > 0) { 10060 /* if E911, take off hook */ 10061 if (p->sig == SIG_E911) 10062 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 10063 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 10064 } 10065 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10066 break; 10067 case SIG_FEATB: 10068 case SIG_SF_FEATB: 10069 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10070 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10071 break; 10072 case SIG_EMWINK: 10073 /* if we received a '*', we are actually receiving Feature Group D 10074 dial syntax, so use that mode; otherwise, fall through to normal 10075 mode 10076 */ 10077 if (res == '*') { 10078 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 10079 if (res > 0) 10080 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 10081 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10082 break; 10083 } 10084 default: 10085 /* If we got the first digit, get the rest */ 10086 len = 1; 10087 dtmfbuf[len] = '\0'; 10088 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 10089 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 10090 timeout = matchdigittimeout; 10091 } else { 10092 timeout = gendigittimeout; 10093 } 10094 res = ast_waitfordigit(chan, timeout); 10095 if (res < 0) { 10096 ast_debug(1, "waitfordigit returned < 0...\n"); 10097 ast_hangup(chan); 10098 goto quit; 10099 } else if (res) { 10100 dtmfbuf[len++] = res; 10101 dtmfbuf[len] = '\0'; 10102 } else { 10103 break; 10104 } 10105 } 10106 break; 10107 } 10108 } 10109 if (res == -1) { 10110 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 10111 ast_hangup(chan); 10112 goto quit; 10113 } else if (res < 0) { 10114 ast_debug(1, "Got hung up before digits finished\n"); 10115 ast_hangup(chan); 10116 goto quit; 10117 } 10118 10119 if (p->sig == SIG_FGC_CAMA) { 10120 char anibuf[100]; 10121 10122 if (ast_safe_sleep(chan,1000) == -1) { 10123 ast_hangup(chan); 10124 goto quit; 10125 } 10126 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 10127 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 10128 res = my_getsigstr(chan, anibuf, "#", 10000); 10129 if ((res > 0) && (strlen(anibuf) > 2)) { 10130 if (anibuf[strlen(anibuf) - 1] == '#') 10131 anibuf[strlen(anibuf) - 1] = 0; 10132 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 10133 } 10134 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 10135 } 10136 10137 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 10138 if (ast_strlen_zero(exten)) 10139 ast_copy_string(exten, "s", sizeof(exten)); 10140 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 10141 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 10142 if (exten[0] == '*') { 10143 char *stringp=NULL; 10144 ast_copy_string(exten2, exten, sizeof(exten2)); 10145 /* Parse out extension and callerid */ 10146 stringp=exten2 +1; 10147 s1 = strsep(&stringp, "*"); 10148 s2 = strsep(&stringp, "*"); 10149 if (s2) { 10150 if (!ast_strlen_zero(p->cid_num)) 10151 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 10152 else 10153 ast_set_callerid(chan, s1, NULL, s1); 10154 ast_copy_string(exten, s2, sizeof(exten)); 10155 } else 10156 ast_copy_string(exten, s1, sizeof(exten)); 10157 } else if (p->sig == SIG_FEATD) 10158 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 10159 } 10160 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 10161 if (exten[0] == '*') { 10162 char *stringp=NULL; 10163 ast_copy_string(exten2, exten, sizeof(exten2)); 10164 /* Parse out extension and callerid */ 10165 stringp=exten2 +1; 10166 s1 = strsep(&stringp, "#"); 10167 s2 = strsep(&stringp, "#"); 10168 if (s2) { 10169 if (!ast_strlen_zero(p->cid_num)) 10170 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 10171 else 10172 if (*(s1 + 2)) 10173 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 10174 ast_copy_string(exten, s2 + 1, sizeof(exten)); 10175 } else 10176 ast_copy_string(exten, s1 + 2, sizeof(exten)); 10177 } else 10178 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 10179 } 10180 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) { 10181 if (exten[0] == '*') { 10182 char *stringp=NULL; 10183 ast_copy_string(exten2, exten, sizeof(exten2)); 10184 /* Parse out extension and callerid */ 10185 stringp=exten2 +1; 10186 s1 = strsep(&stringp, "#"); 10187 s2 = strsep(&stringp, "#"); 10188 if (s2 && (*(s2 + 1) == '0')) { 10189 if (*(s2 + 2)) 10190 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 10191 } 10192 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 10193 else ast_copy_string(exten, "911", sizeof(exten)); 10194 } else 10195 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 10196 } 10197 if (p->sig == SIG_FEATB) { 10198 if (exten[0] == '*') { 10199 char *stringp=NULL; 10200 ast_copy_string(exten2, exten, sizeof(exten2)); 10201 /* Parse out extension and callerid */ 10202 stringp=exten2 +1; 10203 s1 = strsep(&stringp, "#"); 10204 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 10205 } else 10206 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 10207 } 10208 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 10209 dahdi_wink(p, idx); 10210 /* some switches require a minimum guard time between 10211 the last FGD wink and something that answers 10212 immediately. This ensures it */ 10213 if (ast_safe_sleep(chan, 100)) { 10214 ast_hangup(chan); 10215 goto quit; 10216 } 10217 } 10218 dahdi_enable_ec(p); 10219 if (NEED_MFDETECT(p)) { 10220 if (p->dsp) { 10221 if (!p->hardwaredtmf) 10222 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 10223 else { 10224 ast_dsp_free(p->dsp); 10225 p->dsp = NULL; 10226 } 10227 } 10228 } 10229 10230 if (ast_exists_extension(chan, chan->context, exten, 1, 10231 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 10232 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 10233 if (p->dsp) ast_dsp_digitreset(p->dsp); 10234 res = ast_pbx_run(chan); 10235 if (res) { 10236 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 10237 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10238 } 10239 goto quit; 10240 } else { 10241 ast_verb(2, "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 10242 sleep(2); 10243 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_INFO); 10244 if (res < 0) 10245 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 10246 else 10247 sleep(1); 10248 res = ast_streamfile(chan, "ss-noservice", chan->language); 10249 if (res >= 0) 10250 ast_waitstream(chan, ""); 10251 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10252 ast_hangup(chan); 10253 goto quit; 10254 } 10255 break; 10256 case SIG_FXOLS: 10257 case SIG_FXOGS: 10258 case SIG_FXOKS: 10259 /* Read the first digit */ 10260 timeout = firstdigittimeout; 10261 /* If starting a threeway call, never timeout on the first digit so someone 10262 can use flash-hook as a "hold" feature */ 10263 if (p->subs[SUB_THREEWAY].owner) 10264 timeout = 999999; 10265 while (len < AST_MAX_EXTENSION-1) { 10266 /* Read digit unless it's supposed to be immediate, in which case the 10267 only answer is 's' */ 10268 if (p->immediate) 10269 res = 's'; 10270 else 10271 res = ast_waitfordigit(chan, timeout); 10272 timeout = 0; 10273 if (res < 0) { 10274 ast_debug(1, "waitfordigit returned < 0...\n"); 10275 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 10276 ast_hangup(chan); 10277 goto quit; 10278 } else if (res) { 10279 ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout); 10280 exten[len++]=res; 10281 exten[len] = '\0'; 10282 } 10283 if (!ast_ignore_pattern(chan->context, exten)) 10284 tone_zone_play_tone(p->subs[idx].dfd, -1); 10285 else 10286 tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE); 10287 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && !ast_parking_ext_valid(exten, chan, chan->context)) { 10288 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 10289 if (getforward) { 10290 /* Record this as the forwarding extension */ 10291 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 10292 ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 10293 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10294 if (res) 10295 break; 10296 usleep(500000); 10297 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 10298 sleep(1); 10299 memset(exten, 0, sizeof(exten)); 10300 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE); 10301 len = 0; 10302 getforward = 0; 10303 } else { 10304 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 10305 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 10306 if (!ast_strlen_zero(p->cid_num)) { 10307 if (!p->hidecallerid) 10308 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 10309 else 10310 ast_set_callerid(chan, NULL, NULL, p->cid_num); 10311 } 10312 if (!ast_strlen_zero(p->cid_name)) { 10313 if (!p->hidecallerid) 10314 ast_set_callerid(chan, NULL, p->cid_name, NULL); 10315 } 10316 ast_setstate(chan, AST_STATE_RING); 10317 dahdi_enable_ec(p); 10318 res = ast_pbx_run(chan); 10319 if (res) { 10320 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 10321 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10322 } 10323 goto quit; 10324 } 10325 } else { 10326 /* It's a match, but they just typed a digit, and there is an ambiguous match, 10327 so just set the timeout to matchdigittimeout and wait some more */ 10328 timeout = matchdigittimeout; 10329 } 10330 } else if (res == 0) { 10331 ast_debug(1, "not enough digits (and no ambiguous match)...\n"); 10332 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10333 dahdi_wait_event(p->subs[idx].dfd); 10334 ast_hangup(chan); 10335 goto quit; 10336 } else if (p->callwaiting && !strcmp(exten, "*70")) { 10337 ast_verb(3, "Disabling call waiting on %s\n", chan->name); 10338 /* Disable call waiting if enabled */ 10339 p->callwaiting = 0; 10340 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10341 if (res) { 10342 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 10343 chan->name, strerror(errno)); 10344 } 10345 len = 0; 10346 ioctl(p->subs[idx].dfd,DAHDI_CONFDIAG,&len); 10347 memset(exten, 0, sizeof(exten)); 10348 timeout = firstdigittimeout; 10349 10350 } else if (!strcmp(exten,ast_pickup_ext())) { 10351 /* Scan all channels and see if there are any 10352 * ringing channels that have call groups 10353 * that equal this channels pickup group 10354 */ 10355 if (idx == SUB_REAL) { 10356 /* Switch us from Third call to Call Wait */ 10357 if (p->subs[SUB_THREEWAY].owner) { 10358 /* If you make a threeway call and the *8# a call, it should actually 10359 look like a callwait */ 10360 alloc_sub(p, SUB_CALLWAIT); 10361 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 10362 unalloc_sub(p, SUB_THREEWAY); 10363 } 10364 dahdi_enable_ec(p); 10365 if (ast_pickup_call(chan)) { 10366 ast_debug(1, "No call pickup possible...\n"); 10367 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10368 dahdi_wait_event(p->subs[idx].dfd); 10369 } 10370 ast_hangup(chan); 10371 goto quit; 10372 } else { 10373 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 10374 ast_hangup(chan); 10375 goto quit; 10376 } 10377 10378 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 10379 ast_verb(3, "Disabling Caller*ID on %s\n", chan->name); 10380 /* Disable Caller*ID if enabled */ 10381 p->hidecallerid = 1; 10382 ast_party_number_free(&chan->caller.id.number); 10383 ast_party_number_init(&chan->caller.id.number); 10384 ast_party_name_free(&chan->caller.id.name); 10385 ast_party_name_init(&chan->caller.id.name); 10386 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10387 if (res) { 10388 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 10389 chan->name, strerror(errno)); 10390 } 10391 len = 0; 10392 memset(exten, 0, sizeof(exten)); 10393 timeout = firstdigittimeout; 10394 } else if (p->callreturn && !strcmp(exten, "*69")) { 10395 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10396 break; 10397 } else if (!strcmp(exten, "*78")) { 10398 dahdi_dnd(p, 1); 10399 /* Do not disturb */ 10400 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10401 getforward = 0; 10402 memset(exten, 0, sizeof(exten)); 10403 len = 0; 10404 } else if (!strcmp(exten, "*79")) { 10405 dahdi_dnd(p, 0); 10406 /* Do not disturb */ 10407 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10408 getforward = 0; 10409 memset(exten, 0, sizeof(exten)); 10410 len = 0; 10411 } else if (p->cancallforward && !strcmp(exten, "*72")) { 10412 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10413 getforward = 1; 10414 memset(exten, 0, sizeof(exten)); 10415 len = 0; 10416 } else if (p->cancallforward && !strcmp(exten, "*73")) { 10417 ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel); 10418 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10419 memset(p->call_forward, 0, sizeof(p->call_forward)); 10420 getforward = 0; 10421 memset(exten, 0, sizeof(exten)); 10422 len = 0; 10423 } else if ((p->transfer || p->canpark) && ast_parking_ext_valid(exten, chan, chan->context) && 10424 p->subs[SUB_THREEWAY].owner && 10425 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 10426 /* This is a three way call, the main call being a real channel, 10427 and we're parking the first call. */ 10428 ast_masq_park_call_exten(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), 10429 chan, exten, chan->context, 0, NULL); 10430 ast_verb(3, "Parking call to '%s'\n", chan->name); 10431 break; 10432 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 10433 ast_verb(3, "Enabling Caller*ID on %s\n", chan->name); 10434 /* Enable Caller*ID if enabled */ 10435 p->hidecallerid = 0; 10436 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 10437 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10438 if (res) { 10439 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 10440 chan->name, strerror(errno)); 10441 } 10442 len = 0; 10443 memset(exten, 0, sizeof(exten)); 10444 timeout = firstdigittimeout; 10445 } else if (!strcmp(exten, "*0")) { 10446 struct ast_channel *nbridge = 10447 p->subs[SUB_THREEWAY].owner; 10448 struct dahdi_pvt *pbridge = NULL; 10449 /* set up the private struct of the bridged one, if any */ 10450 if (nbridge && ast_bridged_channel(nbridge)) 10451 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 10452 if (nbridge && pbridge && 10453 (nbridge->tech == &dahdi_tech) && 10454 (ast_bridged_channel(nbridge)->tech == &dahdi_tech) && 10455 ISTRUNK(pbridge)) { 10456 int func = DAHDI_FLASH; 10457 /* Clear out the dial buffer */ 10458 p->dop.dialstr[0] = '\0'; 10459 /* flash hookswitch */ 10460 if ((ioctl(pbridge->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 10461 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 10462 nbridge->name, strerror(errno)); 10463 } 10464 swap_subs(p, SUB_REAL, SUB_THREEWAY); 10465 unalloc_sub(p, SUB_THREEWAY); 10466 p->owner = p->subs[SUB_REAL].owner; 10467 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 10468 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 10469 ast_hangup(chan); 10470 goto quit; 10471 } else { 10472 tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10473 dahdi_wait_event(p->subs[idx].dfd); 10474 tone_zone_play_tone(p->subs[idx].dfd, -1); 10475 swap_subs(p, SUB_REAL, SUB_THREEWAY); 10476 unalloc_sub(p, SUB_THREEWAY); 10477 p->owner = p->subs[SUB_REAL].owner; 10478 ast_hangup(chan); 10479 goto quit; 10480 } 10481 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, 10482 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)) 10483 && !canmatch_featurecode(exten)) { 10484 ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, 10485 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<Unknown Caller>"), 10486 chan->context); 10487 break; 10488 } 10489 if (!timeout) 10490 timeout = gendigittimeout; 10491 if (len && !ast_ignore_pattern(chan->context, exten)) 10492 tone_zone_play_tone(p->subs[idx].dfd, -1); 10493 } 10494 break; 10495 case SIG_FXSLS: 10496 case SIG_FXSGS: 10497 case SIG_FXSKS: 10498 /* check for SMDI messages */ 10499 if (p->use_smdi && p->smdi_iface) { 10500 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT); 10501 10502 if (smdi_msg != NULL) { 10503 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 10504 10505 if (smdi_msg->type == 'B') 10506 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 10507 else if (smdi_msg->type == 'N') 10508 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 10509 10510 ast_debug(1, "Received SMDI message on %s\n", chan->name); 10511 } else { 10512 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 10513 } 10514 } 10515 10516 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 10517 number = smdi_msg->calling_st; 10518 10519 /* If we want caller id, we're in a prering state due to a polarity reversal 10520 * and we're set to use a polarity reversal to trigger the start of caller id, 10521 * grab the caller id and wait for ringing to start... */ 10522 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && 10523 (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_POLARITY_IN || p->cid_start == CID_START_DTMF_NOALERT))) { 10524 /* If set to use DTMF CID signalling, listen for DTMF */ 10525 if (p->cid_signalling == CID_SIG_DTMF) { 10526 int k = 0; 10527 int off_ms; 10528 struct timeval start = ast_tvnow(); 10529 int ms; 10530 cs = NULL; 10531 ast_debug(1, "Receiving DTMF cid on channel %s\n", chan->name); 10532 dahdi_setlinear(p->subs[idx].dfd, 0); 10533 /* 10534 * We are the only party interested in the Rx stream since 10535 * we have not answered yet. We don't need or even want DTMF 10536 * emulation. The DTMF digits can come so fast that emulation 10537 * can drop some of them. 10538 */ 10539 ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); 10540 off_ms = 4000;/* This is a typical OFF time between rings. */ 10541 for (;;) { 10542 struct ast_frame *f; 10543 10544 ms = ast_remaining_ms(start, off_ms); 10545 res = ast_waitfor(chan, ms); 10546 if (res <= 0) { 10547 /* 10548 * We do not need to restore the dahdi_setlinear() 10549 * or AST_FLAG_END_DTMF_ONLY flag settings since we 10550 * are hanging up the channel. 10551 */ 10552 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 10553 "Exiting simple switch\n"); 10554 ast_hangup(chan); 10555 goto quit; 10556 } 10557 f = ast_read(chan); 10558 if (!f) 10559 break; 10560 if (f->frametype == AST_FRAME_DTMF) { 10561 if (k < ARRAY_LEN(dtmfbuf) - 1) { 10562 dtmfbuf[k++] = f->subclass.integer; 10563 } 10564 ast_debug(1, "CID got digit '%c'\n", f->subclass.integer); 10565 start = ast_tvnow(); 10566 } 10567 ast_frfree(f); 10568 if (chan->_state == AST_STATE_RING || 10569 chan->_state == AST_STATE_RINGING) 10570 break; /* Got ring */ 10571 } 10572 ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); 10573 dtmfbuf[k] = '\0'; 10574 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10575 /* Got cid and ring. */ 10576 ast_debug(1, "CID got string '%s'\n", dtmfbuf); 10577 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 10578 ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags); 10579 /* If first byte is NULL, we have no cid */ 10580 if (!ast_strlen_zero(dtmfcid)) 10581 number = dtmfcid; 10582 else 10583 number = NULL; 10584 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 10585 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 10586 cs = callerid_new(p->cid_signalling); 10587 if (cs) { 10588 int off_ms; 10589 struct timeval start; 10590 int ms; 10591 samples = 0; 10592 #if 1 10593 bump_gains(p); 10594 #endif 10595 /* Take out of linear mode for Caller*ID processing */ 10596 dahdi_setlinear(p->subs[idx].dfd, 0); 10597 10598 /* First we wait and listen for the Caller*ID */ 10599 for (;;) { 10600 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10601 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10602 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10603 callerid_free(cs); 10604 ast_hangup(chan); 10605 goto quit; 10606 } 10607 if (i & DAHDI_IOMUX_SIGEVENT) { 10608 res = dahdi_get_event(p->subs[idx].dfd); 10609 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10610 if (res == DAHDI_EVENT_NOALARM) { 10611 p->inalarm = 0; 10612 } 10613 10614 if (p->cid_signalling == CID_SIG_V23_JP) { 10615 if (res == DAHDI_EVENT_RINGBEGIN) { 10616 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 10617 usleep(1); 10618 } 10619 } else { 10620 res = 0; 10621 break; 10622 } 10623 } else if (i & DAHDI_IOMUX_READ) { 10624 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10625 if (res < 0) { 10626 if (errno != ELAST) { 10627 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10628 callerid_free(cs); 10629 ast_hangup(chan); 10630 goto quit; 10631 } 10632 break; 10633 } 10634 samples += res; 10635 10636 if (p->cid_signalling == CID_SIG_V23_JP) { 10637 res = callerid_feed_jp(cs, buf, res, AST_LAW(p)); 10638 } else { 10639 res = callerid_feed(cs, buf, res, AST_LAW(p)); 10640 } 10641 if (res < 0) { 10642 /* 10643 * The previous diagnostic message output likely 10644 * explains why it failed. 10645 */ 10646 ast_log(LOG_WARNING, 10647 "Failed to decode CallerID on channel '%s'\n", 10648 chan->name); 10649 break; 10650 } else if (res) 10651 break; 10652 else if (samples > (8000 * 10)) 10653 break; 10654 } 10655 } 10656 if (res == 1) { 10657 callerid_get(cs, &name, &number, &flags); 10658 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 10659 } 10660 10661 if (p->cid_signalling == CID_SIG_V23_JP) { 10662 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 10663 usleep(1); 10664 } 10665 10666 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 10667 start = ast_tvnow(); 10668 off_ms = 4000;/* This is a typical OFF time between rings. */ 10669 for (;;) { 10670 struct ast_frame *f; 10671 10672 ms = ast_remaining_ms(start, off_ms); 10673 res = ast_waitfor(chan, ms); 10674 if (res <= 0) { 10675 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 10676 "Exiting simple switch\n"); 10677 ast_hangup(chan); 10678 goto quit; 10679 } 10680 if (!(f = ast_read(chan))) { 10681 ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n"); 10682 ast_hangup(chan); 10683 goto quit; 10684 } 10685 ast_frfree(f); 10686 if (chan->_state == AST_STATE_RING || 10687 chan->_state == AST_STATE_RINGING) 10688 break; /* Got ring */ 10689 } 10690 10691 /* We must have a ring by now, so, if configured, lets try to listen for 10692 * distinctive ringing */ 10693 if (p->usedistinctiveringdetection) { 10694 len = 0; 10695 distMatches = 0; 10696 /* Clear the current ring data array so we don't have old data in it. */ 10697 for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++) 10698 curRingData[receivedRingT] = 0; 10699 receivedRingT = 0; 10700 counter = 0; 10701 counter1 = 0; 10702 /* Check to see if context is what it should be, if not set to be. */ 10703 if (strcmp(p->context,p->defcontext) != 0) { 10704 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 10705 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 10706 } 10707 10708 for (;;) { 10709 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10710 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10711 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10712 callerid_free(cs); 10713 ast_hangup(chan); 10714 goto quit; 10715 } 10716 if (i & DAHDI_IOMUX_SIGEVENT) { 10717 res = dahdi_get_event(p->subs[idx].dfd); 10718 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10719 if (res == DAHDI_EVENT_NOALARM) { 10720 p->inalarm = 0; 10721 } 10722 res = 0; 10723 /* Let us detect distinctive ring */ 10724 10725 curRingData[receivedRingT] = p->ringt; 10726 10727 if (p->ringt < p->ringt_base/2) 10728 break; 10729 /* Increment the ringT counter so we can match it against 10730 values in chan_dahdi.conf for distinctive ring */ 10731 if (++receivedRingT == ARRAY_LEN(curRingData)) 10732 break; 10733 } else if (i & DAHDI_IOMUX_READ) { 10734 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10735 if (res < 0) { 10736 if (errno != ELAST) { 10737 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10738 callerid_free(cs); 10739 ast_hangup(chan); 10740 goto quit; 10741 } 10742 break; 10743 } 10744 if (p->ringt > 0) { 10745 if (!(--p->ringt)) { 10746 res = -1; 10747 break; 10748 } 10749 } 10750 } 10751 } 10752 /* this only shows up if you have n of the dring patterns filled in */ 10753 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 10754 for (counter = 0; counter < 3; counter++) { 10755 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this 10756 channel */ 10757 distMatches = 0; 10758 for (counter1 = 0; counter1 < 3; counter1++) { 10759 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 10760 if (p->drings.ringnum[counter].ring[counter1] == -1) { 10761 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 10762 curRingData[counter1]); 10763 distMatches++; 10764 } else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 10765 curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 10766 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 10767 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 10768 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 10769 distMatches++; 10770 } 10771 } 10772 10773 if (distMatches == 3) { 10774 /* The ring matches, set the context to whatever is for distinctive ring.. */ 10775 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 10776 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 10777 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 10778 break; 10779 } 10780 } 10781 } 10782 /* Restore linear mode (if appropriate) for Caller*ID processing */ 10783 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10784 #if 1 10785 restore_gains(p); 10786 #endif 10787 } else 10788 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 10789 } else { 10790 ast_log(LOG_WARNING, "Channel %s in prering " 10791 "state, but I have nothing to do. " 10792 "Terminating simple switch, should be " 10793 "restarted by the actual ring.\n", 10794 chan->name); 10795 ast_hangup(chan); 10796 goto quit; 10797 } 10798 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 10799 if (p->cid_signalling == CID_SIG_DTMF) { 10800 int k = 0; 10801 int off_ms; 10802 struct timeval start; 10803 int ms; 10804 cs = NULL; 10805 dahdi_setlinear(p->subs[idx].dfd, 0); 10806 off_ms = 2000; 10807 start = ast_tvnow(); 10808 for (;;) { 10809 struct ast_frame *f; 10810 10811 ms = ast_remaining_ms(start, off_ms); 10812 res = ast_waitfor(chan, ms); 10813 if (res <= 0) { 10814 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 10815 "Exiting simple switch\n"); 10816 ast_hangup(chan); 10817 goto quit; 10818 } 10819 f = ast_read(chan); 10820 if (!f) { 10821 /* Hangup received waiting for DTMFCID. Exiting simple switch. */ 10822 ast_hangup(chan); 10823 goto quit; 10824 } 10825 if (f->frametype == AST_FRAME_DTMF) { 10826 dtmfbuf[k++] = f->subclass.integer; 10827 ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass.integer); 10828 start = ast_tvnow(); 10829 } 10830 ast_frfree(f); 10831 10832 if (p->ringt_base == p->ringt) 10833 break; 10834 } 10835 dtmfbuf[k] = '\0'; 10836 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10837 /* Got cid and ring. */ 10838 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 10839 ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 10840 dtmfcid, flags); 10841 /* If first byte is NULL, we have no cid */ 10842 if (!ast_strlen_zero(dtmfcid)) 10843 number = dtmfcid; 10844 else 10845 number = NULL; 10846 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 10847 } else { 10848 /* FSK Bell202 callerID */ 10849 cs = callerid_new(p->cid_signalling); 10850 if (cs) { 10851 #if 1 10852 bump_gains(p); 10853 #endif 10854 samples = 0; 10855 len = 0; 10856 distMatches = 0; 10857 /* Clear the current ring data array so we don't have old data in it. */ 10858 for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++) 10859 curRingData[receivedRingT] = 0; 10860 receivedRingT = 0; 10861 counter = 0; 10862 counter1 = 0; 10863 /* Check to see if context is what it should be, if not set to be. */ 10864 if (strcmp(p->context,p->defcontext) != 0) { 10865 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 10866 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 10867 } 10868 10869 /* Take out of linear mode for Caller*ID processing */ 10870 dahdi_setlinear(p->subs[idx].dfd, 0); 10871 for (;;) { 10872 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10873 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10874 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10875 callerid_free(cs); 10876 ast_hangup(chan); 10877 goto quit; 10878 } 10879 if (i & DAHDI_IOMUX_SIGEVENT) { 10880 res = dahdi_get_event(p->subs[idx].dfd); 10881 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10882 if (res == DAHDI_EVENT_NOALARM) { 10883 p->inalarm = 0; 10884 } 10885 /* If we get a PR event, they hung up while processing calerid */ 10886 if ( res == DAHDI_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) { 10887 ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel); 10888 p->polarity = POLARITY_IDLE; 10889 callerid_free(cs); 10890 ast_hangup(chan); 10891 goto quit; 10892 } 10893 res = 0; 10894 /* Let us detect callerid when the telco uses distinctive ring */ 10895 10896 curRingData[receivedRingT] = p->ringt; 10897 10898 if (p->ringt < p->ringt_base/2) 10899 break; 10900 /* Increment the ringT counter so we can match it against 10901 values in chan_dahdi.conf for distinctive ring */ 10902 if (++receivedRingT == ARRAY_LEN(curRingData)) 10903 break; 10904 } else if (i & DAHDI_IOMUX_READ) { 10905 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10906 if (res < 0) { 10907 if (errno != ELAST) { 10908 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10909 callerid_free(cs); 10910 ast_hangup(chan); 10911 goto quit; 10912 } 10913 break; 10914 } 10915 if (p->ringt > 0) { 10916 if (!(--p->ringt)) { 10917 res = -1; 10918 break; 10919 } 10920 } 10921 samples += res; 10922 res = callerid_feed(cs, buf, res, AST_LAW(p)); 10923 if (res < 0) { 10924 /* 10925 * The previous diagnostic message output likely 10926 * explains why it failed. 10927 */ 10928 ast_log(LOG_WARNING, 10929 "Failed to decode CallerID on channel '%s'\n", 10930 chan->name); 10931 break; 10932 } else if (res) 10933 break; 10934 else if (samples > (8000 * 10)) 10935 break; 10936 } 10937 } 10938 if (res == 1) { 10939 callerid_get(cs, &name, &number, &flags); 10940 ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 10941 } 10942 if (distinctiveringaftercid == 1) { 10943 /* Clear the current ring data array so we don't have old data in it. */ 10944 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) { 10945 curRingData[receivedRingT] = 0; 10946 } 10947 receivedRingT = 0; 10948 ast_verb(3, "Detecting post-CID distinctive ring\n"); 10949 for (;;) { 10950 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10951 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10952 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10953 callerid_free(cs); 10954 ast_hangup(chan); 10955 goto quit; 10956 } 10957 if (i & DAHDI_IOMUX_SIGEVENT) { 10958 res = dahdi_get_event(p->subs[idx].dfd); 10959 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10960 if (res == DAHDI_EVENT_NOALARM) { 10961 p->inalarm = 0; 10962 } 10963 res = 0; 10964 /* Let us detect callerid when the telco uses distinctive ring */ 10965 10966 curRingData[receivedRingT] = p->ringt; 10967 10968 if (p->ringt < p->ringt_base/2) 10969 break; 10970 /* Increment the ringT counter so we can match it against 10971 values in chan_dahdi.conf for distinctive ring */ 10972 if (++receivedRingT == ARRAY_LEN(curRingData)) 10973 break; 10974 } else if (i & DAHDI_IOMUX_READ) { 10975 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10976 if (res < 0) { 10977 if (errno != ELAST) { 10978 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10979 callerid_free(cs); 10980 ast_hangup(chan); 10981 goto quit; 10982 } 10983 break; 10984 } 10985 if (p->ringt > 0) { 10986 if (!(--p->ringt)) { 10987 res = -1; 10988 break; 10989 } 10990 } 10991 } 10992 } 10993 } 10994 if (p->usedistinctiveringdetection) { 10995 /* this only shows up if you have n of the dring patterns filled in */ 10996 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 10997 10998 for (counter = 0; counter < 3; counter++) { 10999 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this 11000 channel */ 11001 /* this only shows up if you have n of the dring patterns filled in */ 11002 ast_verb(3, "Checking %d,%d,%d\n", 11003 p->drings.ringnum[counter].ring[0], 11004 p->drings.ringnum[counter].ring[1], 11005 p->drings.ringnum[counter].ring[2]); 11006 distMatches = 0; 11007 for (counter1 = 0; counter1 < 3; counter1++) { 11008 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 11009 if (p->drings.ringnum[counter].ring[counter1] == -1) { 11010 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 11011 curRingData[counter1]); 11012 distMatches++; 11013 } 11014 else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 11015 curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 11016 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 11017 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 11018 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 11019 distMatches++; 11020 } 11021 } 11022 if (distMatches == 3) { 11023 /* The ring matches, set the context to whatever is for distinctive ring.. */ 11024 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 11025 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 11026 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 11027 break; 11028 } 11029 } 11030 } 11031 /* Restore linear mode (if appropriate) for Caller*ID processing */ 11032 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 11033 #if 1 11034 restore_gains(p); 11035 #endif 11036 if (res < 0) { 11037 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name); 11038 } 11039 } else 11040 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 11041 } 11042 } else 11043 cs = NULL; 11044 11045 if (number) 11046 ast_shrink_phone_number(number); 11047 ast_set_callerid(chan, number, name, number); 11048 11049 if (smdi_msg) 11050 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 11051 11052 if (cs) 11053 callerid_free(cs); 11054 11055 my_handle_notify_message(chan, p, flags, -1); 11056 11057 ast_setstate(chan, AST_STATE_RING); 11058 chan->rings = 1; 11059 p->ringt = p->ringt_base; 11060 res = ast_pbx_run(chan); 11061 if (res) { 11062 ast_hangup(chan); 11063 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 11064 } 11065 goto quit; 11066 default: 11067 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 11068 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 11069 if (res < 0) 11070 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 11071 } 11072 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 11073 if (res < 0) 11074 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 11075 ast_hangup(chan); 11076 quit: 11077 ast_mutex_lock(&ss_thread_lock); 11078 ss_thread_count--; 11079 ast_cond_signal(&ss_thread_complete); 11080 ast_mutex_unlock(&ss_thread_lock); 11081 return NULL; 11082 }
| static int analog_tone_to_dahditone | ( | enum analog_tone | tone | ) | [static] |
Definition at line 1649 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().
01650 { 01651 switch (tone) { 01652 case ANALOG_TONE_RINGTONE: 01653 return DAHDI_TONE_RINGTONE; 01654 case ANALOG_TONE_STUTTER: 01655 return DAHDI_TONE_STUTTER; 01656 case ANALOG_TONE_CONGESTION: 01657 return DAHDI_TONE_CONGESTION; 01658 case ANALOG_TONE_DIALTONE: 01659 return DAHDI_TONE_DIALTONE; 01660 case ANALOG_TONE_DIALRECALL: 01661 return DAHDI_TONE_DIALRECALL; 01662 case ANALOG_TONE_INFO: 01663 return DAHDI_TONE_INFO; 01664 default: 01665 return -1; 01666 } 01667 }
| static int analogsub_to_dahdisub | ( | enum analog_sub | analogsub | ) | [static] |
Definition at line 1669 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().
01670 { 01671 int index; 01672 01673 switch (analogsub) { 01674 case ANALOG_SUB_REAL: 01675 index = SUB_REAL; 01676 break; 01677 case ANALOG_SUB_CALLWAIT: 01678 index = SUB_CALLWAIT; 01679 break; 01680 case ANALOG_SUB_THREEWAY: 01681 index = SUB_THREEWAY; 01682 break; 01683 default: 01684 ast_log(LOG_ERROR, "Unidentified sub!\n"); 01685 index = SUB_REAL; 01686 } 01687 01688 return index; 01689 }
| AST_DATA_STRUCTURE | ( | dahdi_pvt | , | |
| DATA_EXPORT_DAHDI_PVT | ||||
| ) |
| AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
| AST_MODFLAG_LOAD_ORDER | , | |||
| tdesc | , | |||
| . | load = load_module, |
|||
| . | unload = unload_module, |
|||
| . | reload = reload, |
|||
| . | load_pri = AST_MODPRI_CHANNEL_DRIVER, |
|||
| . | nonoptreq = "res_smdi" | |||
| ) |
| AST_MUTEX_DEFINE_STATIC | ( | restart_lock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | ss_thread_lock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
| AST_MUTEX_DEFINE_STATIC | ( | iflock | ) |
Protect the interface list (of dahdi_pvt's).
| static int attempt_transfer | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7659 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, LOG_WARNING, dahdi_subchannel::owner, SUB_REAL, SUB_THREEWAY, dahdi_pvt::subs, swap_subs(), and unalloc_sub().
Referenced by dahdi_handle_event().
07660 { 07661 /* In order to transfer, we need at least one of the channels to 07662 actually be in a call bridge. We can't conference two applications 07663 together (but then, why would we want to?) */ 07664 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 07665 /* The three-way person we're about to transfer to could still be in MOH, so 07666 stop if now if appropriate */ 07667 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 07668 ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 07669 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 07670 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 07671 } 07672 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) { 07673 tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, DAHDI_TONE_RINGTONE); 07674 } 07675 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 07676 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 07677 ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name); 07678 return -1; 07679 } 07680 /* Orphan the channel after releasing the lock */ 07681 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 07682 unalloc_sub(p, SUB_THREEWAY); 07683 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 07684 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 07685 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 07686 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 07687 } 07688 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) { 07689 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 07690 } 07691 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 07692 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 07693 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name); 07694 return -1; 07695 } 07696 /* Three-way is now the REAL */ 07697 swap_subs(p, SUB_THREEWAY, SUB_REAL); 07698 ast_channel_unlock(p->subs[SUB_REAL].owner); 07699 unalloc_sub(p, SUB_THREEWAY); 07700 /* Tell the caller not to hangup */ 07701 return 1; 07702 } else { 07703 ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n", 07704 p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name); 07705 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 07706 return -1; 07707 } 07708 return 0; 07709 }
| static int available | ( | struct dahdi_pvt ** | pvt, | |
| int | is_specific_channel | |||
| ) | [static] |
Definition at line 13253 of file chan_dahdi.c.
References analog_available(), analog_lib_handles(), sig_pri_chan::chan_pvt, dahdi_pvt::inalarm, dahdi_pvt::locallyblocked, 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().
13254 { 13255 struct dahdi_pvt *p = *pvt; 13256 13257 if (p->inalarm) 13258 return 0; 13259 13260 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) 13261 return analog_available(p->sig_pvt); 13262 13263 switch (p->sig) { 13264 #if defined(HAVE_PRI) 13265 case SIG_PRI_LIB_HANDLE_CASES: 13266 { 13267 struct sig_pri_chan *pvt_chan; 13268 int res; 13269 13270 pvt_chan = p->sig_pvt; 13271 res = sig_pri_available(&pvt_chan, is_specific_channel); 13272 *pvt = pvt_chan->chan_pvt; 13273 return res; 13274 } 13275 #endif /* defined(HAVE_PRI) */ 13276 #if defined(HAVE_SS7) 13277 case SIG_SS7: 13278 return sig_ss7_available(p->sig_pvt); 13279 #endif /* defined(HAVE_SS7) */ 13280 default: 13281 break; 13282 } 13283 13284 if (p->locallyblocked || p->remotelyblocked) { 13285 return 0; 13286 } 13287 13288 /* If no owner definitely available */ 13289 if (!p->owner) { 13290 #ifdef HAVE_OPENR2 13291 /* Trust MFC/R2 */ 13292 if (p->mfcr2) { 13293 if (p->mfcr2call) { 13294 return 0; 13295 } else { 13296 return 1; 13297 } 13298 } 13299 #endif 13300 return 1; 13301 } 13302 13303 return 0; 13304 }
| static int build_channels | ( | struct dahdi_chan_conf * | conf, | |
| const char * | value, | |||
| int | reload, | |||
| int | lineno, | |||
| int * | found_pseudo | |||
| ) | [static] |
Definition at line 16867 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, LOG_ERROR, LOG_WARNING, mkintf(), parse_spanchan(), dahdi_pvt::sig, and sig2str.
Referenced by process_dahdi().
16868 { 16869 char *c, *chan; 16870 char *subdir; 16871 int x, start, finish; 16872 struct dahdi_pvt *tmp; 16873 16874 if ((reload == 0) && (conf->chan.sig < 0) && !conf->is_sig_auto) { 16875 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 16876 return -1; 16877 } 16878 16879 c = ast_strdupa(value); 16880 c = parse_spanchan(c, &subdir); 16881 16882 while ((chan = strsep(&c, ","))) { 16883 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) { 16884 /* Range */ 16885 } else if (sscanf(chan, "%30d", &start)) { 16886 /* Just one */ 16887 finish = start; 16888 } else if (!strcasecmp(chan, "pseudo")) { 16889 finish = start = CHAN_PSEUDO; 16890 if (found_pseudo) 16891 *found_pseudo = 1; 16892 } else { 16893 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan); 16894 return -1; 16895 } 16896 if (finish < start) { 16897 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 16898 x = finish; 16899 finish = start; 16900 start = x; 16901 } 16902 16903 for (x = start; x <= finish; x++) { 16904 char fn[PATH_MAX]; 16905 int real_channel = x; 16906 16907 if (!ast_strlen_zero(subdir)) { 16908 real_channel = device2chan(subdir, x, fn, sizeof(fn)); 16909 if (real_channel < 0) { 16910 if (conf->ignore_failed_channels) { 16911 ast_log(LOG_WARNING, "Failed configuring %s!%d, (got %d). But moving on to others.\n", 16912 subdir, x, real_channel); 16913 continue; 16914 } else { 16915 ast_log(LOG_ERROR, "Failed configuring %s!%d, (got %d).\n", 16916 subdir, x, real_channel); 16917 return -1; 16918 } 16919 } 16920 } 16921 tmp = mkintf(real_channel, conf, reload); 16922 16923 if (tmp) { 16924 ast_verb(3, "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", real_channel, sig2str(tmp->sig)); 16925 } else { 16926 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n", 16927 (reload == 1) ? "reconfigure" : "register", value); 16928 return -1; 16929 } 16930 } 16931 } 16932 16933 return 0; 16934 }
| static int bump_gains | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5138 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::cid_rxgain, dahdi_subchannel::dfd, 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().
05139 { 05140 int res; 05141 05142 /* Bump receive gain by value stored in cid_rxgain */ 05143 res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain + p->cid_rxgain, p->txgain, p->rxdrc, p->txdrc, p->law); 05144 if (res) { 05145 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno)); 05146 return -1; 05147 } 05148 05149 return 0; 05150 }
| static int calc_energy | ( | const unsigned char * | buf, | |
| int | len, | |||
| format_t | law | |||
| ) | [static] |
Definition at line 11090 of file chan_dahdi.c.
References AST_ALAW, AST_FORMAT_ULAW, and AST_MULAW.
Referenced by do_monitor(), and mwi_thread().
| static int canmatch_featurecode | ( | const char * | exten | ) | [static] |
Definition at line 9912 of file chan_dahdi.c.
References ast_pickup_ext(), and pickup_ext.
Referenced by analog_ss_thread().
09913 { 09914 int extlen = strlen(exten); 09915 const char *pickup_ext; 09916 if (!extlen) { 09917 return 1; 09918 } 09919 pickup_ext = ast_pickup_ext(); 09920 if (extlen < strlen(pickup_ext) && !strncmp(pickup_ext, exten, extlen)) { 09921 return 1; 09922 } 09923 /* hardcoded features are *60, *67, *69, *70, *72, *73, *78, *79, *82, *0 */ 09924 if (exten[0] == '*' && extlen < 3) { 09925 if (extlen == 1) { 09926 return 1; 09927 } 09928 /* "*0" should be processed before it gets here */ 09929 switch (exten[1]) { 09930 case '6': 09931 case '7': 09932 case '8': 09933 return 1; 09934 } 09935 } 09936 return 0; 09937 }
| static int check_for_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7711 of file chan_dahdi.c.
References ast_log(), ast_verb, dahdi_pvt::channel, dahdi_pvt::confno, dahdi_subchannel::curconf, dahdi_subchannel::dfd, errno, LOG_WARNING, dahdi_pvt::master, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_handle_event(), and my_check_for_conference().
07712 { 07713 struct dahdi_confinfo ci; 07714 /* Fine if we already have a master, etc */ 07715 if (p->master || (p->confno > -1)) 07716 return 0; 07717 memset(&ci, 0, sizeof(ci)); 07718 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) { 07719 ast_log(LOG_WARNING, "Failed to get conference info on channel %d: %s\n", p->channel, strerror(errno)); 07720 return 0; 07721 } 07722 /* If we have no master and don't have a confno, then 07723 if we're in a conference, it's probably a MeetMe room or 07724 some such, so don't let us 3-way out! */ 07725 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 07726 ast_verb(3, "Avoiding 3-way call when in an external conference\n"); 07727 return 1; 07728 } 07729 return 0; 07730 }
| static int conf_add | ( | struct dahdi_pvt * | p, | |
| struct dahdi_subchannel * | c, | |||
| int | index, | |||
| int | slavechannel | |||
| ) | [static] |
Definition at line 4708 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().
04709 { 04710 /* If the conference already exists, and we're already in it 04711 don't bother doing anything */ 04712 struct dahdi_confinfo zi; 04713 04714 memset(&zi, 0, sizeof(zi)); 04715 zi.chan = 0; 04716 04717 if (slavechannel > 0) { 04718 /* If we have only one slave, do a digital mon */ 04719 zi.confmode = DAHDI_CONF_DIGITALMON; 04720 zi.confno = slavechannel; 04721 } else { 04722 if (!idx) { 04723 /* Real-side and pseudo-side both participate in conference */ 04724 zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER | 04725 DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER; 04726 } else 04727 zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER; 04728 zi.confno = p->confno; 04729 } 04730 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode)) 04731 return 0; 04732 if (c->dfd < 0) 04733 return 0; 04734 if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) { 04735 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno)); 04736 return -1; 04737 } 04738 if (slavechannel < 1) { 04739 p->confno = zi.confno; 04740 } 04741 c->curconf = zi; 04742 ast_debug(1, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno); 04743 return 0; 04744 }
| static int conf_del | ( | struct dahdi_pvt * | p, | |
| struct dahdi_subchannel * | c, | |||
| int | index | |||
| ) | [static] |
Definition at line 4757 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().
04758 { 04759 struct dahdi_confinfo zi; 04760 if (/* Can't delete if there's no dfd */ 04761 (c->dfd < 0) || 04762 /* Don't delete from the conference if it's not our conference */ 04763 !isourconf(p, c) 04764 /* Don't delete if we don't think it's conferenced at all (implied) */ 04765 ) return 0; 04766 memset(&zi, 0, sizeof(zi)); 04767 if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) { 04768 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno)); 04769 return -1; 04770 } 04771 ast_debug(1, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno); 04772 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 04773 return 0; 04774 }
Definition at line 9577 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(), CHAN_PSEUDO, dahdi_pvt::channel, dahdi_pvt::cid_num, dahdi_pvt::cid_subaddr, dahdi_pvt::lock, dahdi_subchannel::owner, dahdi_pvt::span, and dahdi_pvt::subs.
Referenced by dahdi_cc_callback(), and dahdi_new().
09579 { 09580 struct ast_str *chan_name; 09581 int x, y; 09582 09583 /* Create the new channel name tail. */ 09584 if (!(chan_name = ast_str_create(32))) { 09585 return NULL; 09586 } 09587 if (i->channel == CHAN_PSEUDO) { 09588 ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random()); 09589 #if defined(HAVE_PRI) 09590 } else if (i->pri) { 09591 ast_mutex_lock(&i->pri->lock); 09592 y = ++i->pri->new_chan_seq; 09593 if (is_outgoing) { 09594 ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, address, y); 09595 address[0] = '\0'; 09596 } else if (ast_strlen_zero(i->cid_subaddr)) { 09597 /* Put in caller-id number only since there is no subaddress. */ 09598 ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, i->cid_num, y); 09599 } else { 09600 /* Put in caller-id number and subaddress. */ 09601 ast_str_set(&chan_name, 0, "i%d/%s:%s-%x", i->pri->span, i->cid_num, 09602 i->cid_subaddr, y); 09603 } 09604 ast_mutex_unlock(&i->pri->lock); 09605 #endif /* defined(HAVE_PRI) */ 09606 } else { 09607 y = 1; 09608 do { 09609 ast_str_set(&chan_name, 0, "%d-%d", i->channel, y); 09610 for (x = 0; x < 3; ++x) { 09611 if (i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name), 09612 i->subs[x].owner->name + 6)) { 09613 break; 09614 } 09615 } 09616 ++y; 09617 } while (x < 3); 09618 } 09619 return chan_name; 09620 }
| static void dahdi_ami_channel_event | ( | struct dahdi_pvt * | p, | |
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 2165 of file chan_dahdi.c.
References ast_manager_event, CHAN_PSEUDO, dahdi_pvt::channel, EVENT_FLAG_CALL, and dahdi_pvt::span.
Referenced by dahdi_new().
02166 { 02167 char ch_name[20]; 02168 02169 if (p->channel < CHAN_PSEUDO) { 02170 /* No B channel */ 02171 snprintf(ch_name, sizeof(ch_name), "no-media (%d)", p->channel); 02172 } else if (p->channel == CHAN_PSEUDO) { 02173 /* Pseudo channel */ 02174 strcpy(ch_name, "pseudo"); 02175 } else { 02176 /* Real channel */ 02177 snprintf(ch_name, sizeof(ch_name), "%d", p->channel); 02178 } 02179 ast_manager_event(chan, EVENT_FLAG_CALL, "DAHDIChannel", 02180 "Channel: %s\r\n" 02181 "Uniqueid: %s\r\n" 02182 "DAHDISpan: %d\r\n" 02183 "DAHDIChannel: %s\r\n", 02184 chan->name, 02185 chan->uniqueid, 02186 p->span, 02187 ch_name); 02188 }
| static int dahdi_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 6587 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_pvt::lock, LOG_DEBUG, LOG_WARNING, dahdi_pvt::oprmode, 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.
06588 { 06589 struct dahdi_pvt *p = ast->tech_pvt; 06590 int res = 0; 06591 int idx; 06592 ast_setstate(ast, AST_STATE_UP);/*! \todo XXX this is redundantly set by the analog and PRI submodules! */ 06593 ast_mutex_lock(&p->lock); 06594 idx = dahdi_get_index(ast, p, 0); 06595 if (idx < 0) 06596 idx = SUB_REAL; 06597 /* nothing to do if a radio channel */ 06598 if ((p->radio || (p->oprmode < 0))) { 06599 ast_mutex_unlock(&p->lock); 06600 return 0; 06601 } 06602 06603 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 06604 res = analog_answer(p->sig_pvt, ast); 06605 ast_mutex_unlock(&p->lock); 06606 return res; 06607 } 06608 06609 switch (p->sig) { 06610 #if defined(HAVE_PRI) 06611 case SIG_PRI_LIB_HANDLE_CASES: 06612 res = sig_pri_answer(p->sig_pvt, ast); 06613 break; 06614 #endif /* defined(HAVE_PRI) */ 06615 #if defined(HAVE_SS7) 06616 case SIG_SS7: 06617 res = sig_ss7_answer(p->sig_pvt, ast); 06618 break; 06619 #endif /* defined(HAVE_SS7) */ 06620 #ifdef HAVE_OPENR2 06621 case SIG_MFCR2: 06622 if (!p->mfcr2_call_accepted) { 06623 /* The call was not accepted on offer nor the user, so it must be accepted now before answering, 06624 openr2_chan_answer_call will be called when the callback on_call_accepted is executed */ 06625 p->mfcr2_answer_pending = 1; 06626 if (p->mfcr2_charge_calls) { 06627 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with charge before answering on chan %d\n", p->channel); 06628 openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE); 06629 } else { 06630 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with no charge before answering on chan %d\n", p->channel); 06631 openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE); 06632 } 06633 } else { 06634 ast_log(LOG_DEBUG, "Answering MFC/R2 call on chan %d\n", p->channel); 06635 dahdi_r2_answer(p); 06636 } 06637 break; 06638 #endif 06639 case 0: 06640 ast_mutex_unlock(&p->lock); 06641 return 0; 06642 default: 06643 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 06644 res = -1; 06645 break; 06646 } 06647 ast_mutex_unlock(&p->lock); 06648 return res; 06649 }
| 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 7234 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_remaining_ms(), AST_STATE_RINGING, ast_tvnow(), 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(), ast_channel::fds, ast_frame::frametype, dahdi_pvt::inconference, dahdi_subchannel::inthreeway, dahdi_pvt::lock, LOG_NOTICE, LOG_WARNING, dahdi_pvt::master, dahdi_subchannel::owner, dahdi_pvt::owner, dahdi_pvt::pulsedial, dahdi_pvt::sig, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, dahdi_pvt::subs, t1, ast_channel::tech_pvt, dahdi_pvt::transfer, and update_conf().
07235 { 07236 struct ast_channel *who; 07237 struct dahdi_pvt *p0, *p1, *op0, *op1; 07238 struct dahdi_pvt *master = NULL, *slave = NULL; 07239 struct ast_frame *f; 07240 int inconf = 0; 07241 int nothingok = 1; 07242 int ofd0, ofd1; 07243 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 07244 int os0 = -1, os1 = -1; 07245 int priority = 0; 07246 struct ast_channel *oc0, *oc1; 07247 enum ast_bridge_result res; 07248 struct timeval start = ast_tvnow(); 07249 #ifdef PRI_2BCT 07250 int triedtopribridge = 0; 07251 q931_call *q931c0; 07252 q931_call *q931c1; 07253 #endif 07254 07255 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 07256 There is code below to handle it properly until DTMF is actually seen, 07257 but due to currently unresolved issues it's ignored... 07258 */ 07259 07260 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 07261 return AST_BRIDGE_FAILED_NOWARN; 07262 07263 ast_channel_lock(c0); 07264 while (ast_channel_trylock(c1)) { 07265 CHANNEL_DEADLOCK_AVOIDANCE(c0); 07266 } 07267 07268 p0 = c0->tech_pvt; 07269 p1 = c1->tech_pvt; 07270 /* cant do pseudo-channels here */ 07271 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 07272 ast_channel_unlock(c0); 07273 ast_channel_unlock(c1); 07274 return AST_BRIDGE_FAILED_NOWARN; 07275 } 07276 07277 oi0 = dahdi_get_index(c0, p0, 0); 07278 oi1 = dahdi_get_index(c1, p1, 0); 07279 if ((oi0 < 0) || (oi1 < 0)) { 07280 ast_channel_unlock(c0); 07281 ast_channel_unlock(c1); 07282 return AST_BRIDGE_FAILED; 07283 } 07284 07285 op0 = p0 = c0->tech_pvt; 07286 op1 = p1 = c1->tech_pvt; 07287 ofd0 = c0->fds[0]; 07288 ofd1 = c1->fds[0]; 07289 oc0 = p0->owner; 07290 oc1 = p1->owner; 07291 07292 if (ast_mutex_trylock(&p0->lock)) { 07293 /* Don't block, due to potential for deadlock */ 07294 ast_channel_unlock(c0); 07295 ast_channel_unlock(c1); 07296 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 07297 return AST_BRIDGE_RETRY; 07298 } 07299 if (ast_mutex_trylock(&p1->lock)) { 07300 /* Don't block, due to potential for deadlock */ 07301 ast_mutex_unlock(&p0->lock); 07302 ast_channel_unlock(c0); 07303 ast_channel_unlock(c1); 07304 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 07305 return AST_BRIDGE_RETRY; 07306 } 07307 07308 if ((p0->callwaiting && p0->callwaitingcallerid) 07309 || (p1->callwaiting && p1->callwaitingcallerid)) { 07310 /* 07311 * Call Waiting Caller ID requires DTMF detection to know if it 07312 * can send the CID spill. 07313 * 07314 * For now, don't attempt to native bridge if either channel 07315 * needs DTMF detection. There is code below to handle it 07316 * properly until DTMF is actually seen, but due to currently 07317 * unresolved issues it's ignored... 07318 */ 07319 ast_mutex_unlock(&p0->lock); 07320 ast_mutex_unlock(&p1->lock); 07321 ast_channel_unlock(c0); 07322 ast_channel_unlock(c1); 07323 return AST_BRIDGE_FAILED_NOWARN; 07324 } 07325 07326 #if defined(HAVE_PRI) 07327 if ((dahdi_sig_pri_lib_handles(p0->sig) 07328 && ((struct sig_pri_chan *) p0->sig_pvt)->no_b_channel) 07329 || (dahdi_sig_pri_lib_handles(p1->sig) 07330 && ((struct sig_pri_chan *) p1->sig_pvt)->no_b_channel)) { 07331 /* 07332 * PRI nobch channels (hold and call waiting) are equivalent to 07333 * pseudo channels and cannot be done here. 07334 */ 07335 ast_mutex_unlock(&p0->lock); 07336 ast_mutex_unlock(&p1->lock); 07337 ast_channel_unlock(c0); 07338 ast_channel_unlock(c1); 07339 return AST_BRIDGE_FAILED_NOWARN; 07340 } 07341 #endif /* defined(HAVE_PRI) */ 07342 07343 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 07344 if (p0->owner && p1->owner) { 07345 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 07346 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 07347 master = p0; 07348 slave = p1; 07349 inconf = 1; 07350 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 07351 master = p1; 07352 slave = p0; 07353 inconf = 1; 07354 } else { 07355 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 07356 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 07357 p0->channel, 07358 oi0, (p0->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0, 07359 p0->subs[SUB_REAL].inthreeway, p0->channel, 07360 oi0, (p1->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0, 07361 p1->subs[SUB_REAL].inthreeway); 07362 } 07363 nothingok = 0; 07364 } 07365 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 07366 if (p1->subs[SUB_THREEWAY].inthreeway) { 07367 master = p1; 07368 slave = p0; 07369 nothingok = 0; 07370 } 07371 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 07372 if (p0->subs[SUB_THREEWAY].inthreeway) { 07373 master = p0; 07374 slave = p1; 07375 nothingok = 0; 07376 } 07377 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 07378 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 07379 don't put us in anything */ 07380 if (p1->subs[SUB_CALLWAIT].inthreeway) { 07381 master = p1; 07382 slave = p0; 07383 nothingok = 0; 07384 } 07385 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 07386 /* Same as previous */ 07387 if (p0->subs[SUB_CALLWAIT].inthreeway) { 07388 master = p0; 07389 slave = p1; 07390 nothingok = 0; 07391 } 07392 } 07393 ast_debug(1, "master: %d, slave: %d, nothingok: %d\n", 07394 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 07395 if (master && slave) { 07396 /* Stop any tones, or play ringtone as appropriate. If they're bridged 07397 in an active threeway call with a channel that is ringing, we should 07398 indicate ringing. */ 07399 if ((oi1 == SUB_THREEWAY) && 07400 p1->subs[SUB_THREEWAY].inthreeway && 07401 p1->subs[SUB_REAL].owner && 07402 p1->subs[SUB_REAL].inthreeway && 07403 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 07404 ast_debug(1, 07405 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n", 07406 p0->channel, oi0, c0->name, p1->channel, oi1, c1->name); 07407 tone_zone_play_tone(p0->subs[oi0].dfd, DAHDI_TONE_RINGTONE); 07408 os1 = p1->subs[SUB_REAL].owner->_state; 07409 } else { 07410 ast_debug(1, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n", 07411 p0->channel, oi0, c0->name, p1->channel, oi1, c1->name); 07412 tone_zone_play_tone(p0->subs[oi0].dfd, -1); 07413 } 07414 if ((oi0 == SUB_THREEWAY) && 07415 p0->subs[SUB_THREEWAY].inthreeway && 07416 p0->subs[SUB_REAL].owner && 07417 p0->subs[SUB_REAL].inthreeway && 07418 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 07419 ast_debug(1, 07420 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n", 07421 p1->channel, oi1, c1->name, p0->channel, oi0, c0->name); 07422 tone_zone_play_tone(p1->subs[oi1].dfd, DAHDI_TONE_RINGTONE); 07423 os0 = p0->subs[SUB_REAL].owner->_state; 07424 } else { 07425 ast_debug(1, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n", 07426 p1->channel, oi1, c1->name, p0->channel, oi0, c0->name); 07427 tone_zone_play_tone(p1->subs[oi1].dfd, -1); 07428 } 07429 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 07430 if (!p0->echocanbridged || !p1->echocanbridged) { 07431 /* Disable echo cancellation if appropriate */ 07432 dahdi_disable_ec(p0); 07433 dahdi_disable_ec(p1); 07434 } 07435 } 07436 dahdi_link(slave, master); 07437 master->inconference = inconf; 07438 } else if (!nothingok) 07439 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 07440 07441 update_conf(p0); 07442 update_conf(p1); 07443 t0 = p0->subs[SUB_REAL].inthreeway; 07444 t1 = p1->subs[SUB_REAL].inthreeway; 07445 07446 ast_mutex_unlock(&p0->lock); 07447 ast_mutex_unlock(&p1->lock); 07448 07449 ast_channel_unlock(c0); 07450 ast_channel_unlock(c1); 07451 07452 /* Native bridge failed */ 07453 if ((!master || !slave) && !nothingok) { 07454 dahdi_enable_ec(p0); 07455 dahdi_enable_ec(p1); 07456 return AST_BRIDGE_FAILED; 07457 } 07458 07459 ast_verb(3, "Native bridging %s and %s\n", c0->name, c1->name); 07460 07461 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 07462 disable_dtmf_detect(op0); 07463 07464 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 07465 disable_dtmf_detect(op1); 07466 07467 for (;;) { 07468 struct ast_channel *c0_priority[2] = {c0, c1}; 07469 struct ast_channel *c1_priority[2] = {c1, c0}; 07470 int ms; 07471 07472 /* Here's our main loop... Start by locking things, looking for private parts, 07473 and then balking if anything is wrong */ 07474 07475 ast_channel_lock(c0); 07476 while (ast_channel_trylock(c1)) { 07477 CHANNEL_DEADLOCK_AVOIDANCE(c0); 07478 } 07479 07480 p0 = c0->tech_pvt; 07481 p1 = c1->tech_pvt; 07482 07483 if (op0 == p0) 07484 i0 = dahdi_get_index(c0, p0, 1); 07485 if (op1 == p1) 07486 i1 = dahdi_get_index(c1, p1, 1); 07487 07488 ast_channel_unlock(c0); 07489 ast_channel_unlock(c1); 07490 ms = ast_remaining_ms(start, timeoutms); 07491 if (!ms || 07492 (op0 != p0) || 07493 (op1 != p1) || 07494 (ofd0 != c0->fds[0]) || 07495 (ofd1 != c1->fds[0]) || 07496 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 07497 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 07498 (oc0 != p0->owner) || 07499 (oc1 != p1->owner) || 07500 (t0 != p0->subs[SUB_REAL].inthreeway) || 07501 (t1 != p1->subs[SUB_REAL].inthreeway) || 07502 (oi0 != i0) || 07503 (oi1 != i1)) { 07504 ast_debug(1, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 07505 op0->channel, oi0, op1->channel, oi1); 07506 res = AST_BRIDGE_RETRY; 07507 goto return_from_bridge; 07508 } 07509 07510 #ifdef PRI_2BCT 07511 if (!triedtopribridge) { 07512 triedtopribridge = 1; 07513 if (p0->pri && p0->pri == p1->pri && p0->pri->transfer) { 07514 ast_mutex_lock(&p0->pri->lock); 07515 switch (p0->sig) { 07516 case SIG_PRI_LIB_HANDLE_CASES: 07517 q931c0 = ((struct sig_pri_chan *) (p0->sig_pvt))->call; 07518 break; 07519 default: 07520 q931c0 = NULL; 07521 break; 07522 } 07523 switch (p1->sig) { 07524 case SIG_PRI_LIB_HANDLE_CASES: 07525 q931c1 = ((struct sig_pri_chan *) (p1->sig_pvt))->call; 07526 break; 07527 default: 07528 q931c1 = NULL; 07529 break; 07530 } 07531 if (q931c0 && q931c1) { 07532 pri_channel_bridge(q931c0, q931c1); 07533 } 07534 ast_mutex_unlock(&p0->pri->lock); 07535 } 07536 } 07537 #endif 07538 07539 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &ms); 07540 if (!who) { 07541 ast_debug(1, "Ooh, empty read...\n"); 07542 continue; 07543 } 07544 f = ast_read(who); 07545 if (!f || (f->frametype == AST_FRAME_CONTROL)) { 07546 *fo = f; 07547 *rc = who; 07548 res = AST_BRIDGE_COMPLETE; 07549 goto return_from_bridge; 07550 } 07551 if (f->frametype == AST_FRAME_DTMF) { 07552 if ((who == c0) && p0->pulsedial) { 07553 ast_write(c1, f); 07554 } else if ((who == c1) && p1->pulsedial) { 07555 ast_write(c0, f); 07556 } else { 07557 *fo = f; 07558 *rc = who; 07559 res = AST_BRIDGE_COMPLETE; 07560 goto return_from_bridge; 07561 } 07562 } 07563 ast_frfree(f); 07564 07565 /* Swap who gets priority */ 07566 priority = !priority; 07567 } 07568 07569 return_from_bridge: 07570 if (op0 == p0) 07571 dahdi_enable_ec(p0); 07572 07573 if (op1 == p1) 07574 dahdi_enable_ec(p1); 07575 07576 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 07577 enable_dtmf_detect(op0); 07578 07579 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 07580 enable_dtmf_detect(op1); 07581 07582 dahdi_unlink(slave, master, 1); 07583 07584 return res; 07585 }
| static int dahdi_call | ( | struct ast_channel * | ast, | |
| char * | rdest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 5372 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_sig_pri_lib_handles(), dahdi_subchannel::dfd, 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_subchannel::needbusy, ast_party_id::number, dahdi_pvt::oprmode, dahdi_pvt::outgoing, dahdi_pvt::outsigmod, 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.
05373 { 05374 struct dahdi_pvt *p = ast->tech_pvt; 05375 int x, res, mysig; 05376 char dest[256]; /* must be same length as p->dialdest */ 05377 05378 ast_mutex_lock(&p->lock); 05379 ast_copy_string(dest, rdest, sizeof(dest)); 05380 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 05381 if ((ast->_state == AST_STATE_BUSY)) { 05382 p->subs[SUB_REAL].needbusy = 1; 05383 ast_mutex_unlock(&p->lock); 05384 return 0; 05385 } 05386 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 05387 ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast->name); 05388 ast_mutex_unlock(&p->lock); 05389 return -1; 05390 } 05391 p->waitingfordt.tv_sec = 0; 05392 p->dialednone = 0; 05393 if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */ 05394 { 05395 /* Special pseudo -- automatically up */ 05396 ast_setstate(ast, AST_STATE_UP); 05397 ast_mutex_unlock(&p->lock); 05398 return 0; 05399 } 05400 x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE; 05401 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x); 05402 if (res) 05403 ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno)); 05404 p->outgoing = 1; 05405 05406 if (IS_DIGITAL(ast->transfercapability)){ 05407 set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, p->rxdrc, p->txdrc, p->law); 05408 } else { 05409 set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law); 05410 } 05411 05412 #ifdef HAVE_PRI 05413 if (dahdi_sig_pri_lib_handles(p->sig)) { 05414 res = sig_pri_call(p->sig_pvt, ast, rdest, timeout, 05415 (p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW); 05416 ast_mutex_unlock(&p->lock); 05417 return res; 05418 } 05419 #endif 05420 05421 #if defined(HAVE_SS7) 05422 if (p->sig == SIG_SS7) { 05423 res = sig_ss7_call(p->sig_pvt, ast, rdest); 05424 ast_mutex_unlock(&p->lock); 05425 return res; 05426 } 05427 #endif /* defined(HAVE_SS7) */ 05428 05429 /* If this is analog signalling we can exit here */ 05430 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 05431 p->callwaitrings = 0; 05432 res = analog_call(p->sig_pvt, ast, rdest, timeout); 05433 ast_mutex_unlock(&p->lock); 05434 return res; 05435 } 05436 05437 mysig = p->outsigmod > -1 ? p->outsigmod : p->sig; 05438 switch (mysig) { 05439 case 0: 05440 /* Special pseudo -- automatically up*/ 05441 ast_setstate(ast, AST_STATE_UP); 05442 break; 05443 case SIG_MFCR2: 05444 break; 05445 default: 05446 ast_debug(1, "not yet implemented\n"); 05447 ast_mutex_unlock(&p->lock); 05448 return -1; 05449 } 05450 05451 #ifdef HAVE_OPENR2 05452 if (p->mfcr2) { 05453 openr2_calling_party_category_t chancat; 05454 int callres = 0; 05455 char *c, *l; 05456 05457 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ 05458 p->dialdest[0] = '\0'; 05459 05460 c = strchr(dest, '/'); 05461 if (c) { 05462 c++; 05463 } else { 05464 c = ""; 05465 } 05466 if (!p->hidecallerid) { 05467 l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL; 05468 } else { 05469 l = NULL; 05470 } 05471 if (strlen(c) < p->stripmsd) { 05472 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 05473 ast_mutex_unlock(&p->lock); 05474 return -1; 05475 } 05476 p->dialing = 1; 05477 chancat = dahdi_r2_get_channel_category(ast); 05478 callres = openr2_chan_make_call(p->r2chan, l, (c + p->stripmsd), chancat); 05479 if (-1 == callres) { 05480 ast_mutex_unlock(&p->lock); 05481 ast_log(LOG_ERROR, "unable to make new MFC/R2 call!\n"); 05482 return -1; 05483 } 05484 p->mfcr2_call_accepted = 0; 05485 p->mfcr2_progress = 0; 05486 ast_setstate(ast, AST_STATE_DIALING); 05487 } 05488 #endif /* HAVE_OPENR2 */ 05489 ast_mutex_unlock(&p->lock); 05490 return 0; 05491 }
| static int dahdi_callwait | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 5339 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().
05340 { 05341 struct dahdi_pvt *p = ast->tech_pvt; 05342 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 05343 if (p->cidspill) { 05344 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 05345 ast_free(p->cidspill); 05346 } 05347 05348 /* 05349 * SAS: Subscriber Alert Signal, 440Hz for 300ms 05350 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves 05351 */ 05352 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 05353 return -1; 05354 save_conference(p); 05355 /* Silence */ 05356 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 05357 if (!p->callwaitrings && p->callwaitingcallerid) { 05358 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 05359 p->callwaitcas = 1; 05360 p->cidlen = 2400 + 680 + READ_SIZE * 4; 05361 } else { 05362 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 05363 p->callwaitcas = 0; 05364 p->cidlen = 2400 + READ_SIZE * 4; 05365 } 05366 p->cidpos = 0; 05367 send_callerid(p); 05368 05369 return 0; 05370 }
| 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. |
This callback acts like a forked dial with all prongs of the fork busy. Essentially, for each channel that could have taken the call, indicate that it is busy.
| 0 | on success. | |
| -1 | on error. |
Definition at line 13918 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_starting_point::backwards, dahdi_pvt::cc_params, dahdi_starting_point::channelmatch, create_channel_name(), dahdi_sig_pri_lib_handles(), determine_starting_point(), dahdi_starting_point::groupmatch, HAVE_PRI, is_group_or_channel_match(), dahdi_pvt::next, dahdi_pvt::prev, dahdi_pvt::sig, dahdi_pvt::span, and dahdi_starting_point::span.
13919 { 13920 struct dahdi_pvt *p; 13921 struct dahdi_pvt *exitpvt; 13922 struct dahdi_starting_point start; 13923 int groupmatched = 0; 13924 int channelmatched = 0; 13925 13926 ast_mutex_lock(&iflock); 13927 p = determine_starting_point(dest, &start); 13928 if (!p) { 13929 ast_mutex_unlock(&iflock); 13930 return -1; 13931 } 13932 exitpvt = p; 13933 for (;;) { 13934 if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)) { 13935 /* We found a potential match. call the callback */ 13936 struct ast_str *device_name; 13937 char *dash; 13938 const char *monitor_type; 13939 char dialstring[AST_CHANNEL_NAME]; 13940 char full_device_name[AST_CHANNEL_NAME]; 13941 13942 switch (ast_get_cc_monitor_policy(p->cc_params)) { 13943 case AST_CC_MONITOR_NEVER: 13944 break; 13945 case AST_CC_MONITOR_NATIVE: 13946 case AST_CC_MONITOR_ALWAYS: 13947 case AST_CC_MONITOR_GENERIC: 13948 #if defined(HAVE_PRI) 13949 if (dahdi_sig_pri_lib_handles(p->sig)) { 13950 /* 13951 * ISDN is in a trunk busy condition so we need to monitor 13952 * the span congestion device state. 13953 */ 13954 snprintf(full_device_name, sizeof(full_device_name), 13955 "DAHDI/I%d/congestion", p->pri->span); 13956 } else 13957 #endif /* defined(HAVE_PRI) */ 13958 { 13959 #if defined(HAVE_PRI) 13960 device_name = create_channel_name(p, 1, ""); 13961 #else 13962 device_name = create_channel_name(p); 13963 #endif /* defined(HAVE_PRI) */ 13964 snprintf(full_device_name, sizeof(full_device_name), "DAHDI/%s", 13965 device_name ? ast_str_buffer(device_name) : ""); 13966 ast_free(device_name); 13967 /* 13968 * The portion after the '-' in the channel name is either a random 13969 * number, a sequence number, or a subchannel number. None are 13970 * necessary so strip them off. 13971 */ 13972 dash = strrchr(full_device_name, '-'); 13973 if (dash) { 13974 *dash = '\0'; 13975 } 13976 } 13977 snprintf(dialstring, sizeof(dialstring), "DAHDI/%s", dest); 13978 13979 /* 13980 * Analog can only do generic monitoring. 13981 * ISDN is in a trunk busy condition and any "device" is going 13982 * to be busy until a B channel becomes available. The generic 13983 * monitor can do this task. 13984 */ 13985 monitor_type = AST_CC_GENERIC_MONITOR_TYPE; 13986 callback(inbound, 13987 #if defined(HAVE_PRI) 13988 p->pri ? p->pri->cc_params : p->cc_params, 13989 #else 13990 p->cc_params, 13991 #endif /* defined(HAVE_PRI) */ 13992 monitor_type, full_device_name, dialstring, NULL); 13993 break; 13994 } 13995 } 13996 p = start.backwards ? p->prev : p->next; 13997 if (!p) { 13998 p = start.backwards ? ifend : iflist; 13999 } 14000 if (p == exitpvt) { 14001 break; 14002 } 14003 } 14004 ast_mutex_unlock(&iflock); 14005 return 0; 14006 }
| static struct dahdi_chan_conf dahdi_chan_conf_default | ( | void | ) | [static, read] |
returns a new dahdi_chan_conf with default values (by-value)
Definition at line 1355 of file chan_dahdi.c.
References ast_cc_config_params_init, CID_SIG_BELL, CID_START_RING, DAHDI_CHAN_MAPPING_PHYSICAL, and DEFAULT_CIDRINGS.
Referenced by process_dahdi(), and setup_dahdi().
01356 { 01357 /* recall that if a field is not included here it is initialized 01358 * to 0 or equivalent 01359 */ 01360 struct dahdi_chan_conf conf = { 01361 #ifdef HAVE_PRI 01362 .pri.pri = { 01363 .nsf = PRI_NSF_NONE, 01364 .switchtype = PRI_SWITCH_NI2, 01365 .dialplan = PRI_UNKNOWN + 1, 01366 .localdialplan = PRI_NATIONAL_ISDN + 1, 01367 .nodetype = PRI_CPE, 01368 .qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL, 01369 .inband_on_proceeding = 1, 01370 01371 #if defined(HAVE_PRI_CCSS) 01372 .cc_ptmp_recall_mode = 1,/* specificRecall */ 01373 .cc_qsig_signaling_link_req = 1,/* retain */ 01374 .cc_qsig_signaling_link_rsp = 1,/* retain */ 01375 #endif /* defined(HAVE_PRI_CCSS) */ 01376 01377 .minunused = 2, 01378 .idleext = "", 01379 .idledial = "", 01380 .internationalprefix = "", 01381 .nationalprefix = "", 01382 .localprefix = "", 01383 .privateprefix = "", 01384 .unknownprefix = "", 01385 .resetinterval = -1, 01386 }, 01387 #endif 01388 #if defined(HAVE_SS7) 01389 .ss7.ss7 = { 01390 .called_nai = SS7_NAI_NATIONAL, 01391 .calling_nai = SS7_NAI_NATIONAL, 01392 .internationalprefix = "", 01393 .nationalprefix = "", 01394 .subscriberprefix = "", 01395 .unknownprefix = "" 01396 }, 01397 #endif /* defined(HAVE_SS7) */ 01398 #ifdef HAVE_OPENR2 01399 .mfcr2 = { 01400 .variant = OR2_VAR_ITU, 01401 .mfback_timeout = -1, 01402 .metering_pulse_timeout = -1, 01403 .max_ani = 10, 01404 .max_dnis = 4, 01405 .get_ani_first = -1, 01406 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 01407 .skip_category_request = -1, 01408 #endif 01409 .call_files = 0, 01410 .allow_collect_calls = 0, 01411 .charge_calls = 1, 01412 .accept_on_offer = 1, 01413 .forced_release = 0, 01414 .double_answer = 0, 01415 .immediate_accept = -1, 01416 .logdir = "", 01417 .r2proto_file = "", 01418 .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING, 01419 .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER 01420 }, 01421 #endif 01422 .chan = { 01423 .context = "default", 01424 .cid_num = "", 01425 .cid_name = "", 01426 .cid_tag = "", 01427 .mohinterpret = "default", 01428 .mohsuggest = "", 01429 .parkinglot = "", 01430 .transfertobusy = 1, 01431 01432 .cid_signalling = CID_SIG_BELL, 01433 .cid_start = CID_START_RING, 01434 .dahditrcallerid = 0, 01435 .use_callerid = 1, 01436 .sig = -1, 01437 .outsigmod = -1, 01438 01439 .cid_rxgain = +5.0, 01440 01441 .tonezone = -1, 01442 01443 .echocancel.head.tap_length = 1, 01444 01445 .busycount = 3, 01446 01447 .accountcode = "", 01448 01449 .mailbox = "", 01450 01451 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 01452 .mwisend_fsk = 1, 01453 #endif 01454 .polarityonanswerdelay = 600, 01455 01456 .sendcalleridafter = DEFAULT_CIDRINGS, 01457 01458 .buf_policy = DAHDI_POLICY_IMMEDIATE, 01459 .buf_no = numbufs, 01460 .usefaxbuffers = 0, 01461 .cc_params = ast_cc_config_params_init(), 01462 }, 01463 .timing = { 01464 .prewinktime = -1, 01465 .preflashtime = -1, 01466 .winktime = -1, 01467 .flashtime = -1, 01468 .starttime = -1, 01469 .rxwinktime = -1, 01470 .rxflashtime = -1, 01471 .debouncetime = -1 01472 }, 01473 .is_sig_auto = 1, 01474 .smdi_port = "/dev/ttyS0", 01475 }; 01476 01477 return conf; 01478 }
| static int dahdi_channels_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 18518 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, and dahdi_pvt::next.
18520 { 18521 struct dahdi_pvt *tmp; 18522 struct ast_data *data_channel; 18523 18524 ast_mutex_lock(&iflock); 18525 for (tmp = iflist; tmp; tmp = tmp->next) { 18526 data_channel = ast_data_add_node(data_root, "channel"); 18527 if (!data_channel) { 18528 continue; 18529 } 18530 18531 ast_data_add_structure(dahdi_pvt, data_channel, tmp); 18532 18533 /* if this channel doesn't match remove it. */ 18534 if (!ast_data_search_match(search, data_channel)) { 18535 ast_data_remove_node(data_root, data_channel); 18536 } 18537 } 18538 ast_mutex_unlock(&iflock); 18539 18540 return 0; 18541 }
| static void dahdi_close | ( | int | fd | ) | [static] |
Definition at line 4390 of file chan_dahdi.c.
Referenced by dahdi_close_sub().
| static void dahdi_close_sub | ( | struct dahdi_pvt * | chan_pvt, | |
| int | sub_num | |||
| ) | [static] |
Definition at line 4396 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().
04397 { 04398 dahdi_close(chan_pvt->subs[sub_num].dfd); 04399 chan_pvt->subs[sub_num].dfd = -1; 04400 }
| static int dahdi_confmute | ( | struct dahdi_pvt * | p, | |
| int | muted | |||
| ) | [inline, static] |
Definition at line 5182 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, dahdi_subchannel::dfd, 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().
05183 { 05184 int x, res; 05185 05186 x = muted; 05187 #if defined(HAVE_PRI) || defined(HAVE_SS7) 05188 switch (p->sig) { 05189 #if defined(HAVE_PRI) 05190 case SIG_PRI_LIB_HANDLE_CASES: 05191 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 05192 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */ 05193 break; 05194 } 05195 /* Fall through */ 05196 #endif /* defined(HAVE_PRI) */ 05197 #if defined(HAVE_SS7) 05198 case SIG_SS7: 05199 #endif /* defined(HAVE_SS7) */ 05200 { 05201 int y = 1; 05202 05203 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y); 05204 if (res) 05205 ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n", 05206 p->channel, strerror(errno)); 05207 } 05208 break; 05209 default: 05210 break; 05211 } 05212 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 05213 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x); 05214 if (res < 0) 05215 ast_log(LOG_WARNING, "DAHDI confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno)); 05216 return res; 05217 }
| static char* dahdi_destroy_channel | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15066 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.
15067 { 15068 int channel; 15069 int ret; 15070 switch (cmd) { 15071 case CLI_INIT: 15072 e->command = "dahdi destroy channel"; 15073 e->usage = 15074 "Usage: dahdi destroy channel <chan num>\n" 15075 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n"; 15076 return NULL; 15077 case CLI_GENERATE: 15078 return NULL; 15079 } 15080 if (a->argc != 4) 15081 return CLI_SHOWUSAGE; 15082 15083 channel = atoi(a->argv[3]); 15084 ret = dahdi_destroy_channel_bynum(channel); 15085 return ( RESULT_SUCCESS == ret ) ? CLI_SUCCESS : CLI_FAILURE; 15086 }
| static int dahdi_destroy_channel_bynum | ( | int | channel | ) | [static] |
Definition at line 11440 of file chan_dahdi.c.
References ast_module_unref(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, destroy_channel(), dahdi_subchannel::dfd, dahdi_pvt::next, RESULT_FAILURE, RESULT_SUCCESS, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_destroy_channel(), and do_monitor().
11441 { 11442 struct dahdi_pvt *cur; 11443 11444 ast_mutex_lock(&iflock); 11445 for (cur = iflist; cur; cur = cur->next) { 11446 if (cur->channel == channel) { 11447 int x = DAHDI_FLASH; 11448 11449 /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */ 11450 ioctl(cur->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 11451 11452 destroy_channel(cur, 1); 11453 ast_mutex_unlock(&iflock); 11454 ast_module_unref(ast_module_info->self); 11455 return RESULT_SUCCESS; 11456 } 11457 } 11458 ast_mutex_unlock(&iflock); 11459 return RESULT_FAILURE; 11460 }
| static int dahdi_devicestate | ( | void * | data | ) | [static] |
Definition at line 13856 of file chan_dahdi.c.
References AST_DEVICE_UNKNOWN.
13857 { 13858 #if defined(HAVE_PRI) 13859 char *device; 13860 unsigned span; 13861 int res; 13862 13863 device = data; 13864 13865 if (*device != 'I') { 13866 /* The request is not for an ISDN span device. */ 13867 return AST_DEVICE_UNKNOWN; 13868 } 13869 res = sscanf(device, "I%30u", &span); 13870 if (res != 1 || !span || NUM_SPANS < span) { 13871 /* Bad format for ISDN span device name. */ 13872 return AST_DEVICE_UNKNOWN; 13873 } 13874 device = strchr(device, '/'); 13875 if (!device) { 13876 /* Bad format for ISDN span device name. */ 13877 return AST_DEVICE_UNKNOWN; 13878 } 13879 13880 /* 13881 * Since there are currently no other span devstate's defined, 13882 * it must be congestion. 13883 */ 13884 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER) 13885 ++device; 13886 if (!strcmp(device, "congestion")) 13887 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */ 13888 { 13889 return pris[span - 1].pri.congestion_devstate; 13890 } 13891 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER) 13892 else if (!strcmp(device, "threshold")) { 13893 return pris[span - 1].pri.threshold_devstate; 13894 } 13895 return AST_DEVICE_UNKNOWN; 13896 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */ 13897 #else 13898 return AST_DEVICE_UNKNOWN; 13899 #endif /* defined(HAVE_PRI) */ 13900 }
| static int dahdi_digit_begin | ( | struct ast_channel * | ast, | |
| char | digit | |||
| ) | [static] |
Definition at line 4494 of file chan_dahdi.c.
References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::begindigit, dahdi_get_index, dahdi_subchannel::dfd, dahdi_pvt::dialing, digit_to_dtmfindex(), errno, dahdi_pvt::lock, LOG_WARNING, dahdi_pvt::owner, dahdi_pvt::pulse, dahdi_pvt::sig, sig_pri_digit_begin(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SUB_REAL, dahdi_pvt::subs, and ast_channel::tech_pvt.
04495 { 04496 struct dahdi_pvt *pvt; 04497 int idx; 04498 int dtmf = -1; 04499 int res; 04500 04501 pvt = chan->tech_pvt; 04502 04503 ast_mutex_lock(&pvt->lock); 04504 04505 idx = dahdi_get_index(chan, pvt, 0); 04506 04507 if ((idx != SUB_REAL) || !pvt->owner) 04508 goto out; 04509 04510 #ifdef HAVE_PRI 04511 switch (pvt->sig) { 04512 case SIG_PRI_LIB_HANDLE_CASES: 04513 res = sig_pri_digit_begin(pvt->sig_pvt, chan, digit); 04514 if (!res) 04515 goto out; 04516 break; 04517 default: 04518 break; 04519 } 04520 #endif 04521 if ((dtmf = digit_to_dtmfindex(digit)) == -1) 04522 goto out; 04523 04524 if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) { 04525 struct dahdi_dialoperation zo = { 04526 .op = DAHDI_DIAL_OP_APPEND, 04527 }; 04528 04529 zo.dialstr[0] = 'T'; 04530 zo.dialstr[1] = digit; 04531 zo.dialstr[2] = '\0'; 04532 if ((res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo))) 04533 ast_log(LOG_WARNING, "Channel %s couldn't dial digit %c: %s\n", 04534 chan->name, digit, strerror(errno)); 04535 else 04536 pvt->dialing = 1; 04537 } else { 04538 ast_debug(1, "Channel %s started VLDTMF digit '%c'\n", 04539 chan->name, digit); 04540 pvt->dialing = 1; 04541 pvt->begindigit = digit; 04542 } 04543 04544 out: 04545 ast_mutex_unlock(&pvt->lock); 04546 04547 return 0; 04548 }
| static int dahdi_digit_end | ( | struct ast_channel * | ast, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Definition at line 4550 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_subchannel::dfd, dahdi_pvt::dialing, dahdi_pvt::lock, dahdi_pvt::owner, dahdi_pvt::pulse, dahdi_pvt::sig, SUB_REAL, dahdi_pvt::subs, and ast_channel::tech_pvt.
04551 { 04552 struct dahdi_pvt *pvt; 04553 int res = 0; 04554 int idx; 04555 int x; 04556 04557 pvt = chan->tech_pvt; 04558 04559 ast_mutex_lock(&pvt->lock); 04560 04561 idx = dahdi_get_index(chan, pvt, 0); 04562 04563 if ((idx != SUB_REAL) || !pvt->owner || pvt->pulse) 04564 goto out; 04565 04566 #ifdef HAVE_PRI 04567 /* This means that the digit was already sent via PRI signalling */ 04568 if (dahdi_sig_pri_lib_handles(pvt->sig) && !pvt->begindigit) { 04569 goto out; 04570 } 04571 #endif 04572 04573 if (pvt->begindigit) { 04574 x = -1; 04575 ast_debug(1, "Channel %s ending VLDTMF digit '%c'\n", 04576 chan->name, digit); 04577 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x); 04578 pvt->dialing = 0; 04579 pvt->begindigit = 0; 04580 } 04581 04582 out: 04583 ast_mutex_unlock(&pvt->lock); 04584 04585 return res; 04586 }
| static void dahdi_disable_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4962 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_pvt::channel, dahdi_subchannel::dfd, 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().
04963 { 04964 int res; 04965 04966 if (p->echocanon) { 04967 struct dahdi_echocanparams ecp = { .tap_length = 0 }; 04968 04969 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &ecp); 04970 04971 if (res) 04972 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno)); 04973 else 04974 ast_debug(1, "Disabled echo cancellation on channel %d\n", p->channel); 04975 } 04976 04977 p->echocanon = 0; 04978 }
| 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 |
chan_dahdi has a DND (Do Not Disturb) mode for each dahdichan (physical DAHDI channel). Use this to enable or disable it.
Definition at line 9889 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().
09890 { 09891 if (analog_lib_handles(dahdichan->sig, dahdichan->radio, dahdichan->oprmode)) { 09892 return analog_dnd(dahdichan->sig_pvt, flag); 09893 } 09894 09895 if (flag == -1) { 09896 return dahdichan->dnd; 09897 } 09898 09899 /* Do not disturb */ 09900 dahdichan->dnd = flag; 09901 ast_verb(3, "%s DND on channel %d\n", 09902 flag? "Enabled" : "Disabled", 09903 dahdichan->channel); 09904 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 09905 "Channel: DAHDI/%d\r\n" 09906 "Status: %s\r\n", dahdichan->channel, 09907 flag? "enabled" : "disabled"); 09908 09909 return 0; 09910 }
| static void dahdi_enable_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4890 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_pvt::channel, dahdi_subchannel::dfd, 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_setoption(), handle_init_event(), and my_set_echocanceller().
04891 { 04892 int res; 04893 if (!p) 04894 return; 04895 if (p->echocanon) { 04896 ast_debug(1, "Echo cancellation already on\n"); 04897 return; 04898 } 04899 if (p->digital) { 04900 ast_debug(1, "Echo cancellation isn't required on digital connection\n"); 04901 return; 04902 } 04903 if (p->echocancel.head.tap_length) { 04904 #if defined(HAVE_PRI) || defined(HAVE_SS7) 04905 switch (p->sig) { 04906 #if defined(HAVE_PRI) 04907 case SIG_PRI_LIB_HANDLE_CASES: 04908 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 04909 /* 04910 * PRI nobch pseudo channel. Does not need ec anyway. 04911 * Does not handle ioctl(DAHDI_AUDIOMODE) 04912 */ 04913 return; 04914 } 04915 /* Fall through */ 04916 #endif /* defined(HAVE_PRI) */ 04917 #if defined(HAVE_SS7) 04918 case SIG_SS7: 04919 #endif /* defined(HAVE_SS7) */ 04920 { 04921 int x = 1; 04922 04923 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x); 04924 if (res) 04925 ast_log(LOG_WARNING, 04926 "Unable to enable audio mode on channel %d (%s)\n", 04927 p->channel, strerror(errno)); 04928 } 04929 break; 04930 default: 04931 break; 04932 } 04933 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 04934 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &p->echocancel); 04935 if (res) { 04936 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno)); 04937 } else { 04938 p->echocanon = 1; 04939 ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel); 04940 } 04941 } else 04942 ast_debug(1, "No echo cancellation requested\n"); 04943 }
| static struct ast_frame * dahdi_exception | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 8915 of file chan_dahdi.c.
References __dahdi_exception(), analog_exception(), analog_lib_handles(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::lock, dahdi_pvt::oprmode, dahdi_pvt::radio, dahdi_pvt::sig, dahdi_pvt::sig_pvt, and ast_channel::tech_pvt.
08916 { 08917 struct dahdi_pvt *p = ast->tech_pvt; 08918 struct ast_frame *f; 08919 ast_mutex_lock(&p->lock); 08920 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 08921 struct analog_pvt *analog_p = p->sig_pvt; 08922 f = analog_exception(analog_p, ast); 08923 } else { 08924 f = __dahdi_exception(ast); 08925 } 08926 ast_mutex_unlock(&p->lock); 08927 return f; 08928 }
| static int dahdi_fake_event | ( | struct dahdi_pvt * | p, | |
| int | mode | |||
| ) | [static] |
Definition at line 15912 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::fake_event, HANGUP, LOG_WARNING, dahdi_pvt::owner, and TRANSFER.
Referenced by action_transfer(), and action_transferhangup().
15913 { 15914 if (p) { 15915 switch (mode) { 15916 case TRANSFER: 15917 p->fake_event = DAHDI_EVENT_WINKFLASH; 15918 break; 15919 case HANGUP: 15920 p->fake_event = DAHDI_EVENT_ONHOOK; 15921 break; 15922 default: 15923 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name); 15924 } 15925 } 15926 return 0; 15927 }
| static int dahdi_fixup | ( | struct ast_channel * | oldchan, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
Definition at line 7587 of file chan_dahdi.c.
References ast_channel::_state, analog_fixup(), analog_lib_handles(), AST_CONTROL_RINGING, ast_debug, ast_mutex_lock, ast_mutex_unlock, AST_STATE_RINGING, dahdi_pvt::channel, dahdi_indicate(), dahdi_sig_pri_lib_handles(), dahdi_unlink(), dahdi_pvt::lock, dahdi_pvt::oprmode, dahdi_subchannel::owner, dahdi_pvt::owner, dahdi_pvt::radio, dahdi_pvt::sig, sig_pri_fixup(), dahdi_pvt::sig_pvt, SIG_SS7, sig_ss7_fixup(), dahdi_pvt::subs, ast_channel::tech_pvt, and update_conf().
07588 { 07589 struct dahdi_pvt *p = newchan->tech_pvt; 07590 int x; 07591 07592 ast_mutex_lock(&p->lock); 07593 07594 ast_debug(1, "New owner for channel %d is %s\n", p->channel, newchan->name); 07595 if (p->owner == oldchan) { 07596 p->owner = newchan; 07597 } 07598 for (x = 0; x < 3; x++) { 07599 if (p->subs[x].owner == oldchan) { 07600 if (!x) { 07601 dahdi_unlink(NULL, p, 0); 07602 } 07603 p->subs[x].owner = newchan; 07604 } 07605 } 07606 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 07607 analog_fixup(oldchan, newchan, p->sig_pvt); 07608 #if defined(HAVE_PRI) 07609 } else if (dahdi_sig_pri_lib_handles(p->sig)) { 07610 sig_pri_fixup(oldchan, newchan, p->sig_pvt); 07611 #endif /* defined(HAVE_PRI) */ 07612 #if defined(HAVE_SS7) 07613 } else if (p->sig == SIG_SS7) { 07614 sig_ss7_fixup(oldchan, newchan, p->sig_pvt); 07615 #endif /* defined(HAVE_SS7) */ 07616 } 07617 update_conf(p); 07618 07619 ast_mutex_unlock(&p->lock); 07620 07621 if (newchan->_state == AST_STATE_RINGING) { 07622 dahdi_indicate(newchan, AST_CONTROL_RINGING, NULL, 0); 07623 } 07624 return 0; 07625 }
| static int dahdi_func_read | ( | struct ast_channel * | chan, | |
| const char * | function, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 6942 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.
06943 { 06944 struct dahdi_pvt *p = chan->tech_pvt; 06945 int res = 0; 06946 06947 if (!p) { 06948 /* No private structure! */ 06949 *buf = '\0'; 06950 return -1; 06951 } 06952 06953 if (!strcasecmp(data, "rxgain")) { 06954 ast_mutex_lock(&p->lock); 06955 snprintf(buf, len, "%f", p->rxgain); 06956 ast_mutex_unlock(&p->lock); 06957 } else if (!strcasecmp(data, "txgain")) { 06958 ast_mutex_lock(&p->lock); 06959 snprintf(buf, len, "%f", p->txgain); 06960 ast_mutex_unlock(&p->lock); 06961 } else if (!strcasecmp(data, "dahdi_channel")) { 06962 ast_mutex_lock(&p->lock); 06963 snprintf(buf, len, "%d", p->channel); 06964 ast_mutex_unlock(&p->lock); 06965 } else if (!strcasecmp(data, "dahdi_span")) { 06966 ast_mutex_lock(&p->lock); 06967 snprintf(buf, len, "%d", p->span); 06968 ast_mutex_unlock(&p->lock); 06969 } else if (!strcasecmp(data, "dahdi_type")) { 06970 ast_mutex_lock(&p->lock); 06971 switch (p->sig) { 06972 #if defined(HAVE_OPENR2) 06973 case SIG_MFCR2: 06974 ast_copy_string(buf, "mfc/r2", len); 06975 break; 06976 #endif /* defined(HAVE_OPENR2) */ 06977 #if defined(HAVE_PRI) 06978 case SIG_PRI_LIB_HANDLE_CASES: 06979 ast_copy_string(buf, "pri", len); 06980 break; 06981 #endif /* defined(HAVE_PRI) */ 06982 case 0: 06983 ast_copy_string(buf, "pseudo", len); 06984 break; 06985 #if defined(HAVE_SS7) 06986 case SIG_SS7: 06987 ast_copy_string(buf, "ss7", len); 06988 break; 06989 #endif /* defined(HAVE_SS7) */ 06990 default: 06991 /* The only thing left is analog ports. */ 06992 ast_copy_string(buf, "analog", len); 06993 break; 06994 } 06995 ast_mutex_unlock(&p->lock); 06996 #if defined(HAVE_PRI) 06997 #if defined(HAVE_PRI_REVERSE_CHARGE) 06998 } else if (!strcasecmp(data, "reversecharge")) { 06999 ast_mutex_lock(&p->lock); 07000 switch (p->sig) { 07001 case SIG_PRI_LIB_HANDLE_CASES: 07002 snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->reverse_charging_indication); 07003 break; 07004 default: 07005 *buf = '\0'; 07006 res = -1; 07007 break; 07008 } 07009 ast_mutex_unlock(&p->lock); 07010 #endif 07011 #if defined(HAVE_PRI_SETUP_KEYPAD) 07012 } else if (!strcasecmp(data, "keypad_digits")) { 07013 ast_mutex_lock(&p->lock); 07014 switch (p->sig) { 07015 case SIG_PRI_LIB_HANDLE_CASES: 07016 ast_copy_string(buf, ((struct sig_pri_chan *) p->sig_pvt)->keypad_digits, 07017 len); 07018 break; 07019 default: 07020 *buf = '\0'; 07021 res = -1; 07022 break; 07023 } 07024 ast_mutex_unlock(&p->lock); 07025 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 07026 } else if (!strcasecmp(data, "no_media_path")) { 07027 ast_mutex_lock(&p->lock); 07028 switch (p->sig) { 07029 case SIG_PRI_LIB_HANDLE_CASES: 07030 /* 07031 * TRUE if the call is on hold or is call waiting because 07032 * there is no media path available. 07033 */ 07034 snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel); 07035 break; 07036 default: 07037 *buf = '\0'; 07038 res = -1; 07039 break; 07040 } 07041 ast_mutex_unlock(&p->lock); 07042 #endif /* defined(HAVE_PRI) */ 07043 } else { 07044 *buf = '\0'; 07045 res = -1; 07046 } 07047 07048 return res; 07049 }
| static int dahdi_func_write | ( | struct ast_channel * | chan, | |
| const char * | function, | |||
| char * | data, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 7081 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_subchannel::dfd, dahdi_pvt::echocanon, errno, dahdi_pvt::lock, LOG_WARNING, parse_buffers_policy(), SUB_REAL, dahdi_pvt::subs, and ast_channel::tech_pvt.
07082 { 07083 struct dahdi_pvt *p = chan->tech_pvt; 07084 int res = 0; 07085 07086 if (!p) { 07087 /* No private structure! */ 07088 return -1; 07089 } 07090 07091 if (!strcasecmp(data, "buffers")) { 07092 int num_bufs, policy; 07093 07094 if (!(parse_buffers_policy(value, &num_bufs, &policy))) { 07095 struct dahdi_bufferinfo bi = { 07096 .txbufpolicy = policy, 07097 .rxbufpolicy = policy, 07098 .bufsize = p->bufsize, 07099 .numbufs = num_bufs, 07100 }; 07101 int bpres; 07102 07103 if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 07104 ast_log(LOG_WARNING, "Channel '%d' unable to override buffer policy: %s\n", p->channel, strerror(errno)); 07105 } else { 07106 p->bufferoverrideinuse = 1; 07107 } 07108 } else { 07109 res = -1; 07110 } 07111 } else if (!strcasecmp(data, "echocan_mode")) { 07112 if (!strcasecmp(value, "on")) { 07113 ast_mutex_lock(&p->lock); 07114 dahdi_enable_ec(p); 07115 ast_mutex_unlock(&p->lock); 07116 } else if (!strcasecmp(value, "off")) { 07117 ast_mutex_lock(&p->lock); 07118 dahdi_disable_ec(p); 07119 ast_mutex_unlock(&p->lock); 07120 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 07121 } else if (!strcasecmp(value, "fax")) { 07122 int blah = 1; 07123 07124 ast_mutex_lock(&p->lock); 07125 if (!p->echocanon) { 07126 dahdi_enable_ec(p); 07127 } 07128 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) { 07129 ast_log(LOG_WARNING, "Unable to place echocan into fax mode on channel %d: %s\n", p->channel, strerror(errno)); 07130 } 07131 ast_mutex_unlock(&p->lock); 07132 } else if (!strcasecmp(value, "voice")) { 07133 int blah = 0; 07134 07135 ast_mutex_lock(&p->lock); 07136 if (!p->echocanon) { 07137 dahdi_enable_ec(p); 07138 } 07139 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) { 07140 ast_log(LOG_WARNING, "Unable to place echocan into voice mode on channel %d: %s\n", p->channel, strerror(errno)); 07141 } 07142 ast_mutex_unlock(&p->lock); 07143 #endif 07144 } else { 07145 ast_log(LOG_WARNING, "Unsupported value '%s' provided for '%s' item.\n", value, data); 07146 res = -1; 07147 } 07148 } else { 07149 res = -1; 07150 } 07151 07152 return res; 07153 }
| static int dahdi_get_event | ( | int | fd | ) | [inline, static] |
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition at line 495 of file chan_dahdi.c.
Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_handle_event(), do_monitor(), mwi_thread(), my_distinctive_ring(), my_get_callerid(), and my_get_event().
| static void dahdi_handle_dtmf | ( | struct ast_channel * | ast, | |
| int | idx, | |||
| struct ast_frame ** | dest | |||
| ) | [static] |
Definition at line 7764 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, 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_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().
07765 { 07766 struct dahdi_pvt *p = ast->tech_pvt; 07767 struct ast_frame *f = *dest; 07768 07769 ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n", 07770 f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End", 07771 f->subclass.integer, f->subclass.integer, ast->name); 07772 07773 if (p->confirmanswer) { 07774 if (f->frametype == AST_FRAME_DTMF_END) { 07775 ast_debug(1, "Confirm answer on %s!\n", ast->name); 07776 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 07777 of a DTMF digit */ 07778 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 07779 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 07780 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 07781 p->confirmanswer = 0; 07782 } else { 07783 p->subs[idx].f.frametype = AST_FRAME_NULL; 07784 p->subs[idx].f.subclass.integer = 0; 07785 } 07786 *dest = &p->subs[idx].f; 07787 } else if (p->callwaitcas) { 07788 if (f->frametype == AST_FRAME_DTMF_END) { 07789 if ((f->subclass.integer == 'A') || (f->subclass.integer == 'D')) { 07790 ast_debug(1, "Got some DTMF, but it's for the CAS\n"); 07791 ast_free(p->cidspill); 07792 p->cidspill = NULL; 07793 send_cwcidspill(p); 07794 } 07795 p->callwaitcas = 0; 07796 } 07797 p->subs[idx].f.frametype = AST_FRAME_NULL; 07798 p->subs[idx].f.subclass.integer = 0; 07799 *dest = &p->subs[idx].f; 07800 } else if (f->subclass.integer == 'f') { 07801 if (f->frametype == AST_FRAME_DTMF_END) { 07802 /* Fax tone -- Handle and return NULL */ 07803 if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) { 07804 /* If faxbuffers are configured, use them for the fax transmission */ 07805 if (p->usefaxbuffers && !p->bufferoverrideinuse) { 07806 struct dahdi_bufferinfo bi = { 07807 .txbufpolicy = p->faxbuf_policy, 07808 .bufsize = p->bufsize, 07809 .numbufs = p->faxbuf_no 07810 }; 07811 int res; 07812 07813 if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 07814 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast->name, strerror(errno)); 07815 } else { 07816 p->bufferoverrideinuse = 1; 07817 } 07818 } 07819 p->faxhandled = 1; 07820 if (p->dsp) { 07821 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 07822 ast_dsp_set_features(p->dsp, p->dsp_features); 07823 ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast->name); 07824 } 07825 if (strcmp(ast->exten, "fax")) { 07826 const char *target_context = S_OR(ast->macrocontext, ast->context); 07827 07828 /* We need to unlock 'ast' here because ast_exists_extension has the 07829 * potential to start autoservice on the channel. Such action is prone 07830 * to deadlock. 07831 */ 07832 ast_mutex_unlock(&p->lock); 07833 ast_channel_unlock(ast); 07834 if (ast_exists_extension(ast, target_context, "fax", 1, 07835 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 07836 ast_channel_lock(ast); 07837 ast_mutex_lock(&p->lock); 07838 ast_verb(3, "Redirecting %s to fax extension\n", ast->name); 07839 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 07840 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 07841 if (ast_async_goto(ast, target_context, "fax", 1)) 07842 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 07843 } else { 07844 ast_channel_lock(ast); 07845 ast_mutex_lock(&p->lock); 07846 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 07847 } 07848 } else { 07849 ast_debug(1, "Already in a fax extension, not redirecting\n"); 07850 } 07851 } else { 07852 ast_debug(1, "Fax already handled\n"); 07853 } 07854 dahdi_confmute(p, 0); 07855 } 07856 p->subs[idx].f.frametype = AST_FRAME_NULL; 07857 p->subs[idx].f.subclass.integer = 0; 07858 *dest = &p->subs[idx].f; 07859 } 07860 }
| static struct ast_frame* dahdi_handle_event | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 7890 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, dahdi_pvt::callprogress, CALLPROGRESS_PROGRESS, dahdi_pvt::callwaitcas, dahdi_pvt::callwaitingrepeat, CANPROGRESSDETECT, dahdi_pvt::channel, CHANNEL_DEADLOCK_AVOIDANCE, check_for_conference(), dahdi_pvt::cid_name, cid_name, dahdi_pvt::cid_num, cid_num, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cidcwexpire, 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::dialednone, dahdi_pvt::dialing, DLA_LOCK, DLA_UNLOCK, dahdi_pvt::dop, dahdi_pvt::dsp, dahdi_pvt::echobreak, dahdi_pvt::echocanon, dahdi_pvt::echorest, dahdi_pvt::echotraining, errno, event2str(), dahdi_subchannel::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, LOG_WARNING, ast_frame::mallocd, MIN_MS_SINCE_FLASH, dahdi_pvt::mohsuggest, ast_party_id::name, dahdi_subchannel::needanswer, 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, dahdi_pvt::owner, dahdi_subchannel::owner, ast_channel::pbx, dahdi_pvt::polarity, POLARITY_IDLE, POLARITY_REV, dahdi_pvt::polaritydelaytv, dahdi_pvt::polarityonanswerdelay, ast_frame::ptr, dahdi_pvt::pulsedial, 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().
07891 { 07892 int res, x; 07893 int idx, mysig; 07894 char *c; 07895 struct dahdi_pvt *p = ast->tech_pvt; 07896 pthread_t threadid; 07897 struct ast_channel *chan; 07898 struct ast_frame *f; 07899 07900 idx = dahdi_get_index(ast, p, 0); 07901 if (idx < 0) { 07902 return &ast_null_frame; 07903 } 07904 mysig = p->sig; 07905 if (p->outsigmod > -1) 07906 mysig = p->outsigmod; 07907 p->subs[idx].f.frametype = AST_FRAME_NULL; 07908 p->subs[idx].f.subclass.integer = 0; 07909 p->subs[idx].f.datalen = 0; 07910 p->subs[idx].f.samples = 0; 07911 p->subs[idx].f.mallocd = 0; 07912 p->subs[idx].f.offset = 0; 07913 p->subs[idx].f.src = "dahdi_handle_event"; 07914 p->subs[idx].f.data.ptr = NULL; 07915 f = &p->subs[idx].f; 07916 07917 if (p->fake_event) { 07918 res = p->fake_event; 07919 p->fake_event = 0; 07920 } else 07921 res = dahdi_get_event(p->subs[idx].dfd); 07922 07923 ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, idx); 07924 07925 if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) { 07926 p->pulsedial = (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0; 07927 ast_debug(1, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 07928 #if defined(HAVE_PRI) 07929 if (dahdi_sig_pri_lib_handles(p->sig) 07930 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING 07931 && p->pri 07932 && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 07933 /* absorb event */ 07934 } else 07935 #endif /* defined(HAVE_PRI) */ 07936 { 07937 /* Unmute conference */ 07938 dahdi_confmute(p, 0); 07939 p->subs[idx].f.frametype = AST_FRAME_DTMF_END; 07940 p->subs[idx].f.subclass.integer = res & 0xff; 07941 dahdi_handle_dtmf(ast, idx, &f); 07942 } 07943 return f; 07944 } 07945 07946 if (res & DAHDI_EVENT_DTMFDOWN) { 07947 ast_debug(1, "DTMF Down '%c'\n", res & 0xff); 07948 #if defined(HAVE_PRI) 07949 if (dahdi_sig_pri_lib_handles(p->sig) 07950 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING 07951 && p->pri 07952 && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 07953 /* absorb event */ 07954 } else 07955 #endif /* defined(HAVE_PRI) */ 07956 { 07957 /* Mute conference */ 07958 dahdi_confmute(p, 1); 07959 p->subs[idx].f.frametype = AST_FRAME_DTMF_BEGIN; 07960 p->subs[idx].f.subclass.integer = res & 0xff; 07961 dahdi_handle_dtmf(ast, idx, &f); 07962 } 07963 return &p->subs[idx].f; 07964 } 07965 07966 switch (res) { 07967 case DAHDI_EVENT_EC_DISABLED: 07968 ast_verb(3, "Channel %d echo canceler disabled.\n", p->channel); 07969 p->echocanon = 0; 07970 break; 07971 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 07972 case DAHDI_EVENT_TX_CED_DETECTED: 07973 ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel); 07974 break; 07975 case DAHDI_EVENT_RX_CED_DETECTED: 07976 ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel); 07977 break; 07978 case DAHDI_EVENT_EC_NLP_DISABLED: 07979 ast_verb(3, "Channel %d echo canceler disabled its NLP.\n", p->channel); 07980 break; 07981 case DAHDI_EVENT_EC_NLP_ENABLED: 07982 ast_verb(3, "Channel %d echo canceler enabled its NLP.\n", p->channel); 07983 break; 07984 #endif 07985 case DAHDI_EVENT_BITSCHANGED: 07986 #ifdef HAVE_OPENR2 07987 if (p->sig != SIG_MFCR2) { 07988 ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig)); 07989 } else { 07990 ast_log(LOG_DEBUG, "bits changed in chan %d\n", p->channel); 07991 openr2_chan_handle_cas(p->r2chan); 07992 } 07993 #else 07994 ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig)); 07995 #endif 07996 break; 07997 case DAHDI_EVENT_PULSE_START: 07998 /* Stop tone if there's a pulse start and the PBX isn't started */ 07999 if (!ast->pbx) 08000 tone_zone_play_tone(p->subs[idx].dfd, -1); 08001 break; 08002 case DAHDI_EVENT_DIALCOMPLETE: 08003 /* DAHDI has completed dialing all digits sent using DAHDI_DIAL. */ 08004 #if defined(HAVE_PRI) 08005 if (dahdi_sig_pri_lib_handles(p->sig)) { 08006 if (p->inalarm) { 08007 break; 08008 } 08009 if (ioctl(p->subs[idx].dfd, DAHDI_DIALING, &x) == -1) { 08010 ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed on %s: %s\n", ast->name, 08011 strerror(errno)); 08012 return NULL; 08013 } 08014 if (x) { 08015 /* Still dialing in DAHDI driver */ 08016 break; 08017 } 08018 /* 08019 * The ast channel is locked and the private may be locked more 08020 * than once. 08021 */ 08022 sig_pri_dial_complete(p->sig_pvt, ast); 08023 break; 08024 } 08025 #endif /* defined(HAVE_PRI) */ 08026 #ifdef HAVE_OPENR2 08027 if ((p->sig & SIG_MFCR2) && p->r2chan && ast->_state != AST_STATE_UP) { 08028 /* we don't need to do anything for this event for R2 signaling 08029 if the call is being setup */ 08030 break; 08031 } 08032 #endif 08033 if (p->inalarm) break; 08034 if ((p->radio || (p->oprmode < 0))) break; 08035 if (ioctl(p->subs[idx].dfd,DAHDI_DIALING,&x) == -1) { 08036 ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed on %s: %s\n",ast->name, strerror(errno)); 08037 return NULL; 08038 } 08039 if (!x) { /* if not still dialing in driver */ 08040 dahdi_enable_ec(p); 08041 if (p->echobreak) { 08042 dahdi_train_ec(p); 08043 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 08044 p->dop.op = DAHDI_DIAL_OP_REPLACE; 08045 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08046 p->echobreak = 0; 08047 } else { 08048 p->dialing = 0; 08049 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) { 08050 /* if thru with dialing after offhook */ 08051 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 08052 ast_setstate(ast, AST_STATE_UP); 08053 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08054 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08055 break; 08056 } else { /* if to state wait for offhook to dial rest */ 08057 /* we now wait for off hook */ 08058 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 08059 } 08060 } 08061 if (ast->_state == AST_STATE_DIALING) { 08062 if ((p->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 08063 ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n"); 08064 } else if (p->confirmanswer || (!p->dialednone 08065 && ((mysig == SIG_EM) || (mysig == SIG_EM_E1) 08066 || (mysig == SIG_EMWINK) || (mysig == SIG_FEATD) 08067 || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF) 08068 || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) 08069 || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB) 08070 || (mysig == SIG_SF) || (mysig == SIG_SFWINK) 08071 || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF) 08072 || (mysig == SIG_SF_FEATB)))) { 08073 ast_setstate(ast, AST_STATE_RINGING); 08074 } else if (!p->answeronpolarityswitch) { 08075 ast_setstate(ast, AST_STATE_UP); 08076 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08077 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08078 /* If aops=0 and hops=1, this is necessary */ 08079 p->polarity = POLARITY_REV; 08080 } else { 08081 /* Start clean, so we can catch the change to REV polarity when party answers */ 08082 p->polarity = POLARITY_IDLE; 08083 } 08084 } 08085 } 08086 } 08087 break; 08088 case DAHDI_EVENT_ALARM: 08089 switch (p->sig) { 08090 #if defined(HAVE_PRI) 08091 case SIG_PRI_LIB_HANDLE_CASES: 08092 sig_pri_chan_alarm_notify(p->sig_pvt, 0); 08093 break; 08094 #endif /* defined(HAVE_PRI) */ 08095 #if defined(HAVE_SS7) 08096 case SIG_SS7: 08097 sig_ss7_set_alarm(p->sig_pvt, 1); 08098 break; 08099 #endif /* defined(HAVE_SS7) */ 08100 default: 08101 p->inalarm = 1; 08102 break; 08103 } 08104 res = get_alarms(p); 08105 handle_alarms(p, res); 08106 #ifdef HAVE_PRI 08107 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 08108 /* fall through intentionally */ 08109 } else { 08110 break; 08111 } 08112 #endif 08113 #if defined(HAVE_SS7) 08114 if (p->sig == SIG_SS7) 08115 break; 08116 #endif /* defined(HAVE_SS7) */ 08117 #ifdef HAVE_OPENR2 08118 if (p->sig == SIG_MFCR2) 08119 break; 08120 #endif 08121 case DAHDI_EVENT_ONHOOK: 08122 if (p->radio) { 08123 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08124 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_UNKEY; 08125 break; 08126 } 08127 if (p->oprmode < 0) 08128 { 08129 if (p->oprmode != -1) break; 08130 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 08131 { 08132 /* Make sure it starts ringing */ 08133 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 08134 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RING); 08135 save_conference(p->oprpeer); 08136 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 08137 } 08138 break; 08139 } 08140 switch (p->sig) { 08141 case SIG_FXOLS: 08142 case SIG_FXOGS: 08143 case SIG_FXOKS: 08144 /* Check for some special conditions regarding call waiting */ 08145 if (idx == SUB_REAL) { 08146 /* The normal line was hung up */ 08147 if (p->subs[SUB_CALLWAIT].owner) { 08148 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 08149 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 08150 ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel); 08151 unalloc_sub(p, SUB_CALLWAIT); 08152 #if 0 08153 p->subs[idx].needanswer = 0; 08154 p->subs[idx].needringing = 0; 08155 #endif 08156 p->callwaitingrepeat = 0; 08157 p->cidcwexpire = 0; 08158 p->cid_suppress_expire = 0; 08159 p->owner = NULL; 08160 /* Don't start streaming audio yet if the incoming call isn't up yet */ 08161 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 08162 p->dialing = 1; 08163 dahdi_ring_phone(p); 08164 } else if (p->subs[SUB_THREEWAY].owner) { 08165 unsigned int mssinceflash; 08166 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 08167 the private structure -- not especially easy or clean */ 08168 while (p->subs[SUB_THREEWAY].owner && ast_channel_trylock(p->subs[SUB_THREEWAY].owner)) { 08169 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 08170 DLA_UNLOCK(&p->lock); 08171 CHANNEL_DEADLOCK_AVOIDANCE(ast); 08172 /* We can grab ast and p in that order, without worry. We should make sure 08173 nothing seriously bad has happened though like some sort of bizarre double 08174 masquerade! */ 08175 DLA_LOCK(&p->lock); 08176 if (p->owner != ast) { 08177 ast_log(LOG_WARNING, "This isn't good...\n"); 08178 return NULL; 08179 } 08180 } 08181 if (!p->subs[SUB_THREEWAY].owner) { 08182 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 08183 return NULL; 08184 } 08185 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 08186 ast_debug(1, "Last flash was %d ms ago\n", mssinceflash); 08187 if (mssinceflash < MIN_MS_SINCE_FLASH) { 08188 /* It hasn't been long enough since the last flashook. This is probably a bounce on 08189 hanging up. Hangup both channels now */ 08190 if (p->subs[SUB_THREEWAY].owner) 08191 ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY].owner, AST_CAUSE_NO_ANSWER); 08192 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08193 ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 08194 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08195 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 08196 if (p->transfer) { 08197 /* In any case this isn't a threeway call anymore */ 08198 p->subs[SUB_REAL].inthreeway = 0; 08199 p->subs[SUB_THREEWAY].inthreeway = 0; 08200 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 08201 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 08202 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08203 /* Swap subs and dis-own channel */ 08204 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08205 p->owner = NULL; 08206 /* Ring the phone */ 08207 dahdi_ring_phone(p); 08208 } else { 08209 if ((res = attempt_transfer(p)) < 0) { 08210 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08211 if (p->subs[SUB_THREEWAY].owner) 08212 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08213 } else if (res) { 08214 /* Don't actually hang up at this point */ 08215 if (p->subs[SUB_THREEWAY].owner) 08216 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08217 break; 08218 } 08219 } 08220 } else { 08221 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08222 if (p->subs[SUB_THREEWAY].owner) 08223 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08224 } 08225 } else { 08226 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08227 /* Swap subs and dis-own channel */ 08228 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08229 p->owner = NULL; 08230 /* Ring the phone */ 08231 dahdi_ring_phone(p); 08232 } 08233 } 08234 } else { 08235 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", idx); 08236 } 08237 /* Fall through */ 08238 default: 08239 dahdi_disable_ec(p); 08240 return NULL; 08241 } 08242 break; 08243 case DAHDI_EVENT_RINGOFFHOOK: 08244 if (p->inalarm) break; 08245 if (p->oprmode < 0) 08246 { 08247 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 08248 { 08249 /* Make sure it stops ringing */ 08250 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 08251 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, -1); 08252 restore_conference(p->oprpeer); 08253 } 08254 break; 08255 } 08256 if (p->radio) 08257 { 08258 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08259 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_KEY; 08260 break; 08261 } 08262 /* for E911, its supposed to wait for offhook then dial 08263 the second half of the dial string */ 08264 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 08265 c = strchr(p->dialdest, '/'); 08266 if (c) 08267 c++; 08268 else 08269 c = p->dialdest; 08270 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 08271 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 08272 if (strlen(p->dop.dialstr) > 4) { 08273 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 08274 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 08275 p->echorest[sizeof(p->echorest) - 1] = '\0'; 08276 p->echobreak = 1; 08277 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 08278 } else 08279 p->echobreak = 0; 08280 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) { 08281 int saveerr = errno; 08282 08283 x = DAHDI_ONHOOK; 08284 ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 08285 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr)); 08286 return NULL; 08287 } 08288 p->dialing = 1; 08289 return &p->subs[idx].f; 08290 } 08291 switch (p->sig) { 08292 case SIG_FXOLS: 08293 case SIG_FXOGS: 08294 case SIG_FXOKS: 08295 switch (ast->_state) { 08296 case AST_STATE_RINGING: 08297 dahdi_enable_ec(p); 08298 dahdi_train_ec(p); 08299 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08300 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08301 /* Make sure it stops ringing */ 08302 p->subs[SUB_REAL].needringing = 0; 08303 dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 08304 ast_debug(1, "channel %d answered\n", p->channel); 08305 08306 /* Cancel any running CallerID spill */ 08307 ast_free(p->cidspill); 08308 p->cidspill = NULL; 08309 restore_conference(p); 08310 08311 p->dialing = 0; 08312 p->callwaitcas = 0; 08313 if (p->confirmanswer) { 08314 /* Ignore answer if "confirm answer" is enabled */ 08315 p->subs[idx].f.frametype = AST_FRAME_NULL; 08316 p->subs[idx].f.subclass.integer = 0; 08317 } else if (!ast_strlen_zero(p->dop.dialstr)) { 08318 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 08319 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08320 if (res < 0) { 08321 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08322 p->dop.dialstr[0] = '\0'; 08323 return NULL; 08324 } else { 08325 ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 08326 p->subs[idx].f.frametype = AST_FRAME_NULL; 08327 p->subs[idx].f.subclass.integer = 0; 08328 p->dialing = 1; 08329 } 08330 p->dop.dialstr[0] = '\0'; 08331 ast_setstate(ast, AST_STATE_DIALING); 08332 } else 08333 ast_setstate(ast, AST_STATE_UP); 08334 return &p->subs[idx].f; 08335 case AST_STATE_DOWN: 08336 ast_setstate(ast, AST_STATE_RING); 08337 ast->rings = 1; 08338 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08339 p->subs[idx].f.subclass.integer = AST_CONTROL_OFFHOOK; 08340 ast_debug(1, "channel %d picked up\n", p->channel); 08341 return &p->subs[idx].f; 08342 case AST_STATE_UP: 08343 /* Make sure it stops ringing */ 08344 dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 08345 /* Okay -- probably call waiting*/ 08346 if (ast_bridged_channel(p->owner)) 08347 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08348 p->subs[idx].needunhold = 1; 08349 break; 08350 case AST_STATE_RESERVED: 08351 /* Start up dialtone */ 08352 if (has_voicemail(p)) 08353 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER); 08354 else 08355 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE); 08356 break; 08357 default: 08358 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 08359 } 08360 break; 08361 case SIG_FXSLS: 08362 case SIG_FXSGS: 08363 case SIG_FXSKS: 08364 if (ast->_state == AST_STATE_RING) { 08365 p->ringt = p->ringt_base; 08366 } 08367 08368 /* If we get a ring then we cannot be in 08369 * reversed polarity. So we reset to idle */ 08370 ast_debug(1, "Setting IDLE polarity due " 08371 "to ring. Old polarity was %d\n", 08372 p->polarity); 08373 p->polarity = POLARITY_IDLE; 08374 08375 /* Fall through */ 08376 case SIG_EM: 08377 case SIG_EM_E1: 08378 case SIG_EMWINK: 08379 case SIG_FEATD: 08380 case SIG_FEATDMF: 08381 case SIG_FEATDMF_TA: 08382 case SIG_E911: 08383 case SIG_FGC_CAMA: 08384 case SIG_FGC_CAMAMF: 08385 case SIG_FEATB: 08386 case SIG_SF: 08387 case SIG_SFWINK: 08388 case SIG_SF_FEATD: 08389 case SIG_SF_FEATDMF: 08390 case SIG_SF_FEATB: 08391 if (ast->_state == AST_STATE_PRERING) 08392 ast_setstate(ast, AST_STATE_RING); 08393 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 08394 ast_debug(1, "Ring detected\n"); 08395 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08396 p->subs[idx].f.subclass.integer = AST_CONTROL_RING; 08397 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 08398 ast_debug(1, "Line answered\n"); 08399 if (p->confirmanswer) { 08400 p->subs[idx].f.frametype = AST_FRAME_NULL; 08401 p->subs[idx].f.subclass.integer = 0; 08402 } else { 08403 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08404 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08405 ast_setstate(ast, AST_STATE_UP); 08406 } 08407 } else if (ast->_state != AST_STATE_RING) 08408 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 08409 break; 08410 default: 08411 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 08412 } 08413 break; 08414 case DAHDI_EVENT_RINGBEGIN: 08415 switch (p->sig) { 08416 case SIG_FXSLS: 08417 case SIG_FXSGS: 08418 case SIG_FXSKS: 08419 if (ast->_state == AST_STATE_RING) { 08420 p->ringt = p->ringt_base; 08421 } 08422 break; 08423 } 08424 break; 08425 case DAHDI_EVENT_RINGERON: 08426 break; 08427 case DAHDI_EVENT_NOALARM: 08428 switch (p->sig) { 08429 #if defined(HAVE_PRI) 08430 case SIG_PRI_LIB_HANDLE_CASES: 08431 sig_pri_chan_alarm_notify(p->sig_pvt, 1); 08432 break; 08433 #endif /* defined(HAVE_PRI) */ 08434 #if defined(HAVE_SS7) 08435 case SIG_SS7: 08436 sig_ss7_set_alarm(p->sig_pvt, 0); 08437 break; 08438 #endif /* defined(HAVE_SS7) */ 08439 default: 08440 p->inalarm = 0; 08441 break; 08442 } 08443 handle_clear_alarms(p); 08444 break; 08445 case DAHDI_EVENT_WINKFLASH: 08446 if (p->inalarm) break; 08447 if (p->radio) break; 08448 if (p->oprmode < 0) break; 08449 if (p->oprmode > 1) 08450 { 08451 struct dahdi_params par; 08452 08453 memset(&par, 0, sizeof(par)); 08454 if (ioctl(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par) != -1) 08455 { 08456 if (!par.rxisoffhook) 08457 { 08458 /* Make sure it stops ringing */ 08459 dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 08460 dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RING); 08461 save_conference(p); 08462 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 08463 } 08464 } 08465 break; 08466 } 08467 /* Remember last time we got a flash-hook */ 08468 p->flashtime = ast_tvnow(); 08469 switch (mysig) { 08470 case SIG_FXOLS: 08471 case SIG_FXOGS: 08472 case SIG_FXOKS: 08473 ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 08474 idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd); 08475 08476 /* Cancel any running CallerID spill */ 08477 ast_free(p->cidspill); 08478 p->cidspill = NULL; 08479 restore_conference(p); 08480 p->callwaitcas = 0; 08481 08482 if (idx != SUB_REAL) { 08483 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", idx, p->channel); 08484 goto winkflashdone; 08485 } 08486 08487 if (p->subs[SUB_CALLWAIT].owner) { 08488 /* Swap to call-wait */ 08489 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 08490 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 08491 p->owner = p->subs[SUB_REAL].owner; 08492 ast_debug(1, "Making %s the new owner\n", p->owner->name); 08493 if (p->owner->_state == AST_STATE_RINGING) { 08494 ast_setstate(p->owner, AST_STATE_UP); 08495 p->subs[SUB_REAL].needanswer = 1; 08496 } 08497 p->callwaitingrepeat = 0; 08498 p->cidcwexpire = 0; 08499 p->cid_suppress_expire = 0; 08500 /* Start music on hold if appropriate */ 08501 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 08502 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 08503 S_OR(p->mohsuggest, NULL), 08504 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08505 } 08506 p->subs[SUB_CALLWAIT].needhold = 1; 08507 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 08508 ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD, 08509 S_OR(p->mohsuggest, NULL), 08510 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08511 } 08512 p->subs[SUB_REAL].needunhold = 1; 08513 } else if (!p->subs[SUB_THREEWAY].owner) { 08514 if (!p->threewaycalling) { 08515 /* Just send a flash if no 3-way calling */ 08516 p->subs[SUB_REAL].needflash = 1; 08517 goto winkflashdone; 08518 } else if (!check_for_conference(p)) { 08519 char cid_num[256]; 08520 char cid_name[256]; 08521 08522 cid_num[0] = 0; 08523 cid_name[0] = 0; 08524 if (p->dahditrcallerid && p->owner) { 08525 if (p->owner->caller.id.number.valid 08526 && p->owner->caller.id.number.str) { 08527 ast_copy_string(cid_num, p->owner->caller.id.number.str, 08528 sizeof(cid_num)); 08529 } 08530 if (p->owner->caller.id.name.valid 08531 && p->owner->caller.id.name.str) { 08532 ast_copy_string(cid_name, p->owner->caller.id.name.str, 08533 sizeof(cid_name)); 08534 } 08535 } 08536 /* XXX This section needs much more error checking!!! XXX */ 08537 /* Start a 3-way call if feasible */ 08538 if (!((ast->pbx) || 08539 (ast->_state == AST_STATE_UP) || 08540 (ast->_state == AST_STATE_RING))) { 08541 ast_debug(1, "Flash when call not up or ringing\n"); 08542 goto winkflashdone; 08543 } 08544 if (alloc_sub(p, SUB_THREEWAY)) { 08545 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 08546 goto winkflashdone; 08547 } 08548 08549 /* 08550 * Make new channel 08551 * 08552 * We cannot hold the p or ast locks while creating a new 08553 * channel. 08554 */ 08555 ast_mutex_unlock(&p->lock); 08556 ast_channel_unlock(ast); 08557 chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, NULL); 08558 ast_channel_lock(ast); 08559 ast_mutex_lock(&p->lock); 08560 if (p->dahditrcallerid) { 08561 if (!p->origcid_num) 08562 p->origcid_num = ast_strdup(p->cid_num); 08563 if (!p->origcid_name) 08564 p->origcid_name = ast_strdup(p->cid_name); 08565 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 08566 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 08567 } 08568 /* Swap things around between the three-way and real call */ 08569 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08570 /* Disable echo canceller for better dialing */ 08571 dahdi_disable_ec(p); 08572 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALRECALL); 08573 if (res) 08574 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 08575 p->owner = chan; 08576 if (!chan) { 08577 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 08578 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 08579 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 08580 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 08581 dahdi_enable_ec(p); 08582 ast_hangup(chan); 08583 } else { 08584 ast_verb(3, "Started three way call on channel %d\n", p->channel); 08585 08586 /* Start music on hold if appropriate */ 08587 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 08588 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 08589 S_OR(p->mohsuggest, NULL), 08590 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08591 } 08592 p->subs[SUB_THREEWAY].needhold = 1; 08593 } 08594 } 08595 } else { 08596 /* Already have a 3 way call */ 08597 if (p->subs[SUB_THREEWAY].inthreeway) { 08598 /* Call is already up, drop the last person */ 08599 ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel); 08600 /* If the primary call isn't answered yet, use it */ 08601 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 08602 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 08603 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08604 p->owner = p->subs[SUB_REAL].owner; 08605 } 08606 /* Drop the last call and stop the conference */ 08607 ast_verb(3, "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name); 08608 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08609 p->subs[SUB_REAL].inthreeway = 0; 08610 p->subs[SUB_THREEWAY].inthreeway = 0; 08611 } else { 08612 /* Lets see what we're up to */ 08613 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 08614 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 08615 int otherindex = SUB_THREEWAY; 08616 08617 ast_verb(3, "Building conference call with %s and %s\n", 08618 p->subs[SUB_THREEWAY].owner->name, 08619 p->subs[SUB_REAL].owner->name); 08620 /* Put them in the threeway, and flip */ 08621 p->subs[SUB_THREEWAY].inthreeway = 1; 08622 p->subs[SUB_REAL].inthreeway = 1; 08623 if (ast->_state == AST_STATE_UP) { 08624 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08625 otherindex = SUB_REAL; 08626 } 08627 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 08628 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 08629 p->subs[otherindex].needunhold = 1; 08630 p->owner = p->subs[SUB_REAL].owner; 08631 } else { 08632 ast_verb(3, "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name); 08633 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08634 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08635 p->owner = p->subs[SUB_REAL].owner; 08636 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 08637 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 08638 p->subs[SUB_REAL].needunhold = 1; 08639 dahdi_enable_ec(p); 08640 } 08641 } 08642 } 08643 winkflashdone: 08644 update_conf(p); 08645 break; 08646 case SIG_EM: 08647 case SIG_EM_E1: 08648 case SIG_FEATD: 08649 case SIG_SF: 08650 case SIG_SFWINK: 08651 case SIG_SF_FEATD: 08652 case SIG_FXSLS: 08653 case SIG_FXSGS: 08654 if (p->dialing) 08655 ast_debug(1, "Ignoring wink on channel %d\n", p->channel); 08656 else 08657 ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 08658 break; 08659 case SIG_FEATDMF_TA: 08660 switch (p->whichwink) { 08661 case 0: 08662 ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->caller.ani2, 08663 S_COR(p->owner->caller.ani.number.valid, 08664 p->owner->caller.ani.number.str, "")); 08665 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", 08666 p->owner->caller.ani2, 08667 S_COR(p->owner->caller.ani.number.valid, 08668 p->owner->caller.ani.number.str, "")); 08669 break; 08670 case 1: 08671 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 08672 break; 08673 case 2: 08674 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 08675 return NULL; 08676 } 08677 p->whichwink++; 08678 /* Fall through */ 08679 case SIG_FEATDMF: 08680 case SIG_E911: 08681 case SIG_FGC_CAMAMF: 08682 case SIG_FGC_CAMA: 08683 case SIG_FEATB: 08684 case SIG_SF_FEATDMF: 08685 case SIG_SF_FEATB: 08686 case SIG_EMWINK: 08687 /* FGD MF and EMWINK *Must* wait for wink */ 08688 if (!ast_strlen_zero(p->dop.dialstr)) { 08689 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08690 if (res < 0) { 08691 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08692 p->dop.dialstr[0] = '\0'; 08693 return NULL; 08694 } else 08695 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr); 08696 } 08697 p->dop.dialstr[0] = '\0'; 08698 break; 08699 default: 08700 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 08701 } 08702 break; 08703 case DAHDI_EVENT_HOOKCOMPLETE: 08704 if (p->inalarm) break; 08705 if ((p->radio || (p->oprmode < 0))) break; 08706 if (p->waitingfordt.tv_sec) break; 08707 switch (mysig) { 08708 case SIG_FXSLS: /* only interesting for FXS */ 08709 case SIG_FXSGS: 08710 case SIG_FXSKS: 08711 case SIG_EM: 08712 case SIG_EM_E1: 08713 case SIG_EMWINK: 08714 case SIG_FEATD: 08715 case SIG_SF: 08716 case SIG_SFWINK: 08717 case SIG_SF_FEATD: 08718 if (!ast_strlen_zero(p->dop.dialstr)) { 08719 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08720 if (res < 0) { 08721 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08722 p->dop.dialstr[0] = '\0'; 08723 return NULL; 08724 } else 08725 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr); 08726 } 08727 p->dop.dialstr[0] = '\0'; 08728 p->dop.op = DAHDI_DIAL_OP_REPLACE; 08729 break; 08730 case SIG_FEATDMF: 08731 case SIG_FEATDMF_TA: 08732 case SIG_E911: 08733 case SIG_FGC_CAMA: 08734 case SIG_FGC_CAMAMF: 08735 case SIG_FEATB: 08736 case SIG_SF_FEATDMF: 08737 case SIG_SF_FEATB: 08738 ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 08739 break; 08740 default: 08741 break; 08742 } 08743 break; 08744 case DAHDI_EVENT_POLARITY: 08745 /* 08746 * If we get a Polarity Switch event, check to see 08747 * if we should change the polarity state and 08748 * mark the channel as UP or if this is an indication 08749 * of remote end disconnect. 08750 */ 08751 if (p->polarity == POLARITY_IDLE) { 08752 p->polarity = POLARITY_REV; 08753 if (p->answeronpolarityswitch && 08754 ((ast->_state == AST_STATE_DIALING) || 08755 (ast->_state == AST_STATE_RINGING))) { 08756 ast_debug(1, "Answering on polarity switch!\n"); 08757 ast_setstate(p->owner, AST_STATE_UP); 08758 if (p->hanguponpolarityswitch) { 08759 p->polaritydelaytv = ast_tvnow(); 08760 } 08761 } else 08762 ast_debug(1, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 08763 } 08764 /* Removed else statement from here as it was preventing hangups from ever happening*/ 08765 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 08766 if (p->hanguponpolarityswitch && 08767 (p->polarityonanswerdelay > 0) && 08768 (p->polarity == POLARITY_REV) && 08769 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 08770 /* Added log_debug information below to provide a better indication of what is going on */ 08771 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) ); 08772 08773 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 08774 ast_debug(1, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 08775 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 08776 p->polarity = POLARITY_IDLE; 08777 } else 08778 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); 08779 08780 } else { 08781 p->polarity = POLARITY_IDLE; 08782 ast_debug(1, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 08783 } 08784 /* Added more log_debug information below to provide a better indication of what is going on */ 08785 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) ); 08786 break; 08787 default: 08788 ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel); 08789 } 08790 return &p->subs[idx].f; 08791 }
| static int dahdi_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 6165 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_confmute(), dahdi_disable_ec(), dahdi_get_index, 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, 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::mohsuggest, dahdi_pvt::muting, dahdi_subchannel::needanswer, dahdi_subchannel::needbusy, dahdi_subchannel::needcongestion, dahdi_subchannel::needflash, dahdi_subchannel::needringing, 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::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.
06166 { 06167 int res = 0; 06168 int idx,x; 06169 int law; 06170 /*static int restore_gains(struct dahdi_pvt *p);*/ 06171 struct dahdi_pvt *p = ast->tech_pvt; 06172 struct dahdi_params par; 06173 06174 ast_debug(1, "dahdi_hangup(%s)\n", ast->name); 06175 if (!ast->tech_pvt) { 06176 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 06177 return 0; 06178 } 06179 06180 ast_mutex_lock(&p->lock); 06181 p->exten[0] = '\0'; 06182 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 06183 dahdi_confmute(p, 0); 06184 restore_gains(p); 06185 p->ignoredtmf = 0; 06186 p->waitingfordt.tv_sec = 0; 06187 06188 res = analog_hangup(p->sig_pvt, ast); 06189 revert_fax_buffers(p, ast); 06190 06191 goto hangup_out; 06192 } else { 06193 p->cid_num[0] = '\0'; 06194 p->cid_name[0] = '\0'; 06195 p->cid_subaddr[0] = '\0'; 06196 } 06197 06198 #if defined(HAVE_PRI) 06199 if (dahdi_sig_pri_lib_handles(p->sig)) { 06200 x = 1; 06201 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06202 06203 dahdi_confmute(p, 0); 06204 p->muting = 0; 06205 restore_gains(p); 06206 if (p->dsp) { 06207 ast_dsp_free(p->dsp); 06208 p->dsp = NULL; 06209 } 06210 p->ignoredtmf = 0; 06211 06212 /* Real channel, do some fixup */ 06213 p->subs[SUB_REAL].owner = NULL; 06214 p->subs[SUB_REAL].needbusy = 0; 06215 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 06216 06217 p->owner = NULL; 06218 p->cid_tag[0] = '\0'; 06219 p->ringt = 0;/* Probably not used in this mode. Reset anyway. */ 06220 p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */ 06221 p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */ 06222 p->outgoing = 0; 06223 p->digital = 0; 06224 p->faxhandled = 0; 06225 p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */ 06226 06227 revert_fax_buffers(p, ast); 06228 06229 p->law = p->law_default; 06230 law = p->law_default; 06231 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06232 if (res < 0) { 06233 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", 06234 p->channel, strerror(errno)); 06235 } 06236 06237 sig_pri_hangup(p->sig_pvt, ast); 06238 06239 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06240 dahdi_disable_ec(p); 06241 06242 x = 0; 06243 ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0); 06244 p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */ 06245 06246 p->rdnis[0] = '\0'; 06247 update_conf(p); 06248 reset_conf(p); 06249 06250 /* Restore data mode */ 06251 x = 0; 06252 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06253 06254 if (num_restart_pending == 0) { 06255 restart_monitor(); 06256 } 06257 goto hangup_out; 06258 } 06259 #endif /* defined(HAVE_PRI) */ 06260 06261 #if defined(HAVE_SS7) 06262 if (p->sig == SIG_SS7) { 06263 x = 1; 06264 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06265 06266 dahdi_confmute(p, 0); 06267 p->muting = 0; 06268 restore_gains(p); 06269 if (p->dsp) { 06270 ast_dsp_free(p->dsp); 06271 p->dsp = NULL; 06272 } 06273 p->ignoredtmf = 0; 06274 06275 /* Real channel, do some fixup */ 06276 p->subs[SUB_REAL].owner = NULL; 06277 p->subs[SUB_REAL].needbusy = 0; 06278 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 06279 06280 p->owner = NULL; 06281 p->ringt = 0;/* Probably not used in this mode. Reset anyway. */ 06282 p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */ 06283 p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */ 06284 p->outgoing = 0; 06285 p->digital = 0; 06286 p->faxhandled = 0; 06287 p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */ 06288 06289 revert_fax_buffers(p, ast); 06290 06291 p->law = p->law_default; 06292 law = p->law_default; 06293 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06294 if (res < 0) { 06295 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", 06296 p->channel, strerror(errno)); 06297 } 06298 06299 sig_ss7_hangup(p->sig_pvt, ast); 06300 06301 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06302 dahdi_disable_ec(p); 06303 06304 x = 0; 06305 ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0); 06306 p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */ 06307 06308 update_conf(p); 06309 reset_conf(p); 06310 06311 /* Restore data mode */ 06312 x = 0; 06313 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06314 06315 if (num_restart_pending == 0) { 06316 restart_monitor(); 06317 } 06318 goto hangup_out; 06319 } 06320 #endif /* defined(HAVE_SS7) */ 06321 06322 idx = dahdi_get_index(ast, p, 1); 06323 06324 dahdi_confmute(p, 0); 06325 p->muting = 0; 06326 restore_gains(p); 06327 if (p->origcid_num) { 06328 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 06329 ast_free(p->origcid_num); 06330 p->origcid_num = NULL; 06331 } 06332 if (p->origcid_name) { 06333 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 06334 ast_free(p->origcid_name); 06335 p->origcid_name = NULL; 06336 } 06337 if (p->dsp) 06338 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 06339 06340 ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 06341 p->channel, idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd); 06342 p->ignoredtmf = 0; 06343 06344 if (idx > -1) { 06345 /* Real channel, do some fixup */ 06346 p->subs[idx].owner = NULL; 06347 p->subs[idx].needanswer = 0; 06348 p->subs[idx].needflash = 0; 06349 p->subs[idx].needringing = 0; 06350 p->subs[idx].needbusy = 0; 06351 p->subs[idx].needcongestion = 0; 06352 p->subs[idx].linear = 0; 06353 p->polarity = POLARITY_IDLE; 06354 dahdi_setlinear(p->subs[idx].dfd, 0); 06355 if (idx == SUB_REAL) { 06356 if ((p->subs[SUB_CALLWAIT].dfd > -1) && (p->subs[SUB_THREEWAY].dfd > -1)) { 06357 ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n"); 06358 if (p->subs[SUB_CALLWAIT].inthreeway) { 06359 /* We had flipped over to answer a callwait and now it's gone */ 06360 ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n"); 06361 /* Move to the call-wait, but un-own us until they flip back. */ 06362 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 06363 unalloc_sub(p, SUB_CALLWAIT); 06364 p->owner = NULL; 06365 } else { 06366 /* The three way hung up, but we still have a call wait */ 06367 ast_debug(1, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 06368 swap_subs(p, SUB_THREEWAY, SUB_REAL); 06369 unalloc_sub(p, SUB_THREEWAY); 06370 if (p->subs[SUB_REAL].inthreeway) { 06371 /* This was part of a three way call. Immediately make way for 06372 another call */ 06373 ast_debug(1, "Call was complete, setting owner to former third call\n"); 06374 p->owner = p->subs[SUB_REAL].owner; 06375 } else { 06376 /* This call hasn't been completed yet... Set owner to NULL */ 06377 ast_debug(1, "Call was incomplete, setting owner to NULL\n"); 06378 p->owner = NULL; 06379 } 06380 p->subs[SUB_REAL].inthreeway = 0; 06381 } 06382 } else if (p->subs[SUB_CALLWAIT].dfd > -1) { 06383 /* Move to the call-wait and switch back to them. */ 06384 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 06385 unalloc_sub(p, SUB_CALLWAIT); 06386 p->owner = p->subs[SUB_REAL].owner; 06387 if (p->owner->_state != AST_STATE_UP) 06388 p->subs[SUB_REAL].needanswer = 1; 06389 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 06390 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 06391 } else if (p->subs[SUB_THREEWAY].dfd > -1) { 06392 swap_subs(p, SUB_THREEWAY, SUB_REAL); 06393 unalloc_sub(p, SUB_THREEWAY); 06394 if (p->subs[SUB_REAL].inthreeway) { 06395 /* This was part of a three way call. Immediately make way for 06396 another call */ 06397 ast_debug(1, "Call was complete, setting owner to former third call\n"); 06398 p->owner = p->subs[SUB_REAL].owner; 06399 } else { 06400 /* This call hasn't been completed yet... Set owner to NULL */ 06401 ast_debug(1, "Call was incomplete, setting owner to NULL\n"); 06402 p->owner = NULL; 06403 } 06404 p->subs[SUB_REAL].inthreeway = 0; 06405 } 06406 } else if (idx == SUB_CALLWAIT) { 06407 /* Ditch the holding callwait call, and immediately make it availabe */ 06408 if (p->subs[SUB_CALLWAIT].inthreeway) { 06409 /* This is actually part of a three way, placed on hold. Place the third part 06410 on music on hold now */ 06411 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 06412 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 06413 S_OR(p->mohsuggest, NULL), 06414 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 06415 } 06416 p->subs[SUB_THREEWAY].inthreeway = 0; 06417 /* Make it the call wait now */ 06418 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 06419 unalloc_sub(p, SUB_THREEWAY); 06420 } else 06421 unalloc_sub(p, SUB_CALLWAIT); 06422 } else if (idx == SUB_THREEWAY) { 06423 if (p->subs[SUB_CALLWAIT].inthreeway) { 06424 /* The other party of the three way call is currently in a call-wait state. 06425 Start music on hold for them, and take the main guy out of the third call */ 06426 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 06427 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 06428 S_OR(p->mohsuggest, NULL), 06429 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 06430 } 06431 p->subs[SUB_CALLWAIT].inthreeway = 0; 06432 } 06433 p->subs[SUB_REAL].inthreeway = 0; 06434 /* If this was part of a three way call index, let us make 06435 another three way call */ 06436 unalloc_sub(p, SUB_THREEWAY); 06437 } else { 06438 /* This wasn't any sort of call, but how are we an index? */ 06439 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 06440 } 06441 } 06442 06443 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 06444 p->owner = NULL; 06445 p->ringt = 0; 06446 p->distinctivering = 0; 06447 p->confirmanswer = 0; 06448 p->outgoing = 0; 06449 p->digital = 0; 06450 p->faxhandled = 0; 06451 p->pulsedial = 0; 06452 if (p->dsp) { 06453 ast_dsp_free(p->dsp); 06454 p->dsp = NULL; 06455 } 06456 06457 revert_fax_buffers(p, ast); 06458 06459 p->law = p->law_default; 06460 law = p->law_default; 06461 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06462 if (res < 0) 06463 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno)); 06464 /* Perform low level hangup if no owner left */ 06465 #ifdef HAVE_OPENR2 06466 if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) { 06467 ast_log(LOG_DEBUG, "disconnecting MFC/R2 call on chan %d\n", p->channel); 06468 /* If it's an incoming call, check the mfcr2_forced_release setting */ 06469 if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) { 06470 dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE); 06471 } else { 06472 const char *r2causestr = pbx_builtin_getvar_helper(ast, "MFCR2_CAUSE"); 06473 int r2cause_user = r2causestr ? atoi(r2causestr) : 0; 06474 openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user) 06475 : dahdi_ast_cause_to_r2_cause(ast->hangupcause); 06476 dahdi_r2_disconnect_call(p, r2cause); 06477 } 06478 } else if (p->mfcr2call) { 06479 ast_log(LOG_DEBUG, "Clearing call request on channel %d\n", p->channel); 06480 /* since ast_request() was called but not ast_call() we have not yet dialed 06481 and the openr2 stack will not call on_call_end callback, we need to unset 06482 the mfcr2call flag and bump the monitor count so the monitor thread can take 06483 care of this channel events from now on */ 06484 p->mfcr2call = 0; 06485 } 06486 #endif 06487 switch (p->sig) { 06488 case SIG_SS7: 06489 case SIG_MFCR2: 06490 case SIG_PRI_LIB_HANDLE_CASES: 06491 case 0: 06492 break; 06493 default: 06494 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 06495 break; 06496 } 06497 if (res < 0) { 06498 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); 06499 } 06500 switch (p->sig) { 06501 case SIG_FXOGS: 06502 case SIG_FXOLS: 06503 case SIG_FXOKS: 06504 memset(&par, 0, sizeof(par)); 06505 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par); 06506 if (!res) { 06507 struct analog_pvt *analog_p = p->sig_pvt; 06508 #if 0 06509 ast_debug(1, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 06510 #endif 06511 /* If they're off hook, try playing congestion */ 06512 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0)))) 06513 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 06514 else 06515 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06516 analog_p->fxsoffhookstate = par.rxisoffhook; 06517 } 06518 break; 06519 case SIG_FXSGS: 06520 case SIG_FXSLS: 06521 case SIG_FXSKS: 06522 /* Make sure we're not made available for at least two seconds assuming 06523 we were actually used for an inbound or outbound call. */ 06524 if (ast->_state != AST_STATE_RESERVED) { 06525 time(&p->guardtime); 06526 p->guardtime += 2; 06527 } 06528 break; 06529 default: 06530 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06531 break; 06532 } 06533 if (p->sig) 06534 dahdi_disable_ec(p); 06535 x = 0; 06536 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 06537 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 06538 p->didtdd = 0; 06539 p->callwaitcas = 0; 06540 p->callwaiting = p->permcallwaiting; 06541 p->hidecallerid = p->permhidecallerid; 06542 p->waitingfordt.tv_sec = 0; 06543 p->dialing = 0; 06544 p->rdnis[0] = '\0'; 06545 update_conf(p); 06546 reset_conf(p); 06547 /* Restore data mode */ 06548 switch (p->sig) { 06549 case SIG_PRI_LIB_HANDLE_CASES: 06550 case SIG_SS7: 06551 x = 0; 06552 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 06553 break; 06554 default: 06555 break; 06556 } 06557 if (num_restart_pending == 0) 06558 restart_monitor(); 06559 } 06560 06561 p->callwaitingrepeat = 0; 06562 p->cidcwexpire = 0; 06563 p->cid_suppress_expire = 0; 06564 p->oprmode = 0; 06565 hangup_out: 06566 ast->tech_pvt = NULL; 06567 ast_free(p->cidspill); 06568 p->cidspill = NULL; 06569 06570 ast_mutex_unlock(&p->lock); 06571 ast_verb(3, "Hungup '%s'\n", ast->name); 06572 06573 ast_mutex_lock(&iflock); 06574 if (p->restartpending) { 06575 num_restart_pending--; 06576 } 06577 06578 if (p->destroy) { 06579 destroy_channel(p, 0); 06580 } 06581 ast_mutex_unlock(&iflock); 06582 06583 ast_module_unref(ast_module_info->self); 06584 return 0; 06585 }
| static void dahdi_iflist_extract | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5558 of file chan_dahdi.c.
References DAHDI_IFLIST_NONE, dahdi_pvt::next, dahdi_pvt::prev, and dahdi_pvt::which_iflist.
Referenced by destroy_dahdi_pvt().
05559 { 05560 /* Extract from the forward chain. */ 05561 if (pvt->prev) { 05562 pvt->prev->next = pvt->next; 05563 } else if (iflist == pvt) { 05564 /* Node is at the head of the list. */ 05565 iflist = pvt->next; 05566 } 05567 05568 /* Extract from the reverse chain. */ 05569 if (pvt->next) { 05570 pvt->next->prev = pvt->prev; 05571 } else if (ifend == pvt) { 05572 /* Node is at the end of the list. */ 05573 ifend = pvt->prev; 05574 } 05575 05576 /* Node is no longer in the list. */ 05577 pvt->which_iflist = DAHDI_IFLIST_NONE; 05578 pvt->prev = NULL; 05579 pvt->next = NULL; 05580 }
| static void dahdi_iflist_insert | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5508 of file chan_dahdi.c.
References dahdi_pvt::channel, DAHDI_IFLIST_MAIN, dahdi_pvt::next, dahdi_pvt::prev, and dahdi_pvt::which_iflist.
Referenced by duplicate_pseudo(), and mkintf().
05509 { 05510 struct dahdi_pvt *cur; 05511 05512 pvt->which_iflist = DAHDI_IFLIST_MAIN; 05513 05514 /* Find place in middle of list for the new interface. */ 05515 for (cur = iflist; cur; cur = cur->next) { 05516 if (pvt->channel < cur->channel) { 05517 /* New interface goes before the current interface. */ 05518 pvt->prev = cur->prev; 05519 pvt->next = cur; 05520 if (cur->prev) { 05521 /* Insert into the middle of the list. */ 05522 cur->prev->next = pvt; 05523 } else { 05524 /* Insert at head of list. */ 05525 iflist = pvt; 05526 } 05527 cur->prev = pvt; 05528 return; 05529 } 05530 } 05531 05532 /* New interface goes onto the end of the list */ 05533 pvt->prev = ifend; 05534 pvt->next = NULL; 05535 if (ifend) { 05536 ifend->next = pvt; 05537 } 05538 ifend = pvt; 05539 if (!iflist) { 05540 /* List was empty */ 05541 iflist = pvt; 05542 } 05543 }
| static int dahdi_indicate | ( | struct ast_channel * | chan, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 9453 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, LOG_WARNING, dahdi_pvt::mohinterpret, 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.
Referenced by dahdi_fixup().
09454 { 09455 struct dahdi_pvt *p = chan->tech_pvt; 09456 int res=-1; 09457 int idx; 09458 int func = DAHDI_FLASH; 09459 09460 ast_mutex_lock(&p->lock); 09461 ast_debug(1, "Requested indication %d on channel %s\n", condition, chan->name); 09462 switch (p->sig) { 09463 #if defined(HAVE_PRI) 09464 case SIG_PRI_LIB_HANDLE_CASES: 09465 res = sig_pri_indicate(p->sig_pvt, chan, condition, data, datalen); 09466 ast_mutex_unlock(&p->lock); 09467 return res; 09468 #endif /* defined(HAVE_PRI) */ 09469 #if defined(HAVE_SS7) 09470 case SIG_SS7: 09471 res = sig_ss7_indicate(p->sig_pvt, chan, condition, data, datalen); 09472 ast_mutex_unlock(&p->lock); 09473 return res; 09474 #endif /* defined(HAVE_SS7) */ 09475 default: 09476 break; 09477 } 09478 #ifdef HAVE_OPENR2 09479 if (p->mfcr2 && !p->mfcr2_call_accepted) { 09480 ast_mutex_unlock(&p->lock); 09481 /* if this is an R2 call and the call is not yet accepted, we don't want the 09482 tone indications to mess up with the MF tones */ 09483 return 0; 09484 } 09485 #endif 09486 idx = dahdi_get_index(chan, p, 0); 09487 if (idx == SUB_REAL) { 09488 switch (condition) { 09489 case AST_CONTROL_BUSY: 09490 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_BUSY); 09491 break; 09492 case AST_CONTROL_RINGING: 09493 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_RINGTONE); 09494 09495 if (chan->_state != AST_STATE_UP) { 09496 if ((chan->_state != AST_STATE_RING) || 09497 ((p->sig != SIG_FXSKS) && 09498 (p->sig != SIG_FXSLS) && 09499 (p->sig != SIG_FXSGS))) 09500 ast_setstate(chan, AST_STATE_RINGING); 09501 } 09502 break; 09503 case AST_CONTROL_INCOMPLETE: 09504 ast_debug(1, "Received AST_CONTROL_INCOMPLETE on %s\n", chan->name); 09505 /* act as a progress or proceeding, allowing the caller to enter additional numbers */ 09506 res = 0; 09507 break; 09508 case AST_CONTROL_PROCEEDING: 09509 ast_debug(1, "Received AST_CONTROL_PROCEEDING on %s\n", chan->name); 09510 /* don't continue in ast_indicate */ 09511 res = 0; 09512 break; 09513 case AST_CONTROL_PROGRESS: 09514 ast_debug(1, "Received AST_CONTROL_PROGRESS on %s\n", chan->name); 09515 /* don't continue in ast_indicate */ 09516 res = 0; 09517 break; 09518 case AST_CONTROL_CONGESTION: 09519 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */ 09520 switch (chan->hangupcause) { 09521 case AST_CAUSE_USER_BUSY: 09522 case AST_CAUSE_NORMAL_CLEARING: 09523 case 0:/* Cause has not been set. */ 09524 /* Supply a more appropriate cause. */ 09525 chan->hangupcause = AST_CAUSE_CONGESTION; 09526 break; 09527 default: 09528 break; 09529 } 09530 break; 09531 case AST_CONTROL_HOLD: 09532 ast_moh_start(chan, data, p->mohinterpret); 09533 break; 09534 case AST_CONTROL_UNHOLD: 09535 ast_moh_stop(chan); 09536 break; 09537 case AST_CONTROL_RADIO_KEY: 09538 if (p->radio) 09539 res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 09540 res = 0; 09541 break; 09542 case AST_CONTROL_RADIO_UNKEY: 09543 if (p->radio) 09544 res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_RINGOFF); 09545 res = 0; 09546 break; 09547 case AST_CONTROL_FLASH: 09548 /* flash hookswitch */ 09549 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 09550 /* Clear out the dial buffer */ 09551 p->dop.dialstr[0] = '\0'; 09552 if ((ioctl(p->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 09553 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 09554 chan->name, strerror(errno)); 09555 } else 09556 res = 0; 09557 } else 09558 res = 0; 09559 break; 09560 case AST_CONTROL_SRCUPDATE: 09561 res = 0; 09562 break; 09563 case -1: 09564 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 09565 break; 09566 } 09567 } else { 09568 res = 0; 09569 } 09570 ast_mutex_unlock(&p->lock); 09571 return res; 09572 }
Definition at line 7211 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_pvt::channel, LOG_WARNING, dahdi_pvt::master, MAX_SLAVES, and dahdi_pvt::slaves.
Referenced by dahdi_bridge().
07211 { 07212 int x; 07213 if (!slave || !master) { 07214 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 07215 return; 07216 } 07217 for (x = 0; x < MAX_SLAVES; x++) { 07218 if (!master->slaves[x]) { 07219 master->slaves[x] = slave; 07220 break; 07221 } 07222 } 07223 if (x >= MAX_SLAVES) { 07224 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 07225 master->slaves[MAX_SLAVES - 1] = slave; 07226 } 07227 if (slave->master) 07228 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 07229 slave->master = master; 07230 07231 ast_debug(1, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 07232 }
| static void dahdi_lock_sub_owner | ( | struct dahdi_pvt * | pvt, | |
| int | sub_idx | |||
| ) | [static] |
Definition at line 3806 of file chan_dahdi.c.
References ast_channel_trylock, DEADLOCK_AVOIDANCE, dahdi_pvt::lock, dahdi_subchannel::owner, and dahdi_pvt::subs.
Referenced by wakeup_sub().
03807 { 03808 for (;;) { 03809 if (!pvt->subs[sub_idx].owner) { 03810 /* No subchannel owner pointer */ 03811 break; 03812 } 03813 if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) { 03814 /* Got subchannel owner lock */ 03815 break; 03816 } 03817 /* We must unlock the private to avoid the possibility of a deadlock */ 03818 DEADLOCK_AVOIDANCE(&pvt->lock); 03819 } 03820 }
| static struct ast_channel * dahdi_new | ( | struct dahdi_pvt * | i, | |
| int | state, | |||
| int | startpbx, | |||
| int | idx, | |||
| int | law, | |||
| const char * | linkedid | |||
| ) | [static, read] |
Definition at line 9622 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_DEVSTATE_NOT_CACHABLE, ast_dsp_new(), 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_FLAG_DISABLE_DEVSTATE_CACHE, 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::busy_quietlength, dahdi_pvt::busy_tonelength, dahdi_pvt::busycount, dahdi_pvt::busydetect, 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, dahdi_pvt::cc_params, CHAN_PSEUDO, dahdi_pvt::channel, 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_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_channel::flags, 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, LOG_WARNING, dahdi_pvt::muting, ast_variable::name, ast_party_id::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::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, ast_party_dialed::str, ast_party_number::str, SUB_REAL, 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_request(), do_monitor(), handle_init_event(), mwi_thread(), and my_new_analog_ast_channel().
09623 { 09624 struct ast_channel *tmp; 09625 format_t deflaw; 09626 int x; 09627 int features; 09628 struct ast_str *chan_name; 09629 struct ast_variable *v; 09630 char *dashptr; 09631 char device_name[AST_CHANNEL_NAME]; 09632 09633 if (i->subs[idx].owner) { 09634 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[idx]); 09635 return NULL; 09636 } 09637 09638 #if defined(HAVE_PRI) 09639 /* 09640 * The dnid has been stuffed with the called-number[:subaddress] 09641 * by dahdi_request() for outgoing calls. 09642 */ 09643 chan_name = create_channel_name(i, i->outgoing, i->dnid); 09644 #else 09645 chan_name = create_channel_name(i); 09646 #endif /* defined(HAVE_PRI) */ 09647 if (!chan_name) { 09648 return NULL; 09649 } 09650 09651 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)); 09652 ast_free(chan_name); 09653 if (!tmp) 09654 return NULL; 09655 tmp->tech = &dahdi_tech; 09656 #if defined(HAVE_PRI) 09657 if (i->pri) { 09658 ast_cc_copy_config_params(i->cc_params, i->pri->cc_params); 09659 } 09660 #endif /* defined(HAVE_PRI) */ 09661 ast_channel_cc_params_init(tmp, i->cc_params); 09662 if (law) { 09663 i->law = law; 09664 if (law == DAHDI_LAW_ALAW) { 09665 deflaw = AST_FORMAT_ALAW; 09666 } else { 09667 deflaw = AST_FORMAT_ULAW; 09668 } 09669 } else { 09670 switch (i->sig) { 09671 case SIG_PRI_LIB_HANDLE_CASES: 09672 /* Make sure companding law is known. */ 09673 i->law = (i->law_default == DAHDI_LAW_ALAW) 09674 ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW; 09675 break; 09676 default: 09677 i->law = i->law_default; 09678 break; 09679 } 09680 if (i->law_default == DAHDI_LAW_ALAW) { 09681 deflaw = AST_FORMAT_ALAW; 09682 } else { 09683 deflaw = AST_FORMAT_ULAW; 09684 } 09685 } 09686 ast_channel_set_fd(tmp, 0, i->subs[idx].dfd); 09687 tmp->nativeformats = deflaw; 09688 /* Start out assuming ulaw since it's smaller :) */ 09689 tmp->rawreadformat = deflaw; 09690 tmp->readformat = deflaw; 09691 tmp->rawwriteformat = deflaw; 09692 tmp->writeformat = deflaw; 09693 i->subs[idx].linear = 0; 09694 dahdi_setlinear(i->subs[idx].dfd, i->subs[idx].linear); 09695 features = 0; 09696 if (idx == SUB_REAL) { 09697 if (i->busydetect && CANBUSYDETECT(i)) 09698 features |= DSP_FEATURE_BUSY_DETECT; 09699 if ((i->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(i)) 09700 features |= DSP_FEATURE_CALL_PROGRESS; 09701 if ((i->waitfordialtone) && CANPROGRESSDETECT(i)) 09702 features |= DSP_FEATURE_WAITDIALTONE; 09703 if ((!i->outgoing && (i->callprogress & CALLPROGRESS_FAX_INCOMING)) || 09704 (i->outgoing && (i->callprogress & CALLPROGRESS_FAX_OUTGOING))) { 09705 features |= DSP_FEATURE_FAX_DETECT; 09706 } 09707 x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE; 09708 if (ioctl(i->subs[idx].dfd, DAHDI_TONEDETECT, &x)) { 09709 i->hardwaredtmf = 0; 09710 features |= DSP_FEATURE_DIGIT_DETECT; 09711 } else if (NEED_MFDETECT(i)) { 09712 i->hardwaredtmf = 1; 09713 features |= DSP_FEATURE_DIGIT_DETECT; 09714 } 09715 } 09716 if (features) { 09717 if (i->dsp) { 09718 ast_debug(1, "Already have a dsp on %s?\n", tmp->name); 09719 } else { 09720 if (i->channel != CHAN_PSEUDO) 09721 i->dsp = ast_dsp_new(); 09722 else 09723 i->dsp = NULL; 09724 if (i->dsp) { 09725 i->dsp_features = features; 09726 #if defined(HAVE_PRI) || defined(HAVE_SS7) 09727 /* We cannot do progress detection until receive PROGRESS message */ 09728 if (i->outgoing && (dahdi_sig_pri_lib_handles(i->sig) || (i->sig == SIG_SS7))) { 09729 /* Remember requested DSP features, don't treat 09730 talking as ANSWER */ 09731 i->dsp_features = features & ~DSP_PROGRESS_TALK; 09732 features = 0; 09733 } 09734 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 09735 ast_dsp_set_features(i->dsp, features); 09736 ast_dsp_set_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 09737 if (!ast_strlen_zero(progzone)) 09738 ast_dsp_set_call_progress_zone(i->dsp, progzone); 09739 if (i->busydetect && CANBUSYDETECT(i)) { 09740 ast_dsp_set_busy_count(i->dsp, i->busycount); 09741 ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength); 09742 } 09743 } 09744 } 09745 } 09746 09747 if (state == AST_STATE_RING) 09748 tmp->rings = 1; 09749 tmp->tech_pvt = i; 09750 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 09751 /* Only FXO signalled stuff can be picked up */ 09752 tmp->callgroup = i->callgroup; 09753 tmp->pickupgroup = i->pickupgroup; 09754 } 09755 if (!ast_strlen_zero(i->parkinglot)) 09756 ast_string_field_set(tmp, parkinglot, i->parkinglot); 09757 if (!ast_strlen_zero(i->language)) 09758 ast_string_field_set(tmp, language, i->language); 09759 if (!i->owner) 09760 i->owner = tmp; 09761 if (!ast_strlen_zero(i->accountcode)) 09762 ast_string_field_set(tmp, accountcode, i->accountcode); 09763 if (i->amaflags) 09764 tmp->amaflags = i->amaflags; 09765 i->subs[idx].owner = tmp; 09766 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 09767 if (!analog_lib_handles(i->sig, i->radio, i->oprmode)) { 09768 ast_string_field_set(tmp, call_forward, i->call_forward); 09769 } 09770 /* If we've been told "no ADSI" then enforce it */ 09771 if (!i->adsi) 09772 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 09773 if (!ast_strlen_zero(i->exten)) 09774 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 09775 if (!ast_strlen_zero(i->rdnis)) { 09776 tmp->redirecting.from.number.valid = 1; 09777 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 09778 } 09779 if (!ast_strlen_zero(i->dnid)) { 09780 tmp->dialed.number.str = ast_strdup(i->dnid); 09781 } 09782 09783 /* Don't use ast_set_callerid() here because it will 09784 * generate a needless NewCallerID event */ 09785 #if defined(HAVE_PRI) || defined(HAVE_SS7) 09786 if (!ast_strlen_zero(i->cid_ani)) { 09787 tmp->caller.ani.number.valid = 1; 09788 tmp->caller.ani.number.str = ast_strdup(i->cid_ani); 09789 } else if (!ast_strlen_zero(i->cid_num)) { 09790 tmp->caller.ani.number.valid = 1; 09791 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 09792 } 09793 #else 09794 if (!ast_strlen_zero(i->cid_num)) { 09795 tmp->caller.ani.number.valid = 1; 09796 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 09797 } 09798 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 09799 tmp->caller.id.name.presentation = i->callingpres; 09800 tmp->caller.id.number.presentation = i->callingpres; 09801 tmp->caller.id.number.plan = i->cid_ton; 09802 tmp->caller.ani2 = i->cid_ani2; 09803 tmp->caller.id.tag = ast_strdup(i->cid_tag); 09804 /* clear the fake event in case we posted one before we had ast_channel */ 09805 i->fake_event = 0; 09806 /* Assure there is no confmute on this channel */ 09807 dahdi_confmute(i, 0); 09808 i->muting = 0; 09809 /* Configure the new channel jb */ 09810 ast_jb_configure(tmp, &global_jbconf); 09811 09812 /* Set initial device state */ 09813 ast_copy_string(device_name, tmp->name, sizeof(device_name)); 09814 dashptr = strrchr(device_name, '-'); 09815 if (dashptr) { 09816 *dashptr = '\0'; 09817 } 09818 tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE; 09819 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, device_name); 09820 09821 for (v = i->vars ; v ; v = v->next) 09822 pbx_builtin_setvar_helper(tmp, v->name, v->value); 09823 09824 ast_module_ref(ast_module_info->self); 09825 09826 dahdi_ami_channel_event(i, tmp); 09827 if (startpbx) { 09828 #ifdef HAVE_OPENR2 09829 if (i->mfcr2call) { 09830 pbx_builtin_setvar_helper(tmp, "MFCR2_CATEGORY", openr2_proto_get_category_string(i->mfcr2_recvd_category)); 09831 } 09832 #endif 09833 if (ast_pbx_start(tmp)) { 09834 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 09835 ast_hangup(tmp); 09836 return NULL; 09837 } 09838 } 09839 return tmp; 09840 }
| static int dahdi_open | ( | char * | fn | ) | [static] |
Definition at line 4343 of file chan_dahdi.c.
References ast_log(), errno, LOG_WARNING, and READ_SIZE.
Referenced by alloc_sub(), duplicate_pseudo(), and mkintf().
04344 { 04345 int fd; 04346 int isnum; 04347 int chan = 0; 04348 int bs; 04349 int x; 04350 isnum = 1; 04351 for (x = 0; x < strlen(fn); x++) { 04352 if (!isdigit(fn[x])) { 04353 isnum = 0; 04354 break; 04355 } 04356 } 04357 if (isnum) { 04358 chan = atoi(fn); 04359 if (chan < 1) { 04360 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn); 04361 return -1; 04362 } 04363 fn = "/dev/dahdi/channel"; 04364 } 04365 fd = open(fn, O_RDWR | O_NONBLOCK); 04366 if (fd < 0) { 04367 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno)); 04368 return -1; 04369 } 04370 if (chan) { 04371 if (ioctl(fd, DAHDI_SPECIFY, &chan)) { 04372 x = errno; 04373 close(fd); 04374 errno = x; 04375 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno)); 04376 return -1; 04377 } 04378 } 04379 bs = READ_SIZE; 04380 if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) { 04381 ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno)); 04382 x = errno; 04383 close(fd); 04384 errno = x; 04385 return -1; 04386 } 04387 return fd; 04388 }
| static int dahdi_queryoption | ( | struct ast_channel * | chan, | |
| int | option, | |||
| void * | data, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6682 of file chan_dahdi.c.
References ast_copy_string(), ast_debug, AST_OPTION_CC_AGENT_TYPE, AST_OPTION_DIGIT_DETECT, AST_OPTION_FAX_DETECT, dahdi_sig_pri_lib_handles(), DSP_FEATURE_FAX_DETECT, dahdi_pvt::dsp_features, errno, dahdi_pvt::ignoredtmf, dahdi_pvt::sig, and ast_channel::tech_pvt.
06683 { 06684 char *cp; 06685 struct dahdi_pvt *p = chan->tech_pvt; 06686 06687 /* all supported options require data */ 06688 if (!p || !data || (*datalen < 1)) { 06689 errno = EINVAL; 06690 return -1; 06691 } 06692 06693 switch (option) { 06694 case AST_OPTION_DIGIT_DETECT: 06695 cp = (char *) data; 06696 *cp = p->ignoredtmf ? 0 : 1; 06697 ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name); 06698 break; 06699 case AST_OPTION_FAX_DETECT: 06700 cp = (char *) data; 06701 *cp = (p->dsp_features & DSP_FEATURE_FAX_DETECT) ? 0 : 1; 06702 ast_debug(1, "Reporting fax tone detection %sabled on %s\n", *cp ? "en" : "dis", chan->name); 06703 break; 06704 case AST_OPTION_CC_AGENT_TYPE: 06705 #if defined(HAVE_PRI) 06706 #if defined(HAVE_PRI_CCSS) 06707 if (dahdi_sig_pri_lib_handles(p->sig)) { 06708 ast_copy_string((char *) data, dahdi_pri_cc_type, *datalen); 06709 break; 06710 } 06711 #endif /* defined(HAVE_PRI_CCSS) */ 06712 #endif /* defined(HAVE_PRI) */ 06713 return -1; 06714 default: 06715 return -1; 06716 } 06717 06718 errno = 0; 06719 06720 return 0; 06721 }
Definition at line 3831 of file chan_dahdi.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_frame(), DEADLOCK_AVOIDANCE, dahdi_pvt::lock, and dahdi_pvt::owner.
Referenced by action_dahdidialoffhook().
03832 { 03833 for (;;) { 03834 if (p->owner) { 03835 if (ast_channel_trylock(p->owner)) { 03836 DEADLOCK_AVOIDANCE(&p->lock); 03837 } else { 03838 ast_queue_frame(p->owner, f); 03839 ast_channel_unlock(p->owner); 03840 break; 03841 } 03842 } else 03843 break; 03844 } 03845 }
| static struct ast_frame * dahdi_read | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 8930 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, dahdi_pvt::fake_event, dahdi_pvt::firstradio, ast_frame::frametype, dahdi_pvt::ignoredtmf, dahdi_pvt::inalarm, ast_frame_subclass::integer, dahdi_subchannel::inthreeway, dahdi_subchannel::linear, dahdi_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, mute, dahdi_pvt::muting, 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, dahdi_pvt::owner, ast_frame::ptr, dahdi_pvt::pulsedial, 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.
08931 { 08932 struct dahdi_pvt *p; 08933 int res; 08934 int idx; 08935 void *readbuf; 08936 struct ast_frame *f; 08937 08938 /* 08939 * For analog channels, we must do deadlock avoidance because 08940 * analog ports can have more than one Asterisk channel using 08941 * the same private structure. 08942 */ 08943 p = ast->tech_pvt; 08944 while (ast_mutex_trylock(&p->lock)) { 08945 CHANNEL_DEADLOCK_AVOIDANCE(ast); 08946 08947 /* 08948 * Check to see if the channel is still associated with the same 08949 * private structure. While the Asterisk channel was unlocked 08950 * the following events may have occured: 08951 * 08952 * 1) A masquerade may have associated the channel with another 08953 * technology or private structure. 08954 * 08955 * 2) For PRI calls, call signaling could change the channel 08956 * association to another B channel (private structure). 08957 */ 08958 if (ast->tech_pvt != p) { 08959 /* The channel is no longer associated. Quit gracefully. */ 08960 return &ast_null_frame; 08961 } 08962 } 08963 08964 idx = dahdi_get_index(ast, p, 0); 08965 08966 /* Hang up if we don't really exist */ 08967 if (idx < 0) { 08968 ast_log(LOG_WARNING, "We don't exist?\n"); 08969 ast_mutex_unlock(&p->lock); 08970 return NULL; 08971 } 08972 08973 if ((p->radio || (p->oprmode < 0)) && p->inalarm) { 08974 ast_mutex_unlock(&p->lock); 08975 return NULL; 08976 } 08977 08978 p->subs[idx].f.frametype = AST_FRAME_NULL; 08979 p->subs[idx].f.datalen = 0; 08980 p->subs[idx].f.samples = 0; 08981 p->subs[idx].f.mallocd = 0; 08982 p->subs[idx].f.offset = 0; 08983 p->subs[idx].f.subclass.integer = 0; 08984 p->subs[idx].f.delivery = ast_tv(0,0); 08985 p->subs[idx].f.src = "dahdi_read"; 08986 p->subs[idx].f.data.ptr = NULL; 08987 08988 /* make sure it sends initial key state as first frame */ 08989 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio)) 08990 { 08991 struct dahdi_params ps; 08992 08993 memset(&ps, 0, sizeof(ps)); 08994 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) { 08995 ast_mutex_unlock(&p->lock); 08996 return NULL; 08997 } 08998 p->firstradio = 1; 08999 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09000 if (ps.rxisoffhook) 09001 { 09002 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_KEY; 09003 } 09004 else 09005 { 09006 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_UNKEY; 09007 } 09008 ast_mutex_unlock(&p->lock); 09009 return &p->subs[idx].f; 09010 } 09011 if (p->ringt > 0) { 09012 if (!(--p->ringt)) { 09013 ast_mutex_unlock(&p->lock); 09014 return NULL; 09015 } 09016 } 09017 09018 #ifdef HAVE_OPENR2 09019 if (p->mfcr2) { 09020 openr2_chan_process_event(p->r2chan); 09021 if (OR2_DIR_FORWARD == openr2_chan_get_direction(p->r2chan)) { 09022 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_PROGRESS }, }; 09023 /* if the call is already accepted and we already delivered AST_CONTROL_RINGING 09024 * now enqueue a progress frame to bridge the media up */ 09025 if (p->mfcr2_call_accepted && 09026 !p->mfcr2_progress && 09027 ast->_state == AST_STATE_RINGING) { 09028 ast_log(LOG_DEBUG, "Enqueuing progress frame after R2 accept in chan %d\n", p->channel); 09029 ast_queue_frame(p->owner, &f); 09030 p->mfcr2_progress = 1; 09031 } 09032 } 09033 } 09034 #endif 09035 09036 if (p->subs[idx].needringing) { 09037 /* Send ringing frame if requested */ 09038 p->subs[idx].needringing = 0; 09039 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09040 p->subs[idx].f.subclass.integer = AST_CONTROL_RINGING; 09041 ast_setstate(ast, AST_STATE_RINGING); 09042 ast_mutex_unlock(&p->lock); 09043 return &p->subs[idx].f; 09044 } 09045 09046 if (p->subs[idx].needbusy) { 09047 /* Send busy frame if requested */ 09048 p->subs[idx].needbusy = 0; 09049 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09050 p->subs[idx].f.subclass.integer = AST_CONTROL_BUSY; 09051 ast_mutex_unlock(&p->lock); 09052 return &p->subs[idx].f; 09053 } 09054 09055 if (p->subs[idx].needcongestion) { 09056 /* Send congestion frame if requested */ 09057 p->subs[idx].needcongestion = 0; 09058 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09059 p->subs[idx].f.subclass.integer = AST_CONTROL_CONGESTION; 09060 ast_mutex_unlock(&p->lock); 09061 return &p->subs[idx].f; 09062 } 09063 09064 if (p->subs[idx].needanswer) { 09065 /* Send answer frame if requested */ 09066 p->subs[idx].needanswer = 0; 09067 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09068 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 09069 ast_mutex_unlock(&p->lock); 09070 return &p->subs[idx].f; 09071 } 09072 #ifdef HAVE_OPENR2 09073 if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) { 09074 /* openr2 took care of reading and handling any event 09075 (needanswer, needbusy etc), if we continue we will read() 09076 twice, lets just return a null frame. This should only 09077 happen when openr2 is dialing out */ 09078 ast_mutex_unlock(&p->lock); 09079 return &ast_null_frame; 09080 } 09081 #endif 09082 09083 if (p->subs[idx].needflash) { 09084 /* Send answer frame if requested */ 09085 p->subs[idx].needflash = 0; 09086 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09087 p->subs[idx].f.subclass.integer = AST_CONTROL_FLASH; 09088 ast_mutex_unlock(&p->lock); 09089 return &p->subs[idx].f; 09090 } 09091 09092 if (p->subs[idx].needhold) { 09093 /* Send answer frame if requested */ 09094 p->subs[idx].needhold = 0; 09095 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09096 p->subs[idx].f.subclass.integer = AST_CONTROL_HOLD; 09097 ast_mutex_unlock(&p->lock); 09098 ast_debug(1, "Sending hold on '%s'\n", ast->name); 09099 return &p->subs[idx].f; 09100 } 09101 09102 if (p->subs[idx].needunhold) { 09103 /* Send answer frame if requested */ 09104 p->subs[idx].needunhold = 0; 09105 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09106 p->subs[idx].f.subclass.integer = AST_CONTROL_UNHOLD; 09107 ast_mutex_unlock(&p->lock); 09108 ast_debug(1, "Sending unhold on '%s'\n", ast->name); 09109 return &p->subs[idx].f; 09110 } 09111 09112 /* 09113 * If we have a fake_event, fake an exception to handle it only 09114 * if this channel owns the private. 09115 */ 09116 if (p->fake_event && p->owner == ast) { 09117 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09118 struct analog_pvt *analog_p = p->sig_pvt; 09119 09120 f = analog_exception(analog_p, ast); 09121 } else { 09122 f = __dahdi_exception(ast); 09123 } 09124 ast_mutex_unlock(&p->lock); 09125 return f; 09126 } 09127 09128 if (ast->rawreadformat == AST_FORMAT_SLINEAR) { 09129 if (!p->subs[idx].linear) { 09130 p->subs[idx].linear = 1; 09131 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09132 if (res) 09133 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, idx); 09134 } 09135 } else if ((ast->rawreadformat == AST_FORMAT_ULAW) || 09136 (ast->rawreadformat == AST_FORMAT_ALAW)) { 09137 if (p->subs[idx].linear) { 09138 p->subs[idx].linear = 0; 09139 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09140 if (res) 09141 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, idx); 09142 } 09143 } else { 09144 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat)); 09145 ast_mutex_unlock(&p->lock); 09146 return NULL; 09147 } 09148 readbuf = ((unsigned char *)p->subs[idx].buffer) + AST_FRIENDLY_OFFSET; 09149 CHECK_BLOCKING(ast); 09150 res = read(p->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE); 09151 ast_clear_flag(ast, AST_FLAG_BLOCKING); 09152 /* Check for hangup */ 09153 if (res < 0) { 09154 f = NULL; 09155 if (res == -1) { 09156 if (errno == EAGAIN) { 09157 /* Return "NULL" frame if there is nobody there */ 09158 ast_mutex_unlock(&p->lock); 09159 return &p->subs[idx].f; 09160 } else if (errno == ELAST) { 09161 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09162 struct analog_pvt *analog_p = p->sig_pvt; 09163 f = analog_exception(analog_p, ast); 09164 } else { 09165 f = __dahdi_exception(ast); 09166 } 09167 } else 09168 ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno)); 09169 } 09170 ast_mutex_unlock(&p->lock); 09171 return f; 09172 } 09173 if (res != (p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE)) { 09174 ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE); 09175 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09176 struct analog_pvt *analog_p = p->sig_pvt; 09177 f = analog_exception(analog_p, ast); 09178 } else { 09179 f = __dahdi_exception(ast); 09180 } 09181 ast_mutex_unlock(&p->lock); 09182 return f; 09183 } 09184 if (p->tdd) { /* if in TDD mode, see if we receive that */ 09185 int c; 09186 09187 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 09188 if (c < 0) { 09189 ast_debug(1,"tdd_feed failed\n"); 09190 ast_mutex_unlock(&p->lock); 09191 return NULL; 09192 } 09193 if (c) { /* if a char to return */ 09194 p->subs[idx].f.subclass.integer = 0; 09195 p->subs[idx].f.frametype = AST_FRAME_TEXT; 09196 p->subs[idx].f.mallocd = 0; 09197 p->subs[idx].f.offset = AST_FRIENDLY_OFFSET; 09198 p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET; 09199 p->subs[idx].f.datalen = 1; 09200 *((char *) p->subs[idx].f.data.ptr) = c; 09201 ast_mutex_unlock(&p->lock); 09202 return &p->subs[idx].f; 09203 } 09204 } 09205 if (idx == SUB_REAL) { 09206 /* Ensure the CW timers decrement only on a single subchannel */ 09207 if (p->cidcwexpire) { 09208 if (!--p->cidcwexpire) { 09209 /* Expired CID/CW */ 09210 ast_verb(3, "CPE does not support Call Waiting Caller*ID.\n"); 09211 restore_conference(p); 09212 } 09213 } 09214 if (p->cid_suppress_expire) { 09215 --p->cid_suppress_expire; 09216 } 09217 if (p->callwaitingrepeat) { 09218 if (!--p->callwaitingrepeat) { 09219 /* Expired, Repeat callwaiting tone */ 09220 ++p->callwaitrings; 09221 dahdi_callwait(ast); 09222 } 09223 } 09224 } 09225 if (p->subs[idx].linear) { 09226 p->subs[idx].f.datalen = READ_SIZE * 2; 09227 } else 09228 p->subs[idx].f.datalen = READ_SIZE; 09229 09230 /* Handle CallerID Transmission */ 09231 if ((p->owner == ast) && p->cidspill) { 09232 send_callerid(p); 09233 } 09234 09235 p->subs[idx].f.frametype = AST_FRAME_VOICE; 09236 p->subs[idx].f.subclass.codec = ast->rawreadformat; 09237 p->subs[idx].f.samples = READ_SIZE; 09238 p->subs[idx].f.mallocd = 0; 09239 p->subs[idx].f.offset = AST_FRIENDLY_OFFSET; 09240 p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[idx].buffer[0]); 09241 #if 0 09242 ast_debug(1, "Read %d of voice on %s\n", p->subs[idx].f.datalen, ast->name); 09243 #endif 09244 if (p->dialing || p->radio || /* Transmitting something */ 09245 (idx && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 09246 ((idx == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 09247 ) { 09248 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 09249 don't send anything */ 09250 p->subs[idx].f.frametype = AST_FRAME_NULL; 09251 p->subs[idx].f.subclass.integer = 0; 09252 p->subs[idx].f.samples = 0; 09253 p->subs[idx].f.mallocd = 0; 09254 p->subs[idx].f.offset = 0; 09255 p->subs[idx].f.data.ptr = NULL; 09256 p->subs[idx].f.datalen= 0; 09257 } 09258 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress || p->waitingfordt.tv_sec) && !idx) { 09259 /* Perform busy detection etc on the dahdi line */ 09260 int mute; 09261 09262 f = ast_dsp_process(ast, p->dsp, &p->subs[idx].f); 09263 09264 /* Check if DSP code thinks we should be muting this frame and mute the conference if so */ 09265 mute = ast_dsp_was_muted(p->dsp); 09266 if (p->muting != mute) { 09267 p->muting = mute; 09268 dahdi_confmute(p, mute); 09269 } 09270 09271 if (f) { 09272 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_BUSY)) { 09273 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 09274 /* Treat this as a "hangup" instead of a "busy" on the assumption that 09275 a busy */ 09276 ast_frfree(f); 09277 f = NULL; 09278 } 09279 } else if (f->frametype == AST_FRAME_DTMF_BEGIN 09280 || f->frametype == AST_FRAME_DTMF_END) { 09281 #ifdef HAVE_PRI 09282 if (dahdi_sig_pri_lib_handles(p->sig) 09283 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING 09284 && p->pri 09285 && ((!p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) 09286 || (p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)))) { 09287 /* Don't accept in-band DTMF when in overlap dial mode */ 09288 ast_debug(1, "Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n", 09289 f->frametype == AST_FRAME_DTMF_BEGIN ? "begin" : "end", 09290 f->subclass.integer, f->subclass.integer, ast->name); 09291 09292 f->frametype = AST_FRAME_NULL; 09293 f->subclass.integer = 0; 09294 } 09295 #endif 09296 /* DSP clears us of being pulse */ 09297 p->pulsedial = 0; 09298 } else if (p->waitingfordt.tv_sec) { 09299 if (ast_tvdiff_ms(ast_tvnow(), p->waitingfordt) >= p->waitfordialtone ) { 09300 p->waitingfordt.tv_sec = 0; 09301 ast_log(LOG_WARNING, "Never saw dialtone on channel %d\n", p->channel); 09302 ast_frfree(f); 09303 f = NULL; 09304 } else if (f->frametype == AST_FRAME_VOICE) { 09305 f->frametype = AST_FRAME_NULL; 09306 f->subclass.integer = 0; 09307 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) { 09308 p->waitingfordt.tv_sec = 0; 09309 p->dsp_features &= ~DSP_FEATURE_WAITDIALTONE; 09310 ast_dsp_set_features(p->dsp, p->dsp_features); 09311 ast_log(LOG_DEBUG, "Got 10 samples of dialtone!\n"); 09312 if (!ast_strlen_zero(p->dop.dialstr)) { /* Dial deferred digits */ 09313 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 09314 if (res < 0) { 09315 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 09316 p->dop.dialstr[0] = '\0'; 09317 ast_mutex_unlock(&p->lock); 09318 ast_frfree(f); 09319 return NULL; 09320 } else { 09321 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr); 09322 p->dialing = 1; 09323 p->dop.dialstr[0] = '\0'; 09324 p->dop.op = DAHDI_DIAL_OP_REPLACE; 09325 ast_setstate(ast, AST_STATE_DIALING); 09326 } 09327 } 09328 } 09329 } 09330 } 09331 } 09332 } else 09333 f = &p->subs[idx].f; 09334 09335 if (f) { 09336 switch (f->frametype) { 09337 case AST_FRAME_DTMF_BEGIN: 09338 case AST_FRAME_DTMF_END: 09339 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09340 analog_handle_dtmf(p->sig_pvt, ast, idx, &f); 09341 } else { 09342 dahdi_handle_dtmf(ast, idx, &f); 09343 } 09344 break; 09345 case AST_FRAME_VOICE: 09346 if (p->cidspill || p->cid_suppress_expire) { 09347 /* We are/were sending a caller id spill. Suppress any echo. */ 09348 p->subs[idx].f.frametype = AST_FRAME_NULL; 09349 p->subs[idx].f.subclass.integer = 0; 09350 p->subs[idx].f.samples = 0; 09351 p->subs[idx].f.mallocd = 0; 09352 p->subs[idx].f.offset = 0; 09353 p->subs[idx].f.data.ptr = NULL; 09354 p->subs[idx].f.datalen= 0; 09355 } 09356 break; 09357 default: 09358 break; 09359 } 09360 } 09361 09362 ast_mutex_unlock(&p->lock); 09363 return f; 09364 }
| static struct ast_channel * dahdi_request | ( | const char * | type, | |
| format_t | format, | |||
| const struct ast_channel * | requestor, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static, read] |
Definition at line 13686 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, is_group_or_channel_match(), dahdi_pvt::lock, LOG_DEBUG, LOG_WARNING, dahdi_pvt::next, dahdi_pvt::oprmode, dahdi_starting_point::opt, dahdi_pvt::outgoing, dahdi_pvt::owner, dahdi_pvt::prev, dahdi_pvt::radio, restart_monitor(), 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.
13687 { 13688 int callwait = 0; 13689 struct dahdi_pvt *p; 13690 struct ast_channel *tmp = NULL; 13691 struct dahdi_pvt *exitpvt; 13692 int channelmatched = 0; 13693 int groupmatched = 0; 13694 #if defined(HAVE_PRI) || defined(HAVE_SS7) 13695 int transcapdigital = 0; 13696 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 13697 struct dahdi_starting_point start; 13698 13699 ast_mutex_lock(&iflock); 13700 p = determine_starting_point(data, &start); 13701 if (!p) { 13702 /* We couldn't determine a starting point, which likely means badly-formatted channel name. Abort! */ 13703 ast_mutex_unlock(&iflock); 13704 return NULL; 13705 } 13706 13707 /* Search for an unowned channel */ 13708 exitpvt = p; 13709 while (p && !tmp) { 13710 if (start.roundrobin) 13711 round_robin[start.rr_starting_point] = p; 13712 13713 if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched) 13714 && available(&p, channelmatched)) { 13715 ast_debug(1, "Using channel %d\n", p->channel); 13716 13717 callwait = (p->owner != NULL); 13718 #ifdef HAVE_OPENR2 13719 if (p->mfcr2) { 13720 ast_mutex_lock(&p->lock); 13721 if (p->mfcr2call) { 13722 ast_mutex_unlock(&p->lock); 13723 ast_log(LOG_DEBUG, "Yay!, someone just beat us in the race for channel %d.\n", p->channel); 13724 goto next; 13725 } 13726 p->mfcr2call = 1; 13727 ast_mutex_unlock(&p->lock); 13728 } 13729 #endif 13730 if (p->channel == CHAN_PSEUDO) { 13731 p = duplicate_pseudo(p); 13732 if (!p) { 13733 break; 13734 } 13735 } 13736 13737 p->distinctivering = 0; 13738 /* Make special notes */ 13739 switch (start.opt) { 13740 case '\0': 13741 /* No option present. */ 13742 break; 13743 case 'c': 13744 /* Confirm answer */ 13745 p->confirmanswer = 1; 13746 break; 13747 case 'r': 13748 /* Distinctive ring */ 13749 p->distinctivering = start.cadance; 13750 break; 13751 case 'd': 13752 #if defined(HAVE_PRI) || defined(HAVE_SS7) 13753 /* If this is an ISDN call, make it digital */ 13754 transcapdigital = AST_TRANS_CAP_DIGITAL; 13755 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 13756 break; 13757 default: 13758 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", start.opt, (char *)data); 13759 break; 13760 } 13761 13762 p->outgoing = 1; 13763 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 13764 tmp = analog_request(p->sig_pvt, &callwait, requestor); 13765 #ifdef HAVE_PRI 13766 } else if (dahdi_sig_pri_lib_handles(p->sig)) { 13767 /* 13768 * We already have the B channel reserved for this call. We 13769 * just need to make sure that dahdi_hangup() has completed 13770 * cleaning up before continuing. 13771 */ 13772 ast_mutex_lock(&p->lock); 13773 ast_mutex_unlock(&p->lock); 13774 13775 sig_pri_extract_called_num_subaddr(p->sig_pvt, data, p->dnid, 13776 sizeof(p->dnid)); 13777 tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW, requestor, transcapdigital); 13778 #endif 13779 #if defined(HAVE_SS7) 13780 } else if (p->sig == SIG_SS7) { 13781 tmp = sig_ss7_request(p->sig_pvt, SIG_SS7_DEFLAW, requestor, transcapdigital); 13782 #endif /* defined(HAVE_SS7) */ 13783 } else { 13784 tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, requestor ? requestor->linkedid : ""); 13785 } 13786 if (!tmp) { 13787 p->outgoing = 0; 13788 #if defined(HAVE_PRI) 13789 switch (p->sig) { 13790 case SIG_PRI_LIB_HANDLE_CASES: 13791 #if defined(HAVE_PRI_CALL_WAITING) 13792 if (((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting) { 13793 ((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting = 0; 13794 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1); 13795 } 13796 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 13797 /* 13798 * This should be the last thing to clear when we are done with 13799 * the channel. 13800 */ 13801 ((struct sig_pri_chan *) p->sig_pvt)->allocated = 0; 13802 break; 13803 default: 13804 break; 13805 } 13806 #endif /* defined(HAVE_PRI) */ 13807 } else { 13808 snprintf(p->dialstring, sizeof(p->dialstring), "DAHDI/%s", (char *) data); 13809 } 13810 break; 13811 } 13812 #ifdef HAVE_OPENR2 13813 next: 13814 #endif 13815 if (start.backwards) { 13816 p = p->prev; 13817 if (!p) 13818 p = ifend; 13819 } else { 13820 p = p->next; 13821 if (!p) 13822 p = iflist; 13823 } 13824 /* stop when you roll to the one that we started from */ 13825 if (p == exitpvt) 13826 break; 13827 } 13828 ast_mutex_unlock(&iflock); 13829 restart_monitor(); 13830 if (cause && !tmp) { 13831 if (callwait || channelmatched) { 13832 *cause = AST_CAUSE_BUSY; 13833 } else if (groupmatched) { 13834 *cause = AST_CAUSE_CONGESTION; 13835 } else { 13836 /* 13837 * We did not match any channel requested. 13838 * Dialplan error requesting non-existant channel? 13839 */ 13840 } 13841 } 13842 13843 return tmp; 13844 }
| static int dahdi_restart | ( | void | ) | [static] |
Definition at line 15117 of file chan_dahdi.c.
References ast_active_channels(), ast_cond_wait, ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_verb, dahdi_softhangup_all(), destroy_all_channels(), dahdi_subchannel::dfd, LOG_WARNING, dahdi_pvt::next, dahdi_pvt::owner, setup_dahdi(), sig_pri_init_pri(), sig_ss7_init_linkset(), SIG_SS7_NUM_DCHANS, SUB_REAL, and dahdi_pvt::subs.
Referenced by action_dahdirestart(), and dahdi_restart_cmd().
15118 { 15119 #if defined(HAVE_PRI) || defined(HAVE_SS7) 15120 int i, j; 15121 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 15122 int cancel_code; 15123 struct dahdi_pvt *p; 15124 15125 ast_mutex_lock(&restart_lock); 15126 ast_verb(1, "Destroying channels and reloading DAHDI configuration.\n"); 15127 dahdi_softhangup_all(); 15128 ast_verb(4, "Initial softhangup of all DAHDI channels complete.\n"); 15129 #ifdef HAVE_OPENR2 15130 dahdi_r2_destroy_links(); 15131 #endif 15132 15133 #if defined(HAVE_PRI) 15134 for (i = 0; i < NUM_SPANS; i++) { 15135 if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) { 15136 cancel_code = pthread_cancel(pris[i].pri.master); 15137 pthread_kill(pris[i].pri.master, SIGURG); 15138 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); 15139 pthread_join(pris[i].pri.master, NULL); 15140 ast_debug(4, "Joined thread of span %d\n", i); 15141 } 15142 } 15143 #endif 15144 15145 #if defined(HAVE_SS7) 15146 for (i = 0; i < NUM_SPANS; i++) { 15147 if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) { 15148 cancel_code = pthread_cancel(linksets[i].ss7.master); 15149 pthread_kill(linksets[i].ss7.master, SIGURG); 15150 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); 15151 pthread_join(linksets[i].ss7.master, NULL); 15152 ast_debug(4, "Joined thread of span %d\n", i); 15153 } 15154 } 15155 #endif /* defined(HAVE_SS7) */ 15156 15157 ast_mutex_lock(&monlock); 15158 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 15159 cancel_code = pthread_cancel(monitor_thread); 15160 pthread_kill(monitor_thread, SIGURG); 15161 ast_debug(4, "Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (void *) monitor_thread, cancel_code); 15162 pthread_join(monitor_thread, NULL); 15163 ast_debug(4, "Joined monitor thread\n"); 15164 } 15165 monitor_thread = AST_PTHREADT_NULL; /* prepare to restart thread in setup_dahdi once channels are reconfigured */ 15166 15167 ast_mutex_lock(&ss_thread_lock); 15168 while (ss_thread_count > 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */ 15169 int x = DAHDI_FLASH; 15170 ast_debug(3, "Waiting on %d analog_ss_thread(s) to finish\n", ss_thread_count); 15171 15172 ast_mutex_lock(&iflock); 15173 for (p = iflist; p; p = p->next) { 15174 if (p->owner) { 15175 /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */ 15176 ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 15177 } 15178 } 15179 ast_mutex_unlock(&iflock); 15180 ast_cond_wait(&ss_thread_complete, &ss_thread_lock); 15181 } 15182 15183 /* ensure any created channels before monitor threads were stopped are hungup */ 15184 dahdi_softhangup_all(); 15185 ast_verb(4, "Final softhangup of all DAHDI channels complete.\n"); 15186 destroy_all_channels(); 15187 memset(round_robin, 0, sizeof(round_robin)); 15188 ast_debug(1, "Channels destroyed. Now re-reading config. %d active channels remaining.\n", ast_active_channels()); 15189 15190 ast_mutex_unlock(&monlock); 15191 15192 #ifdef HAVE_PRI 15193 for (i = 0; i < NUM_SPANS; i++) { 15194 for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) 15195 dahdi_close_pri_fd(&(pris[i]), j); 15196 } 15197 15198 memset(pris, 0, sizeof(pris)); 15199 for (i = 0; i < NUM_SPANS; i++) { 15200 sig_pri_init_pri(&pris[i].pri); 15201 } 15202 pri_set_error(dahdi_pri_error); 15203 pri_set_message(dahdi_pri_message); 15204 #endif 15205 #if defined(HAVE_SS7) 15206 for (i = 0; i < NUM_SPANS; i++) { 15207 for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) 15208 dahdi_close_ss7_fd(&(linksets[i]), j); 15209 } 15210 15211 memset(linksets, 0, sizeof(linksets)); 15212 for (i = 0; i < NUM_SPANS; i++) { 15213 sig_ss7_init_linkset(&linksets[i].ss7); 15214 } 15215 ss7_set_error(dahdi_ss7_error); 15216 ss7_set_message(dahdi_ss7_message); 15217 #endif /* defined(HAVE_SS7) */ 15218 15219 if (setup_dahdi(2) != 0) { 15220 ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n"); 15221 ast_mutex_unlock(&ss_thread_lock); 15222 return 1; 15223 } 15224 ast_mutex_unlock(&ss_thread_lock); 15225 ast_mutex_unlock(&restart_lock); 15226 return 0; 15227 }
| static char* dahdi_restart_cmd | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15229 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.
15230 { 15231 switch (cmd) { 15232 case CLI_INIT: 15233 e->command = "dahdi restart"; 15234 e->usage = 15235 "Usage: dahdi restart\n" 15236 " Restarts the DAHDI channels: destroys them all and then\n" 15237 " re-reads them from chan_dahdi.conf.\n" 15238 " Note that this will STOP any running CALL on DAHDI channels.\n" 15239 ""; 15240 return NULL; 15241 case CLI_GENERATE: 15242 return NULL; 15243 } 15244 if (a->argc != 2) 15245 return CLI_SHOWUSAGE; 15246 15247 if (dahdi_restart() != 0) 15248 return CLI_FAILURE; 15249 return CLI_SUCCESS; 15250 }
| static int dahdi_ring_phone | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7627 of file chan_dahdi.c.
References ast_log(), dahdi_subchannel::dfd, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.
Referenced by __dahdi_exception(), dahdi_handle_event(), and my_ring().
07628 { 07629 int x; 07630 int res; 07631 /* Make sure our transmit state is on hook */ 07632 x = 0; 07633 x = DAHDI_ONHOOK; 07634 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 07635 do { 07636 x = DAHDI_RING; 07637 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 07638 if (res) { 07639 switch (errno) { 07640 case EBUSY: 07641 case EINTR: 07642 /* Wait just in case */ 07643 usleep(10000); 07644 continue; 07645 case EINPROGRESS: 07646 res = 0; 07647 break; 07648 default: 07649 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 07650 res = 0; 07651 } 07652 } 07653 } while (res); 07654 return res; 07655 }
| static int dahdi_sendtext | ( | struct ast_channel * | c, | |
| const char * | text | |||
| ) | [static] |
Definition at line 18678 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(), LOG_ERROR, LOG_WARNING, 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.
18679 { 18680 #define END_SILENCE_LEN 400 18681 #define HEADER_MS 50 18682 #define TRAILER_MS 5 18683 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 18684 #define ASCII_BYTES_PER_CHAR 80 18685 18686 unsigned char *buf,*mybuf; 18687 struct dahdi_pvt *p = c->tech_pvt; 18688 struct pollfd fds[1]; 18689 int size,res,fd,len,x; 18690 int bytes=0; 18691 /* Initial carrier (imaginary) */ 18692 float cr = 1.0; 18693 float ci = 0.0; 18694 float scont = 0.0; 18695 int idx; 18696 18697 idx = dahdi_get_index(c, p, 0); 18698 if (idx < 0) { 18699 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 18700 return -1; 18701 } 18702 if (!text[0]) return(0); /* if nothing to send, don't */ 18703 if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ 18704 if (p->mate) 18705 buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 18706 else 18707 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 18708 if (!buf) 18709 return -1; 18710 mybuf = buf; 18711 if (p->mate) { 18712 int codec = AST_LAW(p); 18713 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */ 18714 PUT_CLID_MARKMS; 18715 } 18716 /* Put actual message */ 18717 for (x = 0; text[x]; x++) { 18718 PUT_CLID(text[x]); 18719 } 18720 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */ 18721 PUT_CLID_MARKMS; 18722 } 18723 len = bytes; 18724 buf = mybuf; 18725 } else { 18726 len = tdd_generate(p->tdd, buf, text); 18727 if (len < 1) { 18728 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text)); 18729 ast_free(mybuf); 18730 return -1; 18731 } 18732 } 18733 memset(buf + len, 0x7f, END_SILENCE_LEN); 18734 len += END_SILENCE_LEN; 18735 fd = p->subs[idx].dfd; 18736 while (len) { 18737 if (ast_check_hangup(c)) { 18738 ast_free(mybuf); 18739 return -1; 18740 } 18741 size = len; 18742 if (size > READ_SIZE) 18743 size = READ_SIZE; 18744 fds[0].fd = fd; 18745 fds[0].events = POLLOUT | POLLPRI; 18746 fds[0].revents = 0; 18747 res = poll(fds, 1, -1); 18748 if (!res) { 18749 ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel); 18750 continue; 18751 } 18752 /* if got exception */ 18753 if (fds[0].revents & POLLPRI) { 18754 ast_free(mybuf); 18755 return -1; 18756 } 18757 if (!(fds[0].revents & POLLOUT)) { 18758 ast_debug(1, "write fd not ready on channel %d\n", p->channel); 18759 continue; 18760 } 18761 res = write(fd, buf, size); 18762 if (res != size) { 18763 if (res == -1) { 18764 ast_free(mybuf); 18765 return -1; 18766 } 18767 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 18768 break; 18769 } 18770 len -= size; 18771 buf += size; 18772 } 18773 ast_free(mybuf); 18774 return(0); 18775 }
| static char* dahdi_set_dnd | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15839 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, dahdi_pvt::next, and ast_cli_entry::usage.
15840 { 15841 int channel; 15842 int on; 15843 struct dahdi_pvt *dahdi_chan = NULL; 15844 15845 switch (cmd) { 15846 case CLI_INIT: 15847 e->command = "dahdi set dnd"; 15848 e->usage = 15849 "Usage: dahdi set dnd <chan#> <on|off>\n" 15850 " Sets/resets DND (Do Not Disturb) mode on a channel.\n" 15851 " Changes take effect immediately.\n" 15852 " <chan num> is the channel number\n" 15853 " <on|off> Enable or disable DND mode?\n" 15854 ; 15855 return NULL; 15856 case CLI_GENERATE: 15857 return NULL; 15858 } 15859 15860 if (a->argc != 5) 15861 return CLI_SHOWUSAGE; 15862 15863 if ((channel = atoi(a->argv[3])) <= 0) { 15864 ast_cli(a->fd, "Expected channel number, got '%s'\n", a->argv[3]); 15865 return CLI_SHOWUSAGE; 15866 } 15867 15868 if (ast_true(a->argv[4])) 15869 on = 1; 15870 else if (ast_false(a->argv[4])) 15871 on = 0; 15872 else { 15873 ast_cli(a->fd, "Expected 'on' or 'off', got '%s'\n", a->argv[4]); 15874 return CLI_SHOWUSAGE; 15875 } 15876 15877 ast_mutex_lock(&iflock); 15878 for (dahdi_chan = iflist; dahdi_chan; dahdi_chan = dahdi_chan->next) { 15879 if (dahdi_chan->channel != channel) 15880 continue; 15881 15882 /* Found the channel. Actually set it */ 15883 dahdi_dnd(dahdi_chan, on); 15884 break; 15885 } 15886 ast_mutex_unlock(&iflock); 15887 15888 if (!dahdi_chan) { 15889 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15890 return CLI_FAILURE; 15891 } 15892 15893 return CLI_SUCCESS; 15894 }
| static int dahdi_set_hook | ( | int | fd, | |
| int | hs | |||
| ) | [inline, static] |
Definition at line 5165 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(), mkintf(), mwi_send_process_buffer(), mwi_send_process_event(), my_off_hook(), and my_on_hook().
05166 { 05167 int x, res; 05168 05169 x = hs; 05170 res = ioctl(fd, DAHDI_HOOK, &x); 05171 05172 if (res < 0) { 05173 if (errno == EINPROGRESS) 05174 return 0; 05175 ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno)); 05176 /* will expectedly fail if phone is off hook during operation, such as during a restart */ 05177 } 05178 05179 return res; 05180 }
| static char* dahdi_set_hwgain | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15687 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, dahdi_subchannel::dfd, errno, ast_cli_args::fd, dahdi_pvt::next, SUB_REAL, dahdi_pvt::subs, and ast_cli_entry::usage.
15688 { 15689 int channel; 15690 int gain; 15691 int tx; 15692 struct dahdi_hwgain hwgain; 15693 struct dahdi_pvt *tmp = NULL; 15694 15695 switch (cmd) { 15696 case CLI_INIT: 15697 e->command = "dahdi set hwgain {rx|tx}"; 15698 e->usage = 15699 "Usage: dahdi set hwgain <rx|tx> <chan#> <gain>\n" 15700 " Sets the hardware gain on a given channel. Changes take effect\n" 15701 " immediately whether the channel is in use or not.\n" 15702 "\n" 15703 " <rx|tx> which direction do you want to change (relative to our module)\n" 15704 " <chan num> is the channel number relative to the device\n" 15705 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n" 15706 "\n" 15707 " Please note:\n" 15708 " * This is currently the only way to set hwgain by the channel driver.\n" 15709 " * hwgain is only supportable by hardware with analog ports because\n" 15710 " hwgain works on the analog side of an analog-digital conversion.\n"; 15711 return NULL; 15712 case CLI_GENERATE: 15713 return NULL; 15714 } 15715 15716 if (a->argc != 6) 15717 return CLI_SHOWUSAGE; 15718 15719 if (!strcasecmp("rx", a->argv[3])) 15720 tx = 0; /* rx */ 15721 else if (!strcasecmp("tx", a->argv[3])) 15722 tx = 1; /* tx */ 15723 else 15724 return CLI_SHOWUSAGE; 15725 15726 channel = atoi(a->argv[4]); 15727 gain = atof(a->argv[5])*10.0; 15728 15729 ast_mutex_lock(&iflock); 15730 15731 for (tmp = iflist; tmp; tmp = tmp->next) { 15732 15733 if (tmp->channel != channel) 15734 continue; 15735 15736 if (tmp->subs[SUB_REAL].dfd == -1) 15737 break; 15738 15739 hwgain.newgain = gain; 15740 hwgain.tx = tx; 15741 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_HWGAIN, &hwgain) < 0) { 15742 ast_cli(a->fd, "Unable to set the hardware gain for channel %d: %s\n", channel, strerror(errno)); 15743 ast_mutex_unlock(&iflock); 15744 return CLI_FAILURE; 15745 } 15746 ast_cli(a->fd, "hardware %s gain set to %d (%.1f dB) on channel %d\n", 15747 tx ? "tx" : "rx", gain, (float)gain/10.0, channel); 15748 break; 15749 } 15750 15751 ast_mutex_unlock(&iflock); 15752 15753 if (tmp) 15754 return CLI_SUCCESS; 15755 15756 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15757 return CLI_FAILURE; 15758 15759 }
| static char* dahdi_set_swgain | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15761 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, dahdi_subchannel::dfd, ast_cli_args::fd, dahdi_pvt::law, dahdi_pvt::next, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, set_actual_rxgain(), set_actual_txgain(), SUB_REAL, dahdi_pvt::subs, dahdi_pvt::txdrc, dahdi_pvt::txgain, and ast_cli_entry::usage.
15762 { 15763 int channel; 15764 float gain; 15765 int tx; 15766 int res; 15767 struct dahdi_pvt *tmp = NULL; 15768 15769 switch (cmd) { 15770 case CLI_INIT: 15771 e->command = "dahdi set swgain {rx|tx}"; 15772 e->usage = 15773 "Usage: dahdi set swgain <rx|tx> <chan#> <gain>\n" 15774 " Sets the software gain on a given channel and overrides the\n" 15775 " value provided at module loadtime. Changes take effect\n" 15776 " immediately whether the channel is in use or not.\n" 15777 "\n" 15778 " <rx|tx> which direction do you want to change (relative to our module)\n" 15779 " <chan num> is the channel number relative to the device\n" 15780 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"; 15781 return NULL; 15782 case CLI_GENERATE: 15783 return NULL; 15784 } 15785 15786 if (a->argc != 6) 15787 return CLI_SHOWUSAGE; 15788 15789 if (!strcasecmp("rx", a->argv[3])) 15790 tx = 0; /* rx */ 15791 else if (!strcasecmp("tx", a->argv[3])) 15792 tx = 1; /* tx */ 15793 else 15794 return CLI_SHOWUSAGE; 15795 15796 channel = atoi(a->argv[4]); 15797 gain = atof(a->argv[5]); 15798 15799 ast_mutex_lock(&iflock); 15800 for (tmp = iflist; tmp; tmp = tmp->next) { 15801 15802 if (tmp->channel != channel) 15803 continue; 15804 15805 if (tmp->subs[SUB_REAL].dfd == -1) 15806 break; 15807 15808 if (tx) 15809 res = set_actual_txgain(tmp->subs[SUB_REAL].dfd, gain, tmp->txdrc, tmp->law); 15810 else 15811 res = set_actual_rxgain(tmp->subs[SUB_REAL].dfd, gain, tmp->rxdrc, tmp->law); 15812 15813 if (res) { 15814 ast_cli(a->fd, "Unable to set the software gain for channel %d\n", channel); 15815 ast_mutex_unlock(&iflock); 15816 return CLI_FAILURE; 15817 } 15818 15819 ast_cli(a->fd, "software %s gain set to %.1f on channel %d\n", 15820 tx ? "tx" : "rx", gain, channel); 15821 15822 if (tx) { 15823 tmp->txgain = gain; 15824 } else { 15825 tmp->rxgain = gain; 15826 } 15827 break; 15828 } 15829 ast_mutex_unlock(&iflock); 15830 15831 if (tmp) 15832 return CLI_SUCCESS; 15833 15834 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15835 return CLI_FAILURE; 15836 15837 }
| static int dahdi_setlinear | ( | int | dfd, | |
| int | linear | |||
| ) | [static] |
Definition at line 4418 of file chan_dahdi.c.
Referenced by analog_ss_thread(), dahdi_hangup(), dahdi_new(), dahdi_read(), dahdi_write(), my_all_subchannels_hungup(), my_distinctive_ring(), 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 6723 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, 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.
06724 { 06725 char *cp; 06726 signed char *scp; 06727 int x; 06728 int idx; 06729 struct dahdi_pvt *p = chan->tech_pvt, *pp; 06730 struct oprmode *oprmode; 06731 06732 06733 /* all supported options require data */ 06734 if (!p || !data || (datalen < 1)) { 06735 errno = EINVAL; 06736 return -1; 06737 } 06738 06739 switch (option) { 06740 case AST_OPTION_TXGAIN: 06741 scp = (signed char *) data; 06742 idx = dahdi_get_index(chan, p, 0); 06743 if (idx < 0) { 06744 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 06745 return -1; 06746 } 06747 ast_debug(1, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp); 06748 return set_actual_txgain(p->subs[idx].dfd, p->txgain + (float) *scp, p->txdrc, p->law); 06749 case AST_OPTION_RXGAIN: 06750 scp = (signed char *) data; 06751 idx = dahdi_get_index(chan, p, 0); 06752 if (idx < 0) { 06753 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 06754 return -1; 06755 } 06756 ast_debug(1, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp); 06757 return set_actual_rxgain(p->subs[idx].dfd, p->rxgain + (float) *scp, p->rxdrc, p->law); 06758 case AST_OPTION_TONE_VERIFY: 06759 if (!p->dsp) 06760 break; 06761 cp = (char *) data; 06762 switch (*cp) { 06763 case 1: 06764 ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name); 06765 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 06766 break; 06767 case 2: 06768 ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name); 06769 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 06770 break; 06771 default: 06772 ast_debug(1, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name); 06773 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 06774 break; 06775 } 06776 break; 06777 case AST_OPTION_TDD: 06778 /* turn on or off TDD */ 06779 cp = (char *) data; 06780 p->mate = 0; 06781 if (!*cp) { /* turn it off */ 06782 ast_debug(1, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name); 06783 if (p->tdd) 06784 tdd_free(p->tdd); 06785 p->tdd = 0; 06786 break; 06787 } 06788 ast_debug(1, "Set option TDD MODE, value: %s(%d) on %s\n", 06789 (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name); 06790 dahdi_disable_ec(p); 06791 /* otherwise, turn it on */ 06792 if (!p->didtdd) { /* if havent done it yet */ 06793 unsigned char mybuf[41000];/*! \todo XXX This is an abuse of the stack!! */ 06794 unsigned char *buf; 06795 int size, res, fd, len; 06796 struct pollfd fds[1]; 06797 06798 buf = mybuf; 06799 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 06800 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 06801 len = 40000; 06802 idx = dahdi_get_index(chan, p, 0); 06803 if (idx < 0) { 06804 ast_log(LOG_WARNING, "No index in TDD?\n"); 06805 return -1; 06806 } 06807 fd = p->subs[idx].dfd; 06808 while (len) { 06809 if (ast_check_hangup(chan)) 06810 return -1; 06811 size = len; 06812 if (size > READ_SIZE) 06813 size = READ_SIZE; 06814 fds[0].fd = fd; 06815 fds[0].events = POLLPRI | POLLOUT; 06816 fds[0].revents = 0; 06817 res = poll(fds, 1, -1); 06818 if (!res) { 06819 ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel); 06820 continue; 06821 } 06822 /* if got exception */ 06823 if (fds[0].revents & POLLPRI) 06824 return -1; 06825 if (!(fds[0].revents & POLLOUT)) { 06826 ast_debug(1, "write fd not ready on channel %d\n", p->channel); 06827 continue; 06828 } 06829 res = write(fd, buf, size); 06830 if (res != size) { 06831 if (res == -1) return -1; 06832 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 06833 break; 06834 } 06835 len -= size; 06836 buf += size; 06837 } 06838 p->didtdd = 1; /* set to have done it now */ 06839 } 06840 if (*cp == 2) { /* Mate mode */ 06841 if (p->tdd) 06842 tdd_free(p->tdd); 06843 p->tdd = 0; 06844 p->mate = 1; 06845 break; 06846 } 06847 if (!p->tdd) { /* if we don't have one yet */ 06848 p->tdd = tdd_new(); /* allocate one */ 06849 } 06850 break; 06851 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 06852 if (!p->dsp) 06853 break; 06854 cp = (char *) data; 06855 ast_debug(1, "Set option RELAX DTMF, value: %s(%d) on %s\n", 06856 *cp ? "ON" : "OFF", (int) *cp, chan->name); 06857 ast_dsp_set_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax); 06858 break; 06859 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 06860 #if defined(HAVE_PRI) 06861 if (dahdi_sig_pri_lib_handles(p->sig) 06862 && ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 06863 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */ 06864 break; 06865 } 06866 #endif /* defined(HAVE_PRI) */ 06867 06868 cp = (char *) data; 06869 if (!*cp) { 06870 ast_debug(1, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name); 06871 x = 0; 06872 dahdi_disable_ec(p); 06873 } else { 06874 ast_debug(1, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name); 06875 x = 1; 06876 } 06877 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x) == -1) 06878 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, x, strerror(errno)); 06879 break; 06880 case AST_OPTION_OPRMODE: /* Operator services mode */ 06881 oprmode = (struct oprmode *) data; 06882 /* We don't support operator mode across technologies */ 06883 if (strcasecmp(chan->tech->type, oprmode->peer->tech->type)) { 06884 ast_log(LOG_NOTICE, "Operator mode not supported on %s to %s calls.\n", 06885 chan->tech->type, oprmode->peer->tech->type); 06886 errno = EINVAL; 06887 return -1; 06888 } 06889 pp = oprmode->peer->tech_pvt; 06890 p->oprmode = pp->oprmode = 0; 06891 /* setup peers */ 06892 p->oprpeer = pp; 06893 pp->oprpeer = p; 06894 /* setup modes, if any */ 06895 if (oprmode->mode) 06896 { 06897 pp->oprmode = oprmode->mode; 06898 p->oprmode = -oprmode->mode; 06899 } 06900 ast_debug(1, "Set Operator Services mode, value: %d on %s/%s\n", 06901 oprmode->mode, chan->name,oprmode->peer->name); 06902 break; 06903 case AST_OPTION_ECHOCAN: 06904 cp = (char *) data; 06905 if (*cp) { 06906 ast_debug(1, "Enabling echo cancellation on %s\n", chan->name); 06907 dahdi_enable_ec(p); 06908 } else { 06909 ast_debug(1, "Disabling echo cancellation on %s\n", chan->name); 06910 dahdi_disable_ec(p); 06911 } 06912 break; 06913 case AST_OPTION_DIGIT_DETECT: 06914 cp = (char *) data; 06915 ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", chan->name); 06916 if (*cp) { 06917 enable_dtmf_detect(p); 06918 } else { 06919 disable_dtmf_detect(p); 06920 } 06921 break; 06922 case AST_OPTION_FAX_DETECT: 06923 cp = (char *) data; 06924 if (p->dsp) { 06925 ast_debug(1, "%sabling fax tone detection on %s\n", *cp ? "En" : "Dis", chan->name); 06926 if (*cp) { 06927 p->dsp_features |= DSP_FEATURE_FAX_DETECT; 06928 } else { 06929 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 06930 } 06931 ast_dsp_set_features(p->dsp, p->dsp_features); 06932 } 06933 break; 06934 default: 06935 return -1; 06936 } 06937 errno = 0; 06938 06939 return 0; 06940 }
| static char* dahdi_show_channel | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15349 of file chan_dahdi.c.
References sig_pri_chan::allocated, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_log(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::busy_quietlength, dahdi_pvt::busy_tonelength, dahdi_pvt::busycount, dahdi_pvt::busydetect, sig_pri_chan::call, dahdi_pvt::callwaitcas, dahdi_pvt::channel, sig_ss7_chan::cic, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_subaddr, dahdi_pvt::cid_ton, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_pvt::confno, dahdi_pvt::context, dahdi_dnd(), dahdi_pvt::destroy, dahdi_subchannel::dfd, dahdi_pvt::dialing, dahdi_pvt::dsp, dahdi_pvt::dtmfrelax, dahdi_pvt::echocanbridged, dahdi_pvt::echocancel, dahdi_pvt::echocanon, errno, dahdi_pvt::exten, dahdi_pvt::faxhandled, ast_cli_args::fd, dahdi_pvt::head, dahdi_pvt::inalarm, dahdi_pvt::inconference, dahdi_subchannel::inthreeway, dahdi_pvt::law_default, dahdi_subchannel::linear, LOG_WARNING, dahdi_pvt::mailbox, dahdi_pvt::master, MAX_SLAVES, ast_variable::name, ast_variable::next, dahdi_pvt::next, dahdi_subchannel::owner, dahdi_pvt::owner, dahdi_pvt::params, dahdi_pvt::propconfno, dahdi_pvt::pulsedial, dahdi_pvt::radio, sig_pri_chan::resetting, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, S_OR, dahdi_pvt::sig, sig2str, SIG_PRI_RESET_IDLE, dahdi_pvt::sig_pvt, 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.
15350 { 15351 int channel; 15352 struct dahdi_pvt *tmp = NULL; 15353 struct dahdi_confinfo ci; 15354 struct dahdi_params ps; 15355 int x; 15356 15357 switch (cmd) { 15358 case CLI_INIT: 15359 e->command = "dahdi show channel"; 15360 e->usage = 15361 "Usage: dahdi show channel <chan num>\n" 15362 " Detailed information about a given channel\n"; 15363 return NULL; 15364 case CLI_GENERATE: 15365 return NULL; 15366 } 15367 15368 if (a->argc != 4) 15369 return CLI_SHOWUSAGE; 15370 15371 channel = atoi(a->argv[3]); 15372 15373 ast_mutex_lock(&iflock); 15374 for (tmp = iflist; tmp; tmp = tmp->next) { 15375 if (tmp->channel == channel) { 15376 ast_cli(a->fd, "Channel: %d\n", tmp->channel); 15377 ast_cli(a->fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].dfd); 15378 ast_cli(a->fd, "Span: %d\n", tmp->span); 15379 ast_cli(a->fd, "Extension: %s\n", tmp->exten); 15380 ast_cli(a->fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 15381 ast_cli(a->fd, "Context: %s\n", tmp->context); 15382 ast_cli(a->fd, "Caller ID: %s\n", tmp->cid_num); 15383 ast_cli(a->fd, "Calling TON: %d\n", tmp->cid_ton); 15384 #if defined(HAVE_PRI) 15385 #if defined(HAVE_PRI_SUBADDR) 15386 ast_cli(a->fd, "Caller ID subaddress: %s\n", tmp->cid_subaddr); 15387 #endif /* defined(HAVE_PRI_SUBADDR) */ 15388 #endif /* defined(HAVE_PRI) */ 15389 ast_cli(a->fd, "Caller ID name: %s\n", tmp->cid_name); 15390 ast_cli(a->fd, "Mailbox: %s\n", S_OR(tmp->mailbox, "none")); 15391 if (tmp->vars) { 15392 struct ast_variable *v; 15393 ast_cli(a->fd, "Variables:\n"); 15394 for (v = tmp->vars ; v ; v = v->next) 15395 ast_cli(a->fd, " %s = %s\n", v->name, v->value); 15396 } 15397 ast_cli(a->fd, "Destroy: %d\n", tmp->destroy); 15398 ast_cli(a->fd, "InAlarm: %d\n", tmp->inalarm); 15399 ast_cli(a->fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 15400 ast_cli(a->fd, "Radio: %d\n", tmp->radio); 15401 ast_cli(a->fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>"); 15402 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)" : ""); 15403 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)" : ""); 15404 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)" : ""); 15405 ast_cli(a->fd, "Confno: %d\n", tmp->confno); 15406 ast_cli(a->fd, "Propagated Conference: %d\n", tmp->propconfno); 15407 ast_cli(a->fd, "Real in conference: %d\n", tmp->inconference); 15408 ast_cli(a->fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 15409 ast_cli(a->fd, "Busy Detection: %s\n", tmp->busydetect ? "yes" : "no"); 15410 if (tmp->busydetect) { 15411 #if defined(BUSYDETECT_TONEONLY) 15412 ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_TONEONLY\n"); 15413 #elif defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE) 15414 ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_COMPARE_TONE_AND_SILENCE\n"); 15415 #endif 15416 #ifdef BUSYDETECT_DEBUG 15417 ast_cli(a->fd, " Busy Detector Debug: Enabled\n"); 15418 #endif 15419 ast_cli(a->fd, " Busy Count: %d\n", tmp->busycount); 15420 ast_cli(a->fd, " Busy Pattern: %d,%d\n", tmp->busy_tonelength, tmp->busy_quietlength); 15421 } 15422 ast_cli(a->fd, "TDD: %s\n", tmp->tdd ? "yes" : "no"); 15423 ast_cli(a->fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 15424 ast_cli(a->fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 15425 ast_cli(a->fd, "Default law: %s\n", tmp->law_default == DAHDI_LAW_MULAW ? "ulaw" : tmp->law_default == DAHDI_LAW_ALAW ? "alaw" : "unknown"); 15426 ast_cli(a->fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 15427 ast_cli(a->fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 15428 ast_cli(a->fd, "Gains (RX/TX): %.2f/%.2f\n", tmp->rxgain, tmp->txgain); 15429 ast_cli(a->fd, "Dynamic Range Compression (RX/TX): %.2f/%.2f\n", tmp->rxdrc, tmp->txdrc); 15430 ast_cli(a->fd, "DND: %s\n", dahdi_dnd(tmp, -1) ? "yes" : "no"); 15431 ast_cli(a->fd, "Echo Cancellation:\n"); 15432 15433 if (tmp->echocancel.head.tap_length) { 15434 ast_cli(a->fd, "\t%d taps\n", tmp->echocancel.head.tap_length); 15435 for (x = 0; x < tmp->echocancel.head.param_count; x++) { 15436 ast_cli(a->fd, "\t\t%s: %ud\n", tmp->echocancel.params[x].name, tmp->echocancel.params[x].value); 15437 } 15438 ast_cli(a->fd, "\t%scurrently %s\n", tmp->echocanbridged ? "" : "(unless TDM bridged) ", tmp->echocanon ? "ON" : "OFF"); 15439 } else { 15440 ast_cli(a->fd, "\tnone\n"); 15441 } 15442 ast_cli(a->fd, "Wait for dialtone: %dms\n", tmp->waitfordialtone); 15443 if (tmp->master) 15444 ast_cli(a->fd, "Master Channel: %d\n", tmp->master->channel); 15445 for (x = 0; x < MAX_SLAVES; x++) { 15446 if (tmp->slaves[x]) 15447 ast_cli(a->fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 15448 } 15449 #ifdef HAVE_OPENR2 15450 if (tmp->mfcr2) { 15451 char calldir[OR2_MAX_PATH]; 15452 openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan); 15453 openr2_variant_t r2variant = openr2_context_get_variant(r2context); 15454 ast_cli(a->fd, "MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan)); 15455 ast_cli(a->fd, "MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan)); 15456 ast_cli(a->fd, "MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan)); 15457 ast_cli(a->fd, "MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan)); 15458 ast_cli(a->fd, "MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ? "Yes" : "No"); 15459 ast_cli(a->fd, "MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant)); 15460 ast_cli(a->fd, "MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context)); 15461 ast_cli(a->fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context)); 15462 ast_cli(a->fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No"); 15463 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 15464 ast_cli(a->fd, "MFC/R2 Skip Category Request: %s\n", openr2_context_get_skip_category_request(r2context) ? "Yes" : "No"); 15465 #endif 15466 ast_cli(a->fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No"); 15467 ast_cli(a->fd, "MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No"); 15468 ast_cli(a->fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No"); 15469 ast_cli(a->fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No"); 15470 ast_cli(a->fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No"); 15471 ast_cli(a->fd, "MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context)); 15472 ast_cli(a->fd, "MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context)); 15473 ast_cli(a->fd, "MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan)); 15474 ast_cli(a->fd, "MFC/R2 Tx CAS: %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan)); 15475 ast_cli(a->fd, "MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan)); 15476 ast_cli(a->fd, "MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan)); 15477 ast_cli(a->fd, "MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir, sizeof(calldir))); 15478 } 15479 #endif 15480 #if defined(HAVE_SS7) 15481 if (tmp->ss7) { 15482 struct sig_ss7_chan *chan = tmp->sig_pvt; 15483 15484 ast_cli(a->fd, "CIC: %d\n", chan->cic); 15485 } 15486 #endif /* defined(HAVE_SS7) */ 15487 #ifdef HAVE_PRI 15488 if (tmp->pri) { 15489 struct sig_pri_chan *chan = tmp->sig_pvt; 15490 15491 ast_cli(a->fd, "PRI Flags: "); 15492 if (chan->resetting != SIG_PRI_RESET_IDLE) { 15493 ast_cli(a->fd, "Resetting=%d ", chan->resetting); 15494 } 15495 if (chan->call) 15496 ast_cli(a->fd, "Call "); 15497 if (chan->allocated) { 15498 ast_cli(a->fd, "Allocated "); 15499 } 15500 ast_cli(a->fd, "\n"); 15501 if (tmp->logicalspan) 15502 ast_cli(a->fd, "PRI Logical Span: %d\n", tmp->logicalspan); 15503 else 15504 ast_cli(a->fd, "PRI Logical Span: Implicit\n"); 15505 } 15506 #endif 15507 memset(&ci, 0, sizeof(ci)); 15508 ps.channo = tmp->channel; 15509 if (tmp->subs[SUB_REAL].dfd > -1) { 15510 memset(&ci, 0, sizeof(ci)); 15511 if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) { 15512 ast_cli(a->fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 15513 } 15514 if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONFMUTE, &x)) { 15515 ast_cli(a->fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 15516 } 15517 memset(&ps, 0, sizeof(ps)); 15518 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) { 15519 ast_log(LOG_WARNING, "Failed to get parameters on channel %d: %s\n", tmp->channel, strerror(errno)); 15520 } else { 15521 ast_cli(a->fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 15522 } 15523 } 15524 ast_mutex_unlock(&iflock); 15525 return CLI_SUCCESS; 15526 } 15527 } 15528 ast_mutex_unlock(&iflock); 15529 15530 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15531 return CLI_FAILURE; 15532 }
| static char* dahdi_show_channels | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15262 of file chan_dahdi.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_pvt::context, dahdi_pvt::exten, ast_cli_args::fd, FORMAT, FORMAT2, dahdi_pvt::group, dahdi_pvt::language, dahdi_pvt::locallyblocked, dahdi_pvt::mohinterpret, dahdi_pvt::next, dahdi_pvt::remotelyblocked, and ast_cli_entry::usage.
15263 { 15264 #define FORMAT "%7s %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" 15265 #define FORMAT2 "%7s %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n" 15266 ast_group_t targetnum = 0; 15267 int filtertype = 0; 15268 struct dahdi_pvt *tmp = NULL; 15269 char tmps[20] = ""; 15270 char statestr[20] = ""; 15271 char blockstr[20] = ""; 15272 15273 switch (cmd) { 15274 case CLI_INIT: 15275 e->command = "dahdi show channels [group|context]"; 15276 e->usage = 15277 "Usage: dahdi show channels [ group <group> | context <context> ]\n" 15278 " Shows a list of available channels with optional filtering\n" 15279 " <group> must be a number between 0 and 63\n"; 15280 return NULL; 15281 case CLI_GENERATE: 15282 return NULL; 15283 } 15284 15285 /* syntax: dahdi show channels [ group <group> | context <context> ] */ 15286 15287 if (!((a->argc == 3) || (a->argc == 5))) 15288 return CLI_SHOWUSAGE; 15289 15290 if (a->argc == 5) { 15291 if (!strcasecmp(a->argv[3], "group")) { 15292 targetnum = atoi(a->argv[4]); 15293 if (63 < targetnum) { 15294 return CLI_SHOWUSAGE; 15295 } 15296 targetnum = ((ast_group_t) 1) << targetnum; 15297 filtertype = 1; 15298 } else if (!strcasecmp(a->argv[3], "context")) { 15299 filtertype = 2; 15300 } 15301 } 15302 15303 ast_cli(a->fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret", "Blocked", "State"); 15304 ast_mutex_lock(&iflock); 15305 for (tmp = iflist; tmp; tmp = tmp->next) { 15306 if (filtertype) { 15307 switch(filtertype) { 15308 case 1: /* dahdi show channels group <group> */ 15309 if (!(tmp->group & targetnum)) { 15310 continue; 15311 } 15312 break; 15313 case 2: /* dahdi show channels context <context> */ 15314 if (strcasecmp(tmp->context, a->argv[4])) { 15315 continue; 15316 } 15317 break; 15318 default: 15319 break; 15320 } 15321 } 15322 if (tmp->channel > 0) { 15323 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 15324 } else 15325 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 15326 15327 if (tmp->locallyblocked) 15328 blockstr[0] = 'L'; 15329 else 15330 blockstr[0] = ' '; 15331 15332 if (tmp->remotelyblocked) 15333 blockstr[1] = 'R'; 15334 else 15335 blockstr[1] = ' '; 15336 15337 blockstr[2] = '\0'; 15338 15339 snprintf(statestr, sizeof(statestr), "%s", "In Service"); 15340 15341 ast_cli(a->fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret, blockstr, statestr); 15342 } 15343 ast_mutex_unlock(&iflock); 15344 return CLI_SUCCESS; 15345 #undef FORMAT 15346 #undef FORMAT2 15347 }
| static char* dahdi_show_status | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15571 of file chan_dahdi.c.
References ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, errno, ast_cli_args::fd, FORMAT, FORMAT2, and ast_cli_entry::usage.
15572 { 15573 #define FORMAT "%-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n" 15574 #define FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n" 15575 int span; 15576 int res; 15577 char alarmstr[50]; 15578 15579 int ctl; 15580 struct dahdi_spaninfo s; 15581 15582 switch (cmd) { 15583 case CLI_INIT: 15584 e->command = "dahdi show status"; 15585 e->usage = 15586 "Usage: dahdi show status\n" 15587 " Shows a list of DAHDI cards with status\n"; 15588 return NULL; 15589 case CLI_GENERATE: 15590 return NULL; 15591 } 15592 ctl = open("/dev/dahdi/ctl", O_RDWR); 15593 if (ctl < 0) { 15594 ast_cli(a->fd, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); 15595 return CLI_FAILURE; 15596 } 15597 ast_cli(a->fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC", "Framing", "Coding", "Options", "LBO"); 15598 15599 for (span = 1; span < DAHDI_MAX_SPANS; ++span) { 15600 s.spanno = span; 15601 res = ioctl(ctl, DAHDI_SPANSTAT, &s); 15602 if (res) { 15603 continue; 15604 } 15605 alarmstr[0] = '\0'; 15606 if (s.alarms > 0) { 15607 if (s.alarms & DAHDI_ALARM_BLUE) 15608 strcat(alarmstr, "BLU/"); 15609 if (s.alarms & DAHDI_ALARM_YELLOW) 15610 strcat(alarmstr, "YEL/"); 15611 if (s.alarms & DAHDI_ALARM_RED) 15612 strcat(alarmstr, "RED/"); 15613 if (s.alarms & DAHDI_ALARM_LOOPBACK) 15614 strcat(alarmstr, "LB/"); 15615 if (s.alarms & DAHDI_ALARM_RECOVER) 15616 strcat(alarmstr, "REC/"); 15617 if (s.alarms & DAHDI_ALARM_NOTOPEN) 15618 strcat(alarmstr, "NOP/"); 15619 if (!strlen(alarmstr)) 15620 strcat(alarmstr, "UUU/"); 15621 if (strlen(alarmstr)) { 15622 /* Strip trailing / */ 15623 alarmstr[strlen(alarmstr) - 1] = '\0'; 15624 } 15625 } else { 15626 if (s.numchans) 15627 strcpy(alarmstr, "OK"); 15628 else 15629 strcpy(alarmstr, "UNCONFIGURED"); 15630 } 15631 15632 ast_cli(a->fd, FORMAT, s.desc, alarmstr, s.irqmisses, s.bpvcount, s.crc4count, 15633 s.lineconfig & DAHDI_CONFIG_D4 ? "D4" : 15634 s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" : 15635 s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" : 15636 "CAS", 15637 s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" : 15638 s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" : 15639 s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" : 15640 "Unk", 15641 s.lineconfig & DAHDI_CONFIG_CRC4 ? 15642 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" : 15643 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : "", 15644 lbostr[s.lbo] 15645 ); 15646 } 15647 close(ctl); 15648 15649 return CLI_SUCCESS; 15650 #undef FORMAT 15651 #undef FORMAT2 15652 }
| static char* dahdi_show_version | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15654 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.
15655 { 15656 int pseudo_fd = -1; 15657 struct dahdi_versioninfo vi; 15658 15659 switch (cmd) { 15660 case CLI_INIT: 15661 e->command = "dahdi show version"; 15662 e->usage = 15663 "Usage: dahdi show version\n" 15664 " Shows the DAHDI version in use\n"; 15665 return NULL; 15666 case CLI_GENERATE: 15667 return NULL; 15668 } 15669 if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) { 15670 ast_cli(a->fd, "Failed to open control file to get version.\n"); 15671 return CLI_SUCCESS; 15672 } 15673 15674 strcpy(vi.version, "Unknown"); 15675 strcpy(vi.echo_canceller, "Unknown"); 15676 15677 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi)) 15678 ast_cli(a->fd, "Failed to get DAHDI version: %s\n", strerror(errno)); 15679 else 15680 ast_cli(a->fd, "DAHDI Version: %s Echo Canceller: %s\n", vi.version, vi.echo_canceller); 15681 15682 close(pseudo_fd); 15683 15684 return CLI_SUCCESS; 15685 }
| static char* dahdi_sig2str | ( | int | sig | ) | [static] |
Definition at line 4642 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.
Referenced by mkintf().
04643 { 04644 static char buf[256]; 04645 switch (sig) { 04646 case SIG_EM: 04647 return "E & M Immediate"; 04648 case SIG_EMWINK: 04649 return "E & M Wink"; 04650 case SIG_EM_E1: 04651 return "E & M E1"; 04652 case SIG_FEATD: 04653 return "Feature Group D (DTMF)"; 04654 case SIG_FEATDMF: 04655 return "Feature Group D (MF)"; 04656 case SIG_FEATDMF_TA: 04657 return "Feature Groud D (MF) Tandem Access"; 04658 case SIG_FEATB: 04659 return "Feature Group B (MF)"; 04660 case SIG_E911: 04661 return "E911 (MF)"; 04662 case SIG_FGC_CAMA: 04663 return "FGC/CAMA (Dialpulse)"; 04664 case SIG_FGC_CAMAMF: 04665 return "FGC/CAMA (MF)"; 04666 case SIG_FXSLS: 04667 return "FXS Loopstart"; 04668 case SIG_FXSGS: 04669 return "FXS Groundstart"; 04670 case SIG_FXSKS: 04671 return "FXS Kewlstart"; 04672 case SIG_FXOLS: 04673 return "FXO Loopstart"; 04674 case SIG_FXOGS: 04675 return "FXO Groundstart"; 04676 case SIG_FXOKS: 04677 return "FXO Kewlstart"; 04678 case SIG_PRI: 04679 return "ISDN PRI"; 04680 case SIG_BRI: 04681 return "ISDN BRI Point to Point"; 04682 case SIG_BRI_PTMP: 04683 return "ISDN BRI Point to MultiPoint"; 04684 case SIG_SS7: 04685 return "SS7"; 04686 case SIG_MFCR2: 04687 return "MFC/R2"; 04688 case SIG_SF: 04689 return "SF (Tone) Immediate"; 04690 case SIG_SFWINK: 04691 return "SF (Tone) Wink"; 04692 case SIG_SF_FEATD: 04693 return "SF (Tone) with Feature Group D (DTMF)"; 04694 case SIG_SF_FEATDMF: 04695 return "SF (Tone) with Feature Group D (MF)"; 04696 case SIG_SF_FEATB: 04697 return "SF (Tone) with Feature Group B (MF)"; 04698 case 0: 04699 return "Pseudo"; 04700 default: 04701 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig); 04702 return buf; 04703 } 04704 }
| static int dahdi_sig_pri_lib_handles | ( | int | signaling | ) | [inline, static] |
Definition at line 1541 of file chan_dahdi.c.
References SIG_PRI_LIB_HANDLE_CASES.
Referenced by dahdi_bridge(), dahdi_call(), dahdi_cc_callback(), dahdi_digit_end(), dahdi_fixup(), dahdi_handle_event(), dahdi_hangup(), dahdi_new(), dahdi_queryoption(), dahdi_read(), dahdi_request(), dahdi_setoption(), handle_alarms(), handle_clear_alarms(), and mkintf().
01542 { 01543 int handles; 01544 01545 switch (signaling) { 01546 case SIG_PRI_LIB_HANDLE_CASES: 01547 handles = 1; 01548 break; 01549 default: 01550 handles = 0; 01551 break; 01552 } 01553 01554 return handles; 01555 }
| static void dahdi_softhangup_all | ( | void | ) | [static] |
Definition at line 15088 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, dahdi_pvt::lock, dahdi_pvt::next, option_debug, dahdi_pvt::owner, and dahdi_pvt::restartpending.
Referenced by dahdi_restart().
15089 { 15090 struct dahdi_pvt *p; 15091 retry: 15092 ast_mutex_lock(&iflock); 15093 for (p = iflist; p; p = p->next) { 15094 ast_mutex_lock(&p->lock); 15095 if (p->owner && !p->restartpending) { 15096 if (ast_channel_trylock(p->owner)) { 15097 if (option_debug > 2) 15098 ast_verbose("Avoiding deadlock\n"); 15099 /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */ 15100 ast_mutex_unlock(&p->lock); 15101 ast_mutex_unlock(&iflock); 15102 goto retry; 15103 } 15104 if (option_debug > 2) 15105 ast_verbose("Softhanging up on %s\n", p->owner->name); 15106 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_EXPLICIT); 15107 p->restartpending = 1; 15108 num_restart_pending++; 15109 ast_channel_unlock(p->owner); 15110 } 15111 ast_mutex_unlock(&p->lock); 15112 } 15113 ast_mutex_unlock(&iflock); 15114 }
| static int dahdi_status_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 18447 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 LOG_ERROR.
18449 { 18450 int ctl, res, span; 18451 struct ast_data *data_span, *data_alarms; 18452 struct dahdi_spaninfo s; 18453 18454 ctl = open("/dev/dahdi/ctl", O_RDWR); 18455 if (ctl < 0) { 18456 ast_log(LOG_ERROR, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); 18457 return -1; 18458 } 18459 for (span = 1; span < DAHDI_MAX_SPANS; ++span) { 18460 s.spanno = span; 18461 res = ioctl(ctl, DAHDI_SPANSTAT, &s); 18462 if (res) { 18463 continue; 18464 } 18465 18466 data_span = ast_data_add_node(data_root, "span"); 18467 if (!data_span) { 18468 continue; 18469 } 18470 ast_data_add_str(data_span, "description", s.desc); 18471 18472 /* insert the alarms status */ 18473 data_alarms = ast_data_add_node(data_span, "alarms"); 18474 if (!data_alarms) { 18475 continue; 18476 } 18477 18478 ast_data_add_bool(data_alarms, "BLUE", s.alarms & DAHDI_ALARM_BLUE); 18479 ast_data_add_bool(data_alarms, "YELLOW", s.alarms & DAHDI_ALARM_YELLOW); 18480 ast_data_add_bool(data_alarms, "RED", s.alarms & DAHDI_ALARM_RED); 18481 ast_data_add_bool(data_alarms, "LOOPBACK", s.alarms & DAHDI_ALARM_LOOPBACK); 18482 ast_data_add_bool(data_alarms, "RECOVER", s.alarms & DAHDI_ALARM_RECOVER); 18483 ast_data_add_bool(data_alarms, "NOTOPEN", s.alarms & DAHDI_ALARM_NOTOPEN); 18484 18485 ast_data_add_int(data_span, "irqmisses", s.irqmisses); 18486 ast_data_add_int(data_span, "bpviol", s.bpvcount); 18487 ast_data_add_int(data_span, "crc4", s.crc4count); 18488 ast_data_add_str(data_span, "framing", s.lineconfig & DAHDI_CONFIG_D4 ? "D4" : 18489 s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" : 18490 s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" : 18491 "CAS"); 18492 ast_data_add_str(data_span, "coding", s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" : 18493 s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" : 18494 s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" : 18495 "Unknown"); 18496 ast_data_add_str(data_span, "options", s.lineconfig & DAHDI_CONFIG_CRC4 ? 18497 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" : 18498 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : ""); 18499 ast_data_add_str(data_span, "lbo", lbostr[s.lbo]); 18500 18501 /* if this span doesn't match remove it. */ 18502 if (!ast_data_search_match(search, data_span)) { 18503 ast_data_remove_node(data_root, data_span); 18504 } 18505 } 18506 close(ctl); 18507 18508 return 0; 18509 }
| static void dahdi_train_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4945 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_pvt::channel, dahdi_subchannel::dfd, dahdi_pvt::echocanon, dahdi_pvt::echotraining, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_handle_event(), and my_train_echocanceller().
04946 { 04947 int x; 04948 int res; 04949 04950 if (p && p->echocanon && p->echotraining) { 04951 x = p->echotraining; 04952 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x); 04953 if (res) 04954 ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno)); 04955 else 04956 ast_debug(1, "Engaged echo training on channel %d\n", p->channel); 04957 } else { 04958 ast_debug(1, "No echo training requested\n"); 04959 } 04960 }
| static void dahdi_unlink | ( | struct dahdi_pvt * | slave, | |
| struct dahdi_pvt * | master, | |||
| int | needlock | |||
| ) | [static] |
Definition at line 7155 of file chan_dahdi.c.
References ast_debug, ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, dahdi_pvt::channel, conf_del(), DEADLOCK_AVOIDANCE, dahdi_pvt::inconference, dahdi_pvt::lock, dahdi_pvt::master, MAX_SLAVES, dahdi_pvt::slaves, SUB_REAL, dahdi_pvt::subs, and update_conf().
Referenced by dahdi_bridge(), and dahdi_fixup().
07156 { 07157 /* Unlink a specific slave or all slaves/masters from a given master */ 07158 int x; 07159 int hasslaves; 07160 if (!master) 07161 return; 07162 if (needlock) { 07163 ast_mutex_lock(&master->lock); 07164 if (slave) { 07165 while (ast_mutex_trylock(&slave->lock)) { 07166 DEADLOCK_AVOIDANCE(&master->lock); 07167 } 07168 } 07169 } 07170 hasslaves = 0; 07171 for (x = 0; x < MAX_SLAVES; x++) { 07172 if (master->slaves[x]) { 07173 if (!slave || (master->slaves[x] == slave)) { 07174 /* Take slave out of the conference */ 07175 ast_debug(1, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 07176 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 07177 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 07178 master->slaves[x]->master = NULL; 07179 master->slaves[x] = NULL; 07180 } else 07181 hasslaves = 1; 07182 } 07183 if (!hasslaves) 07184 master->inconference = 0; 07185 } 07186 if (!slave) { 07187 if (master->master) { 07188 /* Take master out of the conference */ 07189 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 07190 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 07191 hasslaves = 0; 07192 for (x = 0; x < MAX_SLAVES; x++) { 07193 if (master->master->slaves[x] == master) 07194 master->master->slaves[x] = NULL; 07195 else if (master->master->slaves[x]) 07196 hasslaves = 1; 07197 } 07198 if (!hasslaves) 07199 master->master->inconference = 0; 07200 } 07201 master->master = NULL; 07202 } 07203 update_conf(master); 07204 if (needlock) { 07205 if (slave) 07206 ast_mutex_unlock(&slave->lock); 07207 ast_mutex_unlock(&master->lock); 07208 } 07209 }
| static int dahdi_version_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 18550 of file chan_dahdi.c.
References ast_data_add_str(), ast_log(), errno, and LOG_ERROR.
18552 { 18553 int pseudo_fd = -1; 18554 struct dahdi_versioninfo vi = { 18555 .version = "Unknown", 18556 .echo_canceller = "Unknown" 18557 }; 18558 18559 if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) { 18560 ast_log(LOG_ERROR, "Failed to open control file to get version.\n"); 18561 return -1; 18562 } 18563 18564 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi)) { 18565 ast_log(LOG_ERROR, "Failed to get DAHDI version: %s\n", strerror(errno)); 18566 } 18567 18568 close(pseudo_fd); 18569 18570 ast_data_add_str(data_root, "value", vi.version); 18571 ast_data_add_str(data_root, "echocanceller", vi.echo_canceller); 18572 18573 return 0; 18574 }
| static int dahdi_wait_event | ( | int | fd | ) | [inline, static] |
Avoid the silly dahdi_waitevent which ignores a bunch of events.
Referenced by analog_ss_thread(), and my_wait_event().
| static int dahdi_wink | ( | struct dahdi_pvt * | p, | |
| int | index | |||
| ) | [static] |
Definition at line 9862 of file chan_dahdi.c.
References dahdi_set_hook(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
Referenced by analog_ss_thread(), and my_wink().
09863 { 09864 int j; 09865 dahdi_set_hook(p->subs[idx].dfd, DAHDI_WINK); 09866 for (;;) 09867 { 09868 /* set bits of interest */ 09869 j = DAHDI_IOMUX_SIGEVENT; 09870 /* wait for some happening */ 09871 if (ioctl(p->subs[idx].dfd,DAHDI_IOMUX,&j) == -1) return(-1); 09872 /* exit loop if we have it */ 09873 if (j & DAHDI_IOMUX_SIGEVENT) break; 09874 } 09875 /* get the event info */ 09876 if (ioctl(p->subs[idx].dfd,DAHDI_GETEVENT,&j) == -1) return(-1); 09877 return 0; 09878 }
| static int dahdi_write | ( | struct ast_channel * | ast, | |
| struct ast_frame * | frame | |||
| ) | [static] |
Definition at line 9388 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, LOG_WARNING, my_dahdi_write(), dahdi_pvt::owner, ast_frame::ptr, ast_frame::subclass, dahdi_pvt::subs, and ast_channel::tech_pvt.
09389 { 09390 struct dahdi_pvt *p = ast->tech_pvt; 09391 int res; 09392 int idx; 09393 idx = dahdi_get_index(ast, p, 0); 09394 if (idx < 0) { 09395 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name); 09396 return -1; 09397 } 09398 09399 /* Write a frame of (presumably voice) data */ 09400 if (frame->frametype != AST_FRAME_VOICE) { 09401 if (frame->frametype != AST_FRAME_IMAGE) 09402 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 09403 return 0; 09404 } 09405 if ((frame->subclass.codec != AST_FORMAT_SLINEAR) && 09406 (frame->subclass.codec != AST_FORMAT_ULAW) && 09407 (frame->subclass.codec != AST_FORMAT_ALAW)) { 09408 ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(frame->subclass.codec)); 09409 return -1; 09410 } 09411 if (p->dialing) { 09412 ast_debug(1, "Dropping frame since I'm still dialing on %s...\n",ast->name); 09413 return 0; 09414 } 09415 if (!p->owner) { 09416 ast_debug(1, "Dropping frame since there is no active owner on %s...\n",ast->name); 09417 return 0; 09418 } 09419 if (p->cidspill) { 09420 ast_debug(1, "Dropping frame since I've still got a callerid spill on %s...\n", 09421 ast->name); 09422 return 0; 09423 } 09424 /* Return if it's not valid data */ 09425 if (!frame->data.ptr || !frame->datalen) 09426 return 0; 09427 09428 if (frame->subclass.codec == AST_FORMAT_SLINEAR) { 09429 if (!p->subs[idx].linear) { 09430 p->subs[idx].linear = 1; 09431 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09432 if (res) 09433 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 09434 } 09435 res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 1); 09436 } else { 09437 /* x-law already */ 09438 if (p->subs[idx].linear) { 09439 p->subs[idx].linear = 0; 09440 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09441 if (res) 09442 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 09443 } 09444 res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 0); 09445 } 09446 if (res < 0) { 09447 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 09448 return -1; 09449 } 09450 return 0; 09451 }
| static enum analog_event dahdievent_to_analogevent | ( | int | event | ) | [static] |
Definition at line 2775 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 do_monitor(), my_get_callerid(), and my_get_event().
02776 { 02777 enum analog_event res; 02778 02779 switch (event) { 02780 case DAHDI_EVENT_ONHOOK: 02781 res = ANALOG_EVENT_ONHOOK; 02782 break; 02783 case DAHDI_EVENT_RINGOFFHOOK: 02784 res = ANALOG_EVENT_RINGOFFHOOK; 02785 break; 02786 case DAHDI_EVENT_WINKFLASH: 02787 res = ANALOG_EVENT_WINKFLASH; 02788 break; 02789 case DAHDI_EVENT_ALARM: 02790 res = ANALOG_EVENT_ALARM; 02791 break; 02792 case DAHDI_EVENT_NOALARM: 02793 res = ANALOG_EVENT_NOALARM; 02794 break; 02795 case DAHDI_EVENT_DIALCOMPLETE: 02796 res = ANALOG_EVENT_DIALCOMPLETE; 02797 break; 02798 case DAHDI_EVENT_RINGERON: 02799 res = ANALOG_EVENT_RINGERON; 02800 break; 02801 case DAHDI_EVENT_RINGEROFF: 02802 res = ANALOG_EVENT_RINGEROFF; 02803 break; 02804 case DAHDI_EVENT_HOOKCOMPLETE: 02805 res = ANALOG_EVENT_HOOKCOMPLETE; 02806 break; 02807 case DAHDI_EVENT_PULSE_START: 02808 res = ANALOG_EVENT_PULSE_START; 02809 break; 02810 case DAHDI_EVENT_POLARITY: 02811 res = ANALOG_EVENT_POLARITY; 02812 break; 02813 case DAHDI_EVENT_RINGBEGIN: 02814 res = ANALOG_EVENT_RINGBEGIN; 02815 break; 02816 case DAHDI_EVENT_EC_DISABLED: 02817 res = ANALOG_EVENT_EC_DISABLED; 02818 break; 02819 case DAHDI_EVENT_REMOVED: 02820 res = ANALOG_EVENT_REMOVED; 02821 break; 02822 case DAHDI_EVENT_NEONMWI_ACTIVE: 02823 res = ANALOG_EVENT_NEONMWI_ACTIVE; 02824 break; 02825 case DAHDI_EVENT_NEONMWI_INACTIVE: 02826 res = ANALOG_EVENT_NEONMWI_INACTIVE; 02827 break; 02828 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 02829 case DAHDI_EVENT_TX_CED_DETECTED: 02830 res = ANALOG_EVENT_TX_CED_DETECTED; 02831 break; 02832 case DAHDI_EVENT_RX_CED_DETECTED: 02833 res = ANALOG_EVENT_RX_CED_DETECTED; 02834 break; 02835 case DAHDI_EVENT_EC_NLP_DISABLED: 02836 res = ANALOG_EVENT_EC_NLP_DISABLED; 02837 break; 02838 case DAHDI_EVENT_EC_NLP_ENABLED: 02839 res = ANALOG_EVENT_EC_NLP_ENABLED; 02840 break; 02841 #endif 02842 case DAHDI_EVENT_PULSEDIGIT: 02843 res = ANALOG_EVENT_PULSEDIGIT; 02844 break; 02845 case DAHDI_EVENT_DTMFDOWN: 02846 res = ANALOG_EVENT_DTMFDOWN; 02847 break; 02848 case DAHDI_EVENT_DTMFUP: 02849 res = ANALOG_EVENT_DTMFUP; 02850 break; 02851 default: 02852 switch(event & 0xFFFF0000) { 02853 case DAHDI_EVENT_PULSEDIGIT: 02854 case DAHDI_EVENT_DTMFDOWN: 02855 case DAHDI_EVENT_DTMFUP: 02856 /* The event includes a digit number in the low word. 02857 * Converting it to a 'enum analog_event' would remove 02858 * that information. Thus it is returned as-is. 02859 */ 02860 return event; 02861 } 02862 02863 res = ANALOG_EVENT_ERROR; 02864 break; 02865 } 02866 02867 return res; 02868 }
| static enum analog_sigtype dahdisig_to_analogsig | ( | int | sig | ) | [static] |
Definition at line 1598 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.
Referenced by mkintf().
01599 { 01600 switch (sig) { 01601 case SIG_FXOLS: 01602 return ANALOG_SIG_FXOLS; 01603 case SIG_FXOGS: 01604 return ANALOG_SIG_FXOGS; 01605 case SIG_FXOKS: 01606 return ANALOG_SIG_FXOKS; 01607 case SIG_FXSLS: 01608 return ANALOG_SIG_FXSLS; 01609 case SIG_FXSGS: 01610 return ANALOG_SIG_FXSGS; 01611 case SIG_FXSKS: 01612 return ANALOG_SIG_FXSKS; 01613 case SIG_EMWINK: 01614 return ANALOG_SIG_EMWINK; 01615 case SIG_EM: 01616 return ANALOG_SIG_EM; 01617 case SIG_EM_E1: 01618 return ANALOG_SIG_EM_E1; 01619 case SIG_FEATD: 01620 return ANALOG_SIG_FEATD; 01621 case SIG_FEATDMF: 01622 return ANALOG_SIG_FEATDMF; 01623 case SIG_E911: 01624 return SIG_E911; 01625 case SIG_FGC_CAMA: 01626 return ANALOG_SIG_FGC_CAMA; 01627 case SIG_FGC_CAMAMF: 01628 return ANALOG_SIG_FGC_CAMAMF; 01629 case SIG_FEATB: 01630 return ANALOG_SIG_FEATB; 01631 case SIG_SFWINK: 01632 return ANALOG_SIG_SFWINK; 01633 case SIG_SF: 01634 return ANALOG_SIG_SF; 01635 case SIG_SF_FEATD: 01636 return ANALOG_SIG_SF_FEATD; 01637 case SIG_SF_FEATDMF: 01638 return ANALOG_SIG_SF_FEATDMF; 01639 case SIG_FEATDMF_TA: 01640 return ANALOG_SIG_FEATDMF_TA; 01641 case SIG_SF_FEATB: 01642 return ANALOG_SIG_FEATB; 01643 default: 01644 return -1; 01645 } 01646 }
| static void deep_copy_dahdi_chan_conf | ( | struct dahdi_chan_conf * | dest, | |
| const struct dahdi_chan_conf * | src | |||
| ) | [static] |
Definition at line 18112 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().
18113 { 18114 struct ast_cc_config_params *cc_params; 18115 18116 cc_params = dest->chan.cc_params; 18117 *dest = *src; 18118 dest->chan.cc_params = cc_params; 18119 ast_cc_copy_config_params(dest->chan.cc_params, src->chan.cc_params); 18120 }
| static void destroy_all_channels | ( | void | ) | [static] |
Definition at line 5840 of file chan_dahdi.c.
References ast_db_del(), ast_db_get(), ast_mutex_lock, ast_mutex_unlock, ast_verb, dahdi_pvt::channel, destroy_dahdi_pvt(), sig_pri_span::lock, sig_pri_span::no_b_chan_iflist, NUM_SPANS, sig_pri_span::pri, and dahdi_pvt::span.
Referenced by __unload_module(), and dahdi_restart().
05841 { 05842 int chan; 05843 #if defined(HAVE_PRI) 05844 unsigned span; 05845 struct sig_pri_span *pri; 05846 #endif /* defined(HAVE_PRI) */ 05847 struct dahdi_pvt *p; 05848 05849 while (num_restart_pending) { 05850 usleep(1); 05851 } 05852 05853 ast_mutex_lock(&iflock); 05854 /* Destroy all the interfaces and free their memory */ 05855 while (iflist) { 05856 p = iflist; 05857 05858 chan = p->channel; 05859 #if defined(HAVE_PRI_SERVICE_MESSAGES) 05860 { 05861 char db_chan_name[20]; 05862 char db_answer[5]; 05863 char state; 05864 int why = -1; 05865 05866 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, p->span, chan); 05867 if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) { 05868 sscanf(db_answer, "%1c:%30d", &state, &why); 05869 } 05870 if (!why) { 05871 /* SRVST persistence is not required */ 05872 ast_db_del(db_chan_name, SRVST_DBKEY); 05873 } 05874 } 05875 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 05876 /* Free associated memory */ 05877 destroy_dahdi_pvt(p); 05878 ast_verb(3, "Unregistered channel %d\n", chan); 05879 } 05880 ifcount = 0; 05881 ast_mutex_unlock(&iflock); 05882 05883 #if defined(HAVE_PRI) 05884 /* Destroy all of the no B channel interface lists */ 05885 for (span = 0; span < NUM_SPANS; ++span) { 05886 if (!pris[span].dchannels[0]) { 05887 break; 05888 } 05889 pri = &pris[span].pri; 05890 ast_mutex_lock(&pri->lock); 05891 while (pri->no_b_chan_iflist) { 05892 p = pri->no_b_chan_iflist; 05893 05894 /* Free associated memory */ 05895 destroy_dahdi_pvt(p); 05896 } 05897 ast_mutex_unlock(&pri->lock); 05898 } 05899 #endif /* defined(HAVE_PRI) */ 05900 }
| static void destroy_channel | ( | struct dahdi_pvt * | cur, | |
| int | now | |||
| ) | [static] |
Definition at line 5822 of file chan_dahdi.c.
References destroy_dahdi_pvt(), dahdi_subchannel::owner, dahdi_pvt::owner, and dahdi_pvt::subs.
Referenced by dahdi_destroy_channel_bynum(), and dahdi_hangup().
05823 { 05824 int i; 05825 05826 if (!now) { 05827 /* Do not destroy the channel now if it is owned by someone. */ 05828 if (cur->owner) { 05829 return; 05830 } 05831 for (i = 0; i < 3; i++) { 05832 if (cur->subs[i].owner) { 05833 return; 05834 } 05835 } 05836 } 05837 destroy_dahdi_pvt(cur); 05838 }
| static void destroy_dahdi_pvt | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5752 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_NONE, 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::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(), destroy_channel(), duplicate_pseudo(), and mkintf().
05753 { 05754 struct dahdi_pvt *p = pvt; 05755 05756 if (p->manages_span_alarms) { 05757 struct dahdi_pvt *next = find_next_iface_in_span(p); 05758 if (next) { 05759 next->manages_span_alarms = 1; 05760 } 05761 } 05762 05763 /* Remove channel from the list */ 05764 #if defined(HAVE_PRI) 05765 dahdi_unlink_pri_pvt(p); 05766 #endif /* defined(HAVE_PRI) */ 05767 #if defined(HAVE_SS7) 05768 dahdi_unlink_ss7_pvt(p); 05769 #endif /* defined(HAVE_SS7) */ 05770 switch (pvt->which_iflist) { 05771 case DAHDI_IFLIST_NONE: 05772 break; 05773 case DAHDI_IFLIST_MAIN: 05774 dahdi_iflist_extract(p); 05775 break; 05776 #if defined(HAVE_PRI) 05777 case DAHDI_IFLIST_NO_B_CHAN: 05778 if (p->pri) { 05779 dahdi_nobch_extract(p->pri, p); 05780 } 05781 break; 05782 #endif /* defined(HAVE_PRI) */ 05783 } 05784 05785 if (p->sig_pvt) { 05786 if (analog_lib_handles(p->sig, 0, 0)) { 05787 analog_delete(p->sig_pvt); 05788 } 05789 switch (p->sig) { 05790 #if defined(HAVE_PRI) 05791 case SIG_PRI_LIB_HANDLE_CASES: 05792 sig_pri_chan_delete(p->sig_pvt); 05793 break; 05794 #endif /* defined(HAVE_PRI) */ 05795 #if defined(HAVE_SS7) 05796 case SIG_SS7: 05797 sig_ss7_chan_delete(p->sig_pvt); 05798 break; 05799 #endif /* defined(HAVE_SS7) */ 05800 default: 05801 break; 05802 } 05803 } 05804 ast_free(p->cidspill); 05805 if (p->use_smdi) 05806 ast_smdi_interface_unref(p->smdi_iface); 05807 if (p->mwi_event_sub) 05808 ast_event_unsubscribe(p->mwi_event_sub); 05809 if (p->vars) { 05810 ast_variables_destroy(p->vars); 05811 } 05812 if (p->cc_params) { 05813 ast_cc_config_params_destroy(p->cc_params); 05814 } 05815 ast_mutex_destroy(&p->lock); 05816 dahdi_close_sub(p, SUB_REAL); 05817 if (p->owner) 05818 p->owner->tech_pvt = NULL; 05819 ast_free(p); 05820 }
| static struct dahdi_pvt* determine_starting_point | ( | const char * | data, | |
| struct dahdi_starting_point * | param | |||
| ) | [static, read] |
Definition at line 13525 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(), dahdi_starting_point::backwards, dahdi_starting_point::cadance, CHAN_PSEUDO, dahdi_starting_point::channelmatch, errno, dahdi_starting_point::groupmatch, LOG_ERROR, LOG_WARNING, dahdi_pvt::next, dahdi_starting_point::opt, dahdi_pvt::prev, dahdi_starting_point::roundrobin, dahdi_starting_point::rr_starting_point, and dahdi_starting_point::span.
Referenced by dahdi_cc_callback(), and dahdi_request().
13526 { 13527 char *dest; 13528 char *s; 13529 int x; 13530 int res = 0; 13531 struct dahdi_pvt *p; 13532 char *subdir = NULL; 13533 AST_DECLARE_APP_ARGS(args, 13534 AST_APP_ARG(group); /* channel/group token */ 13535 //AST_APP_ARG(ext); /* extension token */ 13536 //AST_APP_ARG(opts); /* options token */ 13537 AST_APP_ARG(other); /* Any remining unused arguments */ 13538 ); 13539 13540 /* 13541 * data is ---v 13542 * Dial(DAHDI/pseudo[/extension[/options]]) 13543 * Dial(DAHDI/<channel#>[c|r<cadance#>|d][/extension[/options]]) 13544 * Dial(DAHDI/<subdir>!<channel#>[c|r<cadance#>|d][/extension[/options]]) 13545 * Dial(DAHDI/i<span>[/extension[/options]]) 13546 * Dial(DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]) 13547 * 13548 * i - ISDN span channel restriction. 13549 * Used by CC to ensure that the CC recall goes out the same span. 13550 * Also to make ISDN channel names dialable when the sequence number 13551 * is stripped off. (Used by DTMF attended transfer feature.) 13552 * 13553 * g - channel group allocation search forward 13554 * G - channel group allocation search backward 13555 * r - channel group allocation round robin search forward 13556 * R - channel group allocation round robin search backward 13557 * 13558 * c - Wait for DTMF digit to confirm answer 13559 * r<cadance#> - Set distintive ring cadance number 13560 * d - Force bearer capability for ISDN/SS7 call to digital. 13561 */ 13562 13563 if (data) { 13564 dest = ast_strdupa(data); 13565 } else { 13566 ast_log(LOG_WARNING, "Channel requested with no data\n"); 13567 return NULL; 13568 } 13569 AST_NONSTANDARD_APP_ARGS(args, dest, '/'); 13570 if (!args.argc || ast_strlen_zero(args.group)) { 13571 ast_log(LOG_WARNING, "No channel/group specified\n"); 13572 return NULL; 13573 } 13574 13575 /* Initialize the output parameters */ 13576 memset(param, 0, sizeof(*param)); 13577 param->channelmatch = -1; 13578 13579 if (strchr(args.group, '!') != NULL) { 13580 char *prev = args.group; 13581 while ((s = strchr(prev, '!')) != NULL) { 13582 *s++ = '/'; 13583 prev = s; 13584 } 13585 *(prev - 1) = '\0'; 13586 subdir = args.group; 13587 args.group = prev; 13588 } else if (args.group[0] == 'i') { 13589 /* Extract the ISDN span channel restriction specifier. */ 13590 res = sscanf(args.group + 1, "%30d", &x); 13591 if (res < 1) { 13592 ast_log(LOG_WARNING, "Unable to determine ISDN span for data %s\n", data); 13593 return NULL; 13594 } 13595 param->span = x; 13596 13597 /* Remove the ISDN span channel restriction specifier. */ 13598 s = strchr(args.group, '-'); 13599 if (!s) { 13600 /* Search all groups since we are ISDN span restricted. */ 13601 return iflist; 13602 } 13603 args.group = s + 1; 13604 res = 0; 13605 } 13606 if (toupper(args.group[0]) == 'G' || toupper(args.group[0])=='R') { 13607 /* Retrieve the group number */ 13608 s = args.group + 1; 13609 res = sscanf(s, "%30d%1c%30d", &x, ¶m->opt, ¶m->cadance); 13610 if (res < 1) { 13611 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", data); 13612 return NULL; 13613 } 13614 param->groupmatch = ((ast_group_t) 1 << x); 13615 13616 if (toupper(args.group[0]) == 'G') { 13617 if (args.group[0] == 'G') { 13618 param->backwards = 1; 13619 p = ifend; 13620 } else 13621 p = iflist; 13622 } else { 13623 if (ARRAY_LEN(round_robin) <= x) { 13624 ast_log(LOG_WARNING, "Round robin index %d out of range for data %s\n", 13625 x, data); 13626 return NULL; 13627 } 13628 if (args.group[0] == 'R') { 13629 param->backwards = 1; 13630 p = round_robin[x] ? round_robin[x]->prev : ifend; 13631 if (!p) 13632 p = ifend; 13633 } else { 13634 p = round_robin[x] ? round_robin[x]->next : iflist; 13635 if (!p) 13636 p = iflist; 13637 } 13638 param->roundrobin = 1; 13639 param->rr_starting_point = x; 13640 } 13641 } else { 13642 s = args.group; 13643 if (!strcasecmp(s, "pseudo")) { 13644 /* Special case for pseudo */ 13645 x = CHAN_PSEUDO; 13646 param->channelmatch = x; 13647 } else { 13648 res = sscanf(s, "%30d%1c%30d", &x, ¶m->opt, ¶m->cadance); 13649 if (res < 1) { 13650 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", data); 13651 return NULL; 13652 } else { 13653 param->channelmatch = x; 13654 } 13655 } 13656 if (subdir) { 13657 char path[PATH_MAX]; 13658 struct stat stbuf; 13659 13660 snprintf(path, sizeof(path), "/dev/dahdi/%s/%d", 13661 subdir, param->channelmatch); 13662 if (stat(path, &stbuf) < 0) { 13663 ast_log(LOG_WARNING, "stat(%s) failed: %s\n", 13664 path, strerror(errno)); 13665 return NULL; 13666 } 13667 if (!S_ISCHR(stbuf.st_mode)) { 13668 ast_log(LOG_ERROR, "%s: Not a character device file\n", 13669 path); 13670 return NULL; 13671 } 13672 param->channelmatch = minor(stbuf.st_rdev); 13673 } 13674 13675 p = iflist; 13676 } 13677 13678 if (param->opt == 'r' && res < 3) { 13679 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", data); 13680 param->opt = '\0'; 13681 } 13682 13683 return p; 13684 }
| static int device2chan | ( | const char * | subdir, | |
| int | channel, | |||
| char * | path, | |||
| int | pathlen | |||
| ) | [static] |
Definition at line 12299 of file chan_dahdi.c.
References ast_log(), errno, LOG_DEBUG, and LOG_ERROR.
Referenced by build_channels().
12300 { 12301 struct stat stbuf; 12302 int num; 12303 12304 snprintf(path, pathlen, "/dev/dahdi/%s/%d", subdir, channel); 12305 if (stat(path, &stbuf) < 0) { 12306 ast_log(LOG_ERROR, "stat(%s) failed: %s\n", path, strerror(errno)); 12307 return -errno; 12308 } 12309 if (!S_ISCHR(stbuf.st_mode)) { 12310 ast_log(LOG_ERROR, "%s: Not a character device file\n", path); 12311 return -EINVAL; 12312 } 12313 num = minor(stbuf.st_rdev); 12314 ast_log(LOG_DEBUG, "%s -> %d\n", path, num); 12315 return num; 12316 12317 }
| static int digit_to_dtmfindex | ( | char | digit | ) | [static] |
Definition at line 4478 of file chan_dahdi.c.
Referenced by dahdi_digit_begin().
04479 { 04480 if (isdigit(digit)) 04481 return DAHDI_TONE_DTMF_BASE + (digit - '0'); 04482 else if (digit >= 'A' && digit <= 'D') 04483 return DAHDI_TONE_DTMF_A + (digit - 'A'); 04484 else if (digit >= 'a' && digit <= 'd') 04485 return DAHDI_TONE_DTMF_A + (digit - 'a'); 04486 else if (digit == '*') 04487 return DAHDI_TONE_DTMF_s; 04488 else if (digit == '#') 04489 return DAHDI_TONE_DTMF_p; 04490 else 04491 return -1; 04492 }
| static void disable_dtmf_detect | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 6651 of file chan_dahdi.c.
References ast_dsp_set_features(), dahdi_subchannel::dfd, 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().
06652 { 06653 int val = 0; 06654 06655 p->ignoredtmf = 1; 06656 06657 ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val); 06658 06659 if (!p->hardwaredtmf && p->dsp) { 06660 p->dsp_features &= ~DSP_FEATURE_DIGIT_DETECT; 06661 ast_dsp_set_features(p->dsp, p->dsp_features); 06662 } 06663 }
| static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 11714 of file chan_dahdi.c.
References ANALOG_EVENT_DTMFCID, analog_handle_init_event(), analog_lib_handles(), analog_ss_thread(), ast_calloc, ast_debug, ast_fdisset(), ast_free, ast_hangup(), AST_LAW, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, ast_pthread_create_detached, AST_STATE_PRERING, ast_strlen_zero(), mwi_thread_data::buf, calc_energy(), dahdi_pvt::channel, dahdi_pvt::cid_start, CID_START_DTMF_NOALERT, dahdi_pvt::cidspill, dahdi_destroy_channel_bynum(), dahdi_get_event(), dahdi_new(), dahdievent_to_analogevent(), dahdi_subchannel::dfd, dahdi_pvt::dtmfcid_delay, dahdi_pvt::dtmfcid_holdoff_state, errno, event2str(), analog_pvt::fxsoffhookstate, handle_init_event(), has_voicemail(), last, mwi_thread_data::len, dahdi_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, dahdi_pvt::mailbox, monitor_pfds_clean(), analog_pvt::msgstate, mwi_send_init(), mwi_send_process_buffer(), mwi_send_process_event(), mwi_thread(), dahdi_pvt::mwimonitor_fsk, dahdi_pvt::mwimonitoractive, dahdi_pvt::mwisendactive, dahdi_pvt::next, analog_pvt::onhooktime, dahdi_pvt::oprmode, dahdi_subchannel::owner, dahdi_pvt::owner, analog_subchannel::owner, analog_pvt::owner, mwi_thread_data::pvt, dahdi_pvt::radio, RESULT_SUCCESS, dahdi_pvt::sig, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_MFCR2, dahdi_pvt::sig_pvt, SUB_REAL, analog_pvt::subs, and dahdi_pvt::subs.
Referenced by restart_monitor().
11715 { 11716 int count, res, res2, spoint, pollres=0; 11717 struct dahdi_pvt *i; 11718 struct dahdi_pvt *last = NULL; 11719 struct dahdi_pvt *doomed; 11720 time_t thispass = 0, lastpass = 0; 11721 int found; 11722 char buf[1024]; 11723 struct pollfd *pfds=NULL; 11724 int lastalloc = -1; 11725 /* This thread monitors all the frame relay interfaces which are not yet in use 11726 (and thus do not have a separate thread) indefinitely */ 11727 /* From here on out, we die whenever asked */ 11728 #if 0 11729 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 11730 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 11731 return NULL; 11732 } 11733 ast_debug(1, "Monitor starting...\n"); 11734 #endif 11735 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 11736 11737 pthread_cleanup_push(monitor_pfds_clean, &pfds); 11738 for (;;) { 11739 /* Lock the interface list */ 11740 ast_mutex_lock(&iflock); 11741 if (!pfds || (lastalloc != ifcount)) { 11742 if (pfds) { 11743 ast_free(pfds); 11744 pfds = NULL; 11745 } 11746 if (ifcount) { 11747 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) { 11748 ast_mutex_unlock(&iflock); 11749 return NULL; 11750 } 11751 } 11752 lastalloc = ifcount; 11753 } 11754 /* Build the stuff we're going to poll on, that is the socket of every 11755 dahdi_pvt that does not have an associated owner channel */ 11756 count = 0; 11757 for (i = iflist; i; i = i->next) { 11758 ast_mutex_lock(&i->lock); 11759 if (pfds && (i->subs[SUB_REAL].dfd > -1) && i->sig && (!i->radio) && !(i->sig & SIG_MFCR2)) { 11760 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) { 11761 struct analog_pvt *p = i->sig_pvt; 11762 11763 if (!p) { 11764 ast_log(LOG_ERROR, "No sig_pvt?\n"); 11765 } else if (!p->owner && !p->subs[SUB_REAL].owner) { 11766 /* This needs to be watched, as it lacks an owner */ 11767 pfds[count].fd = i->subs[SUB_REAL].dfd; 11768 pfds[count].events = POLLPRI; 11769 pfds[count].revents = 0; 11770 /* Message waiting or r2 channels also get watched for reading */ 11771 if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk || 11772 (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) { 11773 pfds[count].events |= POLLIN; 11774 } 11775 count++; 11776 } 11777 } else { 11778 if (!i->owner && !i->subs[SUB_REAL].owner && !i->mwimonitoractive ) { 11779 /* This needs to be watched, as it lacks an owner */ 11780 pfds[count].fd = i->subs[SUB_REAL].dfd; 11781 pfds[count].events = POLLPRI; 11782 pfds[count].revents = 0; 11783 /* If we are monitoring for VMWI or sending CID, we need to 11784 read from the channel as well */ 11785 if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk || 11786 (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) { 11787 pfds[count].events |= POLLIN; 11788 } 11789 count++; 11790 } 11791 } 11792 } 11793 ast_mutex_unlock(&i->lock); 11794 } 11795 /* Okay, now that we know what to do, release the interface lock */ 11796 ast_mutex_unlock(&iflock); 11797 11798 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 11799 pthread_testcancel(); 11800 /* Wait at least a second for something to happen */ 11801 res = poll(pfds, count, 1000); 11802 pthread_testcancel(); 11803 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 11804 11805 /* Okay, poll has finished. Let's see what happened. */ 11806 if (res < 0) { 11807 if ((errno != EAGAIN) && (errno != EINTR)) 11808 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 11809 continue; 11810 } 11811 /* Alright, lock the interface list again, and let's look and see what has 11812 happened */ 11813 ast_mutex_lock(&iflock); 11814 found = 0; 11815 spoint = 0; 11816 lastpass = thispass; 11817 thispass = time(NULL); 11818 doomed = NULL; 11819 for (i = iflist;; i = i->next) { 11820 if (doomed) { 11821 int res; 11822 res = dahdi_destroy_channel_bynum(doomed->channel); 11823 if (res != RESULT_SUCCESS) { 11824 ast_log(LOG_WARNING, "Couldn't find channel to destroy, hopefully another destroy operation just happened.\n"); 11825 } 11826 doomed = NULL; 11827 } 11828 if (!i) { 11829 break; 11830 } 11831 11832 if (thispass != lastpass) { 11833 if (!found && ((i == last) || ((i == iflist) && !last))) { 11834 last = i; 11835 if (last) { 11836 struct analog_pvt *analog_p = last->sig_pvt; 11837 /* Only allow MWI to be initiated on a quiescent fxs port */ 11838 if (analog_p 11839 && !last->mwisendactive 11840 && (last->sig & __DAHDI_SIG_FXO) 11841 && !analog_p->fxsoffhookstate 11842 && !last->owner 11843 && !ast_strlen_zero(last->mailbox) 11844 && (thispass - analog_p->onhooktime > 3)) { 11845 res = has_voicemail(last); 11846 if (analog_p->msgstate != res) { 11847 /* Set driver resources for signalling VMWI */ 11848 res2 = ioctl(last->subs[SUB_REAL].dfd, DAHDI_VMWI, &res); 11849 if (res2) { 11850 /* TODO: This message will ALWAYS be generated on some cards; any way to restrict it to those cards where it is interesting? */ 11851 ast_debug(3, "Unable to control message waiting led on channel %d: %s\n", last->channel, strerror(errno)); 11852 } 11853 /* If enabled for FSK spill then initiate it */ 11854 if (mwi_send_init(last)) { 11855 ast_log(LOG_WARNING, "Unable to initiate mwi send sequence on channel %d\n", last->channel); 11856 } 11857 analog_p->msgstate = res; 11858 found ++; 11859 } 11860 } 11861 last = last->next; 11862 } 11863 } 11864 } 11865 if ((i->subs[SUB_REAL].dfd > -1) && i->sig) { 11866 if (i->radio && !i->owner) 11867 { 11868 res = dahdi_get_event(i->subs[SUB_REAL].dfd); 11869 if (res) 11870 { 11871 ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 11872 /* Don't hold iflock while handling init events */ 11873 ast_mutex_unlock(&iflock); 11874 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) 11875 doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res)); 11876 else 11877 doomed = handle_init_event(i, res); 11878 ast_mutex_lock(&iflock); 11879 } 11880 continue; 11881 } 11882 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].dfd, count, &spoint); 11883 if (pollres & POLLIN) { 11884 if (i->owner || i->subs[SUB_REAL].owner) { 11885 #ifdef HAVE_PRI 11886 if (!i->pri) 11887 #endif 11888 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd); 11889 continue; 11890 } 11891 if (!i->mwimonitor_fsk && !i->mwisendactive && i->cid_start != CID_START_DTMF_NOALERT) { 11892 ast_log(LOG_WARNING, "Whoa.... I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd); 11893 continue; 11894 } 11895 res = read(i->subs[SUB_REAL].dfd, buf, sizeof(buf)); 11896 if (res > 0) { 11897 if (i->mwimonitor_fsk) { 11898 if (calc_energy((unsigned char *) buf, res, AST_LAW(i)) > mwilevel) { 11899 pthread_attr_t attr; 11900 pthread_t threadid; 11901 struct mwi_thread_data *mtd; 11902 11903 pthread_attr_init(&attr); 11904 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 11905 11906 ast_log(LOG_DEBUG, "Maybe some MWI on port %d!\n", i->channel); 11907 if ((mtd = ast_calloc(1, sizeof(*mtd)))) { 11908 mtd->pvt = i; 11909 memcpy(mtd->buf, buf, res); 11910 mtd->len = res; 11911 i->mwimonitoractive = 1; 11912 if (ast_pthread_create_background(&threadid, &attr, mwi_thread, mtd)) { 11913 ast_log(LOG_WARNING, "Unable to start mwi thread on channel %d\n", i->channel); 11914 i->mwimonitoractive = 0; 11915 ast_free(mtd); 11916 } 11917 } 11918 } 11919 /* If configured to check for a DTMF CID spill that comes without alert (e.g no polarity reversal) */ 11920 } else if (i->cid_start == CID_START_DTMF_NOALERT) { 11921 int energy; 11922 struct timeval now; 11923 /* State machine dtmfcid_holdoff_state allows for the line to settle 11924 * before checking agin for dtmf energy. Presently waits for 500 mS before checking again 11925 */ 11926 if (1 == i->dtmfcid_holdoff_state) { 11927 gettimeofday(&i->dtmfcid_delay, NULL); 11928 i->dtmfcid_holdoff_state = 2; 11929 } else if (2 == i->dtmfcid_holdoff_state) { 11930 gettimeofday(&now, NULL); 11931 if ((int)(now.tv_sec - i->dtmfcid_delay.tv_sec) * 1000000 + (int)now.tv_usec - (int)i->dtmfcid_delay.tv_usec > 500000) { 11932 i->dtmfcid_holdoff_state = 0; 11933 } 11934 } else { 11935 energy = calc_energy((unsigned char *) buf, res, AST_LAW(i)); 11936 if (!i->mwisendactive && energy > dtmfcid_level) { 11937 pthread_t threadid; 11938 struct ast_channel *chan; 11939 ast_mutex_unlock(&iflock); 11940 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) { 11941 /* just in case this event changes or somehow destroys a channel, set doomed here too */ 11942 doomed = analog_handle_init_event(i->sig_pvt, ANALOG_EVENT_DTMFCID); 11943 i->dtmfcid_holdoff_state = 1; 11944 } else { 11945 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11946 if (!chan) { 11947 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11948 } else { 11949 res = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan); 11950 if (res) { 11951 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11952 ast_hangup(chan); 11953 } else { 11954 i->dtmfcid_holdoff_state = 1; 11955 } 11956 } 11957 } 11958 ast_mutex_lock(&iflock); 11959 } 11960 } 11961 } 11962 if (i->mwisendactive) { 11963 mwi_send_process_buffer(i, res); 11964 } 11965 } else { 11966 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 11967 } 11968 } 11969 if (pollres & POLLPRI) { 11970 if (i->owner || i->subs[SUB_REAL].owner) { 11971 #ifdef HAVE_PRI 11972 if (!i->pri) 11973 #endif 11974 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].dfd); 11975 continue; 11976 } 11977 res = dahdi_get_event(i->subs[SUB_REAL].dfd); 11978 ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 11979 /* Don't hold iflock while handling init events */ 11980 ast_mutex_unlock(&iflock); 11981 if (0 == i->mwisendactive || 0 == mwi_send_process_event(i, res)) { 11982 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) 11983 doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res)); 11984 else 11985 doomed = handle_init_event(i, res); 11986 } 11987 ast_mutex_lock(&iflock); 11988 } 11989 } 11990 } 11991 ast_mutex_unlock(&iflock); 11992 } 11993 /* Never reached */ 11994 pthread_cleanup_pop(1); 11995 return NULL; 11996 11997 }
| static int drc_sample | ( | int | sample, | |
| float | drc | |||
| ) | [static] |
Definition at line 4981 of file chan_dahdi.c.
Referenced by fill_rxgain(), and fill_txgain().
04982 { 04983 float neg; 04984 float shallow, steep; 04985 float max = SHRT_MAX; 04986 04987 neg = (sample < 0 ? -1 : 1); 04988 steep = drc*sample; 04989 shallow = neg*(max-max/drc)+(float)sample/drc; 04990 if (abs(steep) < abs(shallow)) { 04991 sample = steep; 04992 } 04993 else { 04994 sample = shallow; 04995 } 04996 04997 return sample; 04998 }
Definition at line 13461 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(), dahdi_pvt::destroy, destroy_dahdi_pvt(), dahdi_subchannel::dfd, errno, dahdi_pvt::lock, LOG_ERROR, LOG_WARNING, dahdi_pvt::next, dahdi_pvt::prev, SUB_REAL, dahdi_pvt::subs, and dahdi_pvt::which_iflist.
Referenced by dahdi_request().
13462 { 13463 struct dahdi_pvt *p; 13464 struct dahdi_bufferinfo bi; 13465 int res; 13466 13467 p = ast_malloc(sizeof(*p)); 13468 if (!p) { 13469 return NULL; 13470 } 13471 *p = *src; 13472 13473 /* Must deep copy the cc_params. */ 13474 p->cc_params = ast_cc_config_params_init(); 13475 if (!p->cc_params) { 13476 ast_free(p); 13477 return NULL; 13478 } 13479 ast_cc_copy_config_params(p->cc_params, src->cc_params); 13480 13481 p->which_iflist = DAHDI_IFLIST_NONE; 13482 p->next = NULL; 13483 p->prev = NULL; 13484 ast_mutex_init(&p->lock); 13485 p->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo"); 13486 if (p->subs[SUB_REAL].dfd < 0) { 13487 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 13488 destroy_dahdi_pvt(p); 13489 return NULL; 13490 } 13491 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi); 13492 if (!res) { 13493 bi.txbufpolicy = src->buf_policy; 13494 bi.rxbufpolicy = src->buf_policy; 13495 bi.numbufs = src->buf_no; 13496 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi); 13497 if (res < 0) { 13498 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel: %s\n", strerror(errno)); 13499 } 13500 } else 13501 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel: %s\n", strerror(errno)); 13502 p->destroy = 1; 13503 dahdi_iflist_insert(p); 13504 return p; 13505 }
| static void enable_dtmf_detect | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 6665 of file chan_dahdi.c.
References ast_dsp_set_features(), CHAN_PSEUDO, dahdi_pvt::channel, dahdi_subchannel::dfd, 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().
06666 { 06667 int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE; 06668 06669 if (p->channel == CHAN_PSEUDO) 06670 return; 06671 06672 p->ignoredtmf = 0; 06673 06674 ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val); 06675 06676 if (!p->hardwaredtmf && p->dsp) { 06677 p->dsp_features |= DSP_FEATURE_DIGIT_DETECT; 06678 ast_dsp_set_features(p->dsp, p->dsp_features); 06679 } 06680 }
| static const char * event2str | ( | int | event | ) | [static] |
Definition at line 4633 of file chan_dahdi.c.
References ARRAY_LEN.
Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_handle_event(), do_monitor(), mwi_thread(), and my_distinctive_ring().
| static void fill_rxgain | ( | struct dahdi_gains * | g, | |
| float | gain, | |||
| float | drc, | |||
| int | law | |||
| ) | [static] |
Definition at line 5051 of file chan_dahdi.c.
References ARRAY_LEN, AST_ALAW, AST_LIN2A, AST_LIN2MU(), AST_MULAW, and drc_sample().
Referenced by set_actual_rxgain().
05052 { 05053 int j; 05054 int k; 05055 float linear_gain = pow(10.0, gain / 20.0); 05056 05057 switch (law) { 05058 case DAHDI_LAW_ALAW: 05059 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) { 05060 if (gain || drc) { 05061 k = AST_ALAW(j); 05062 if (drc) { 05063 k = drc_sample(k, drc); 05064 } 05065 k = (float)k * linear_gain; 05066 if (k > 32767) { 05067 k = 32767; 05068 } else if (k < -32768) { 05069 k = -32768; 05070 } 05071 g->rxgain[j] = AST_LIN2A(k); 05072 } else { 05073 g->rxgain[j] = j; 05074 } 05075 } 05076 break; 05077 case DAHDI_LAW_MULAW: 05078 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) { 05079 if (gain || drc) { 05080 k = AST_MULAW(j); 05081 if (drc) { 05082 k = drc_sample(k, drc); 05083 } 05084 k = (float)k * linear_gain; 05085 if (k > 32767) { 05086 k = 32767; 05087 } else if (k < -32768) { 05088 k = -32768; 05089 } 05090 g->rxgain[j] = AST_LIN2MU(k); 05091 } else { 05092 g->rxgain[j] = j; 05093 } 05094 } 05095 break; 05096 } 05097 }
| static void fill_txgain | ( | struct dahdi_gains * | g, | |
| float | gain, | |||
| float | drc, | |||
| int | law | |||
| ) | [static] |
Definition at line 5001 of file chan_dahdi.c.
References ARRAY_LEN, AST_ALAW, AST_LIN2A, AST_LIN2MU(), AST_MULAW, and drc_sample().
Referenced by set_actual_txgain().
05002 { 05003 int j; 05004 int k; 05005 05006 float linear_gain = pow(10.0, gain / 20.0); 05007 05008 switch (law) { 05009 case DAHDI_LAW_ALAW: 05010 for (j = 0; j < ARRAY_LEN(g->txgain); j++) { 05011 if (gain || drc) { 05012 k = AST_ALAW(j); 05013 if (drc) { 05014 k = drc_sample(k, drc); 05015 } 05016 k = (float)k * linear_gain; 05017 if (k > 32767) { 05018 k = 32767; 05019 } else if (k < -32768) { 05020 k = -32768; 05021 } 05022 g->txgain[j] = AST_LIN2A(k); 05023 } else { 05024 g->txgain[j] = j; 05025 } 05026 } 05027 break; 05028 case DAHDI_LAW_MULAW: 05029 for (j = 0; j < ARRAY_LEN(g->txgain); j++) { 05030 if (gain || drc) { 05031 k = AST_MULAW(j); 05032 if (drc) { 05033 k = drc_sample(k, drc); 05034 } 05035 k = (float)k * linear_gain; 05036 if (k > 32767) { 05037 k = 32767; 05038 } else if (k < -32768) { 05039 k = -32768; 05040 } 05041 g->txgain[j] = AST_LIN2MU(k); 05042 05043 } else { 05044 g->txgain[j] = j; 05045 } 05046 } 05047 break; 05048 } 05049 }
| static struct dahdi_pvt* find_channel | ( | int | channel | ) | [static, read] |
Definition at line 15928 of file chan_dahdi.c.
References ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, and dahdi_pvt::next.
Referenced by find_channel_from_str().
15929 { 15930 struct dahdi_pvt *p; 15931 15932 ast_mutex_lock(&iflock); 15933 for (p = iflist; p; p = p->next) { 15934 if (p->channel == channel) { 15935 break; 15936 } 15937 } 15938 ast_mutex_unlock(&iflock); 15939 return p; 15940 }
| static struct dahdi_pvt* find_channel_from_str | ( | const char * | channel | ) | [static, read] |
Definition at line 15951 of file chan_dahdi.c.
References find_channel().
Referenced by action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_transfer(), and action_transferhangup().
15952 { 15953 int chan_num; 15954 15955 if (sscanf(channel, "%30d", &chan_num) != 1) { 15956 /* Not numeric string. */ 15957 return NULL; 15958 } 15959 15960 return find_channel(chan_num); 15961 }
Definition at line 5741 of file chan_dahdi.c.
References dahdi_pvt::next, dahdi_pvt::prev, and dahdi_pvt::span.
Referenced by destroy_dahdi_pvt().
| static int get_alarms | ( | struct dahdi_pvt * | p | ) | [static] |
Checks channel for alarms
| p | a channel to check for alarms. |
Definition at line 7737 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, dahdi_subchannel::dfd, errno, LOG_WARNING, dahdi_pvt::span, SUB_REAL, and dahdi_pvt::subs.
Referenced by action_dahdishowchannels(), dahdi_handle_event(), handle_init_event(), mkintf(), mwi_thread(), and my_get_and_handle_alarms().
07738 { 07739 int res; 07740 struct dahdi_spaninfo zi; 07741 struct dahdi_params params; 07742 07743 memset(&zi, 0, sizeof(zi)); 07744 zi.spanno = p->span; 07745 07746 if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SPANSTAT, &zi)) >= 0) { 07747 if (zi.alarms != DAHDI_ALARM_NONE) 07748 return zi.alarms; 07749 } else { 07750 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d: %s\n", p->channel, strerror(errno)); 07751 return 0; 07752 } 07753 07754 /* No alarms on the span. Check for channel alarms. */ 07755 memset(¶ms, 0, sizeof(params)); 07756 if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, ¶ms)) >= 0) 07757 return params.chan_alarms; 07758 07759 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 07760 07761 return DAHDI_ALARM_NONE; 07762 }
| static void handle_alarms | ( | struct dahdi_pvt * | p, | |
| int | alms | |||
| ) | [static] |
Definition at line 7862 of file chan_dahdi.c.
References alarm2str(), ast_log(), dahdi_pvt::channel, dahdi_sig_pri_lib_handles(), EVENT_FLAG_SYSTEM, LOG_WARNING, manager_event, dahdi_pvt::manages_span_alarms, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, dahdi_pvt::sig, sig_pri_is_alarm_ignored(), and dahdi_pvt::span.
Referenced by dahdi_handle_event(), handle_init_event(), mkintf(), mwi_thread(), and my_get_and_handle_alarms().
07863 { 07864 const char *alarm_str; 07865 07866 #if defined(HAVE_PRI) 07867 if (dahdi_sig_pri_lib_handles(p->sig) && sig_pri_is_alarm_ignored(p->pri)) { 07868 return; 07869 } 07870 #endif /* defined(HAVE_PRI) */ 07871 07872 alarm_str = alarm2str(alms); 07873 if (report_alarms & REPORT_CHANNEL_ALARMS) { 07874 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str); 07875 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 07876 "Alarm: %s\r\n" 07877 "Channel: %d\r\n", 07878 alarm_str, p->channel); 07879 } 07880 07881 if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) { 07882 ast_log(LOG_WARNING, "Detected alarm on span %d: %s\n", p->span, alarm_str); 07883 manager_event(EVENT_FLAG_SYSTEM, "SpanAlarm", 07884 "Alarm: %s\r\n" 07885 "Span: %d\r\n", 07886 alarm_str, p->span); 07887 } 07888 }
| static void handle_clear_alarms | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 3847 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, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, dahdi_pvt::sig, sig_pri_is_alarm_ignored(), and dahdi_pvt::span.
Referenced by dahdi_handle_event(), handle_init_event(), and mwi_thread().
03848 { 03849 #if defined(HAVE_PRI) 03850 if (dahdi_sig_pri_lib_handles(p->sig) && sig_pri_is_alarm_ignored(p->pri)) { 03851 return; 03852 } 03853 #endif /* defined(HAVE_PRI) */ 03854 03855 if (report_alarms & REPORT_CHANNEL_ALARMS) { 03856 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 03857 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel); 03858 } 03859 if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) { 03860 ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", p->span); 03861 manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear", "Span: %d\r\n", p->span); 03862 } 03863 }
| static char* handle_dahdi_show_cadences | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15534 of file chan_dahdi.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, ast_cli_entry::command, ast_cli_args::fd, term_color(), and ast_cli_entry::usage.
15535 { 15536 int i, j; 15537 switch (cmd) { 15538 case CLI_INIT: 15539 e->command = "dahdi show cadences"; 15540 e->usage = 15541 "Usage: dahdi show cadences\n" 15542 " Shows all cadences currently defined\n"; 15543 return NULL; 15544 case CLI_GENERATE: 15545 return NULL; 15546 } 15547 for (i = 0; i < num_cadence; i++) { 15548 char output[1024]; 15549 char tmp[16], tmp2[64]; 15550 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 15551 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 15552 15553 for (j = 0; j < 16; j++) { 15554 if (cadences[i].ringcadence[j] == 0) 15555 break; 15556 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 15557 if (cidrings[i] * 2 - 1 == j) 15558 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 15559 else 15560 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 15561 if (j != 0) 15562 strncat(output, ",", sizeof(output) - strlen(output) - 1); 15563 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 15564 } 15565 ast_cli(a->fd,"%s\n",output); 15566 } 15567 return CLI_SUCCESS; 15568 }
Definition at line 11462 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(), dahdi_subchannel::dfd, errno, get_alarms(), handle_alarms(), handle_clear_alarms(), dahdi_pvt::hanguponpolarityswitch, has_voicemail(), dahdi_pvt::immediate, dahdi_pvt::inalarm, dahdi_pvt::lock, LOG_NOTICE, LOG_WARNING, 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.
Referenced by do_monitor().
11463 { 11464 int res; 11465 pthread_t threadid; 11466 struct ast_channel *chan; 11467 11468 /* Handle an event on a given channel for the monitor thread. */ 11469 11470 switch (event) { 11471 case DAHDI_EVENT_NONE: 11472 case DAHDI_EVENT_BITSCHANGED: 11473 break; 11474 case DAHDI_EVENT_WINKFLASH: 11475 case DAHDI_EVENT_RINGOFFHOOK: 11476 if (i->inalarm) break; 11477 if (i->radio) break; 11478 /* Got a ring/answer. What kind of channel are we? */ 11479 switch (i->sig) { 11480 case SIG_FXOLS: 11481 case SIG_FXOGS: 11482 case SIG_FXOKS: 11483 res = dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 11484 if (res && (errno == EBUSY)) 11485 break; 11486 11487 /* Cancel VMWI spill */ 11488 ast_free(i->cidspill); 11489 i->cidspill = NULL; 11490 restore_conference(i); 11491 11492 if (i->immediate) { 11493 dahdi_enable_ec(i); 11494 /* The channel is immediately up. Start right away */ 11495 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 11496 chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, NULL); 11497 if (!chan) { 11498 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 11499 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11500 if (res < 0) 11501 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11502 } 11503 } else { 11504 /* Check for callerid, digits, etc */ 11505 chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, NULL); 11506 if (chan) { 11507 if (has_voicemail(i)) 11508 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER); 11509 else 11510 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE); 11511 if (res < 0) 11512 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 11513 if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11514 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11515 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11516 if (res < 0) 11517 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11518 ast_hangup(chan); 11519 } 11520 } else 11521 ast_log(LOG_WARNING, "Unable to create channel\n"); 11522 } 11523 break; 11524 case SIG_FXSLS: 11525 case SIG_FXSGS: 11526 case SIG_FXSKS: 11527 i->ringt = i->ringt_base; 11528 /* Fall through */ 11529 case SIG_EMWINK: 11530 case SIG_FEATD: 11531 case SIG_FEATDMF: 11532 case SIG_FEATDMF_TA: 11533 case SIG_E911: 11534 case SIG_FGC_CAMA: 11535 case SIG_FGC_CAMAMF: 11536 case SIG_FEATB: 11537 case SIG_EM: 11538 case SIG_EM_E1: 11539 case SIG_SFWINK: 11540 case SIG_SF_FEATD: 11541 case SIG_SF_FEATDMF: 11542 case SIG_SF_FEATB: 11543 case SIG_SF: 11544 /* Check for callerid, digits, etc */ 11545 if (i->cid_start == CID_START_POLARITY_IN) { 11546 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11547 } else { 11548 chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, NULL); 11549 } 11550 11551 if (!chan) { 11552 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11553 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11554 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11555 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11556 if (res < 0) { 11557 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11558 } 11559 ast_hangup(chan); 11560 } 11561 break; 11562 default: 11563 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 11564 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11565 if (res < 0) 11566 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11567 return NULL; 11568 } 11569 break; 11570 case DAHDI_EVENT_NOALARM: 11571 switch (i->sig) { 11572 #if defined(HAVE_PRI) 11573 case SIG_PRI_LIB_HANDLE_CASES: 11574 ast_mutex_lock(&i->lock); 11575 sig_pri_chan_alarm_notify(i->sig_pvt, 1); 11576 ast_mutex_unlock(&i->lock); 11577 break; 11578 #endif /* defined(HAVE_PRI) */ 11579 #if defined(HAVE_SS7) 11580 case SIG_SS7: 11581 sig_ss7_set_alarm(i->sig_pvt, 0); 11582 break; 11583 #endif /* defined(HAVE_SS7) */ 11584 default: 11585 i->inalarm = 0; 11586 break; 11587 } 11588 handle_clear_alarms(i); 11589 break; 11590 case DAHDI_EVENT_ALARM: 11591 switch (i->sig) { 11592 #if defined(HAVE_PRI) 11593 case SIG_PRI_LIB_HANDLE_CASES: 11594 ast_mutex_lock(&i->lock); 11595 sig_pri_chan_alarm_notify(i->sig_pvt, 0); 11596 ast_mutex_unlock(&i->lock); 11597 break; 11598 #endif /* defined(HAVE_PRI) */ 11599 #if defined(HAVE_SS7) 11600 case SIG_SS7: 11601 sig_ss7_set_alarm(i->sig_pvt, 1); 11602 break; 11603 #endif /* defined(HAVE_SS7) */ 11604 default: 11605 i->inalarm = 1; 11606 break; 11607 } 11608 res = get_alarms(i); 11609 handle_alarms(i, res); 11610 /* fall thru intentionally */ 11611 case DAHDI_EVENT_ONHOOK: 11612 if (i->radio) 11613 break; 11614 /* Back on hook. Hang up. */ 11615 switch (i->sig) { 11616 case SIG_FXOLS: 11617 case SIG_FXOGS: 11618 case SIG_FEATD: 11619 case SIG_FEATDMF: 11620 case SIG_FEATDMF_TA: 11621 case SIG_E911: 11622 case SIG_FGC_CAMA: 11623 case SIG_FGC_CAMAMF: 11624 case SIG_FEATB: 11625 case SIG_EM: 11626 case SIG_EM_E1: 11627 case SIG_EMWINK: 11628 case SIG_SF_FEATD: 11629 case SIG_SF_FEATDMF: 11630 case SIG_SF_FEATB: 11631 case SIG_SF: 11632 case SIG_SFWINK: 11633 case SIG_FXSLS: 11634 case SIG_FXSGS: 11635 case SIG_FXSKS: 11636 case SIG_FXOKS: 11637 dahdi_disable_ec(i); 11638 /* Diddle the battery for the zhone */ 11639 #ifdef ZHONE_HACK 11640 dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 11641 usleep(1); 11642 #endif 11643 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11644 dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 11645 break; 11646 case SIG_SS7: 11647 case SIG_PRI_LIB_HANDLE_CASES: 11648 dahdi_disable_ec(i); 11649 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11650 break; 11651 default: 11652 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 11653 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11654 return NULL; 11655 } 11656 break; 11657 case DAHDI_EVENT_POLARITY: 11658 switch (i->sig) { 11659 case SIG_FXSLS: 11660 case SIG_FXSKS: 11661 case SIG_FXSGS: 11662 /* We have already got a PR before the channel was 11663 created, but it wasn't handled. We need polarity 11664 to be REV for remote hangup detection to work. 11665 At least in Spain */ 11666 if (i->hanguponpolarityswitch) 11667 i->polarity = POLARITY_REV; 11668 if (i->cid_start == CID_START_POLARITY || i->cid_start == CID_START_POLARITY_IN) { 11669 i->polarity = POLARITY_REV; 11670 ast_verb(2, "Starting post polarity " 11671 "CID detection on channel %d\n", 11672 i->channel); 11673 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11674 if (!chan) { 11675 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11676 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11677 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11678 ast_hangup(chan); 11679 } 11680 } 11681 break; 11682 default: 11683 ast_log(LOG_WARNING, "handle_init_event detected " 11684 "polarity reversal on non-FXO (SIG_FXS) " 11685 "interface %d\n", i->channel); 11686 } 11687 break; 11688 case DAHDI_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */ 11689 ast_log(LOG_NOTICE, 11690 "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n", 11691 i->channel); 11692 return i; 11693 case DAHDI_EVENT_NEONMWI_ACTIVE: 11694 if (i->mwimonitor_neon) { 11695 notify_message(i->mailbox, 1); 11696 ast_log(LOG_NOTICE, "NEON MWI set for channel %d, mailbox %s \n", i->channel, i->mailbox); 11697 } 11698 break; 11699 case DAHDI_EVENT_NEONMWI_INACTIVE: 11700 if (i->mwimonitor_neon) { 11701 notify_message(i->mailbox, 0); 11702 ast_log(LOG_NOTICE, "NEON MWI cleared for channel %d, mailbox %s\n", i->channel, i->mailbox); 11703 } 11704 break; 11705 } 11706 return NULL; 11707 }
| static int has_voicemail | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5276 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, and mailbox.
Referenced by dahdi_handle_event(), do_monitor(), handle_init_event(), mwi_send_init(), and my_has_voicemail().
05277 { 05278 int new_msgs; 05279 struct ast_event *event; 05280 char *mailbox, *context; 05281 05282 mailbox = context = ast_strdupa(p->mailbox); 05283 strsep(&context, "@"); 05284 if (ast_strlen_zero(context)) 05285 context = "default"; 05286 05287 event = ast_event_get_cached(AST_EVENT_MWI, 05288 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 05289 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 05290 AST_EVENT_IE_END); 05291 05292 if (event) { 05293 new_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 05294 ast_event_destroy(event); 05295 } else 05296 new_msgs = ast_app_has_voicemail(p->mailbox, NULL); 05297 05298 return new_msgs; 05299 }
| 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 13220 of file chan_dahdi.c.
References dahdi_pvt::channel, dahdi_pvt::group, and dahdi_pvt::span.
Referenced by dahdi_cc_callback(), and dahdi_request().
13221 { 13222 #if defined(HAVE_PRI) 13223 if (0 < span) { 13224 /* The channel must be on the specified PRI span. */ 13225 if (!p->pri || p->pri->span != span) { 13226 return 0; 13227 } 13228 if (!groupmatch && channelmatch == -1) { 13229 /* Match any group since it only needs to be on the PRI span. */ 13230 *groupmatched = 1; 13231 return 1; 13232 } 13233 } 13234 #endif /* defined(HAVE_PRI) */ 13235 /* check group matching */ 13236 if (groupmatch) { 13237 if ((p->group & groupmatch) != groupmatch) 13238 /* Doesn't match the specified group, try the next one */ 13239 return 0; 13240 *groupmatched = 1; 13241 } 13242 /* Check to see if we have a channel match */ 13243 if (channelmatch != -1) { 13244 if (p->channel != channelmatch) 13245 /* Doesn't match the specified channel, try the next one */ 13246 return 0; 13247 *channelmatched = 1; 13248 } 13249 13250 return 1; 13251 }
| static int isourconf | ( | struct dahdi_pvt * | p, | |
| struct dahdi_subchannel * | c | |||
| ) | [static] |
Definition at line 4746 of file chan_dahdi.c.
References dahdi_pvt::channel, dahdi_pvt::confno, and dahdi_subchannel::curconf.
Referenced by conf_del().
04747 { 04748 /* If they're listening to our channel, they're ours */ 04749 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON)) 04750 return 1; 04751 /* If they're a talker on our (allocated) conference, they're ours */ 04752 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER)) 04753 return 1; 04754 return 0; 04755 }
Definition at line 4776 of file chan_dahdi.c.
References dahdi_subchannel::dfd, dahdi_subchannel::inthreeway, dahdi_pvt::law, MAX_SLAVES, dahdi_pvt::slaves, and dahdi_pvt::subs.
Referenced by my_complete_conference_update(), and update_conf().
04777 { 04778 int x; 04779 int useslavenative; 04780 struct dahdi_pvt *slave = NULL; 04781 /* Start out optimistic */ 04782 useslavenative = 1; 04783 /* Update conference state in a stateless fashion */ 04784 for (x = 0; x < 3; x++) { 04785 /* Any three-way calling makes slave native mode *definitely* out 04786 of the question */ 04787 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) 04788 useslavenative = 0; 04789 } 04790 /* If we don't have any 3-way calls, check to see if we have 04791 precisely one slave */ 04792 if (useslavenative) { 04793 for (x = 0; x < MAX_SLAVES; x++) { 04794 if (p->slaves[x]) { 04795 if (slave) { 04796 /* Whoops already have a slave! No 04797 slave native and stop right away */ 04798 slave = NULL; 04799 useslavenative = 0; 04800 break; 04801 } else { 04802 /* We have one slave so far */ 04803 slave = p->slaves[x]; 04804 } 04805 } 04806 } 04807 } 04808 /* If no slave, slave native definitely out */ 04809 if (!slave) 04810 useslavenative = 0; 04811 else if (slave->law != p->law) { 04812 useslavenative = 0; 04813 slave = NULL; 04814 } 04815 if (out) 04816 *out = slave; 04817 return useslavenative; 04818 }
| static int load_module | ( | void | ) | [static] |
Definition at line 18597 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, HAVE_PRI_CCSS, LOG_ERROR, setup_dahdi(), sig_pri_init_pri(), sig_pri_load(), and sig_ss7_init_linkset().
18598 { 18599 int res; 18600 #if defined(HAVE_PRI) || defined(HAVE_SS7) 18601 int y; 18602 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 18603 18604 #ifdef HAVE_PRI 18605 memset(pris, 0, sizeof(pris)); 18606 for (y = 0; y < NUM_SPANS; y++) { 18607 sig_pri_init_pri(&pris[y].pri); 18608 } 18609 pri_set_error(dahdi_pri_error); 18610 pri_set_message(dahdi_pri_message); 18611 ast_register_application_xml(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec); 18612 #ifdef HAVE_PRI_PROG_W_CAUSE 18613 ast_register_application_xml(dahdi_send_callrerouting_facility_app, dahdi_send_callrerouting_facility_exec); 18614 #endif 18615 #if defined(HAVE_PRI_CCSS) 18616 if (ast_cc_agent_register(&dahdi_pri_cc_agent_callbacks) 18617 || ast_cc_monitor_register(&dahdi_pri_cc_monitor_callbacks)) { 18618 __unload_module(); 18619 return AST_MODULE_LOAD_FAILURE; 18620 } 18621 #endif /* defined(HAVE_PRI_CCSS) */ 18622 if (sig_pri_load( 18623 #if defined(HAVE_PRI_CCSS) 18624 dahdi_pri_cc_type 18625 #else 18626 NULL 18627 #endif /* defined(HAVE_PRI_CCSS) */ 18628 )) { 18629 __unload_module(); 18630 return AST_MODULE_LOAD_FAILURE; 18631 } 18632 #endif 18633 #if defined(HAVE_SS7) 18634 memset(linksets, 0, sizeof(linksets)); 18635 for (y = 0; y < NUM_SPANS; y++) { 18636 sig_ss7_init_linkset(&linksets[y].ss7); 18637 } 18638 ss7_set_error(dahdi_ss7_error); 18639 ss7_set_message(dahdi_ss7_message); 18640 #endif /* defined(HAVE_SS7) */ 18641 res = setup_dahdi(0); 18642 /* Make sure we can register our DAHDI channel type */ 18643 if (res) 18644 return AST_MODULE_LOAD_DECLINE; 18645 if (ast_channel_register(&dahdi_tech)) { 18646 ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n"); 18647 __unload_module(); 18648 return AST_MODULE_LOAD_FAILURE; 18649 } 18650 #ifdef HAVE_PRI 18651 ast_cli_register_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli)); 18652 #endif 18653 #if defined(HAVE_SS7) 18654 ast_cli_register_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli)); 18655 #endif /* defined(HAVE_SS7) */ 18656 #ifdef HAVE_OPENR2 18657 ast_cli_register_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli)); 18658 ast_register_application_xml(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec); 18659 #endif 18660 18661 ast_cli_register_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli)); 18662 /* register all the data providers */ 18663 ast_data_register_multiple(dahdi_data_providers, ARRAY_LEN(dahdi_data_providers)); 18664 memset(round_robin, 0, sizeof(round_robin)); 18665 ast_manager_register_xml("DAHDITransfer", 0, action_transfer); 18666 ast_manager_register_xml("DAHDIHangup", 0, action_transferhangup); 18667 ast_manager_register_xml("DAHDIDialOffhook", 0, action_dahdidialoffhook); 18668 ast_manager_register_xml("DAHDIDNDon", 0, action_dahdidndon); 18669 ast_manager_register_xml("DAHDIDNDoff", 0, action_dahdidndoff); 18670 ast_manager_register_xml("DAHDIShowChannels", 0, action_dahdishowchannels); 18671 ast_manager_register_xml("DAHDIRestart", 0, action_dahdirestart); 18672 18673 ast_cond_init(&ss_thread_complete, NULL); 18674 18675 return res; 18676 }
| static struct dahdi_pvt* mkintf | ( | int | channel, | |
| const struct dahdi_chan_conf * | conf, | |||
| int | reloading | |||
| ) | [static, read] |
< Current channel structure initializing
< TRUE if the channel interface already exists.
Definition at line 12333 of file chan_dahdi.c.
References dahdi_pvt::accountcode, dahdi_pvt::adsi, dahdi_pvt::amaflags, ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, ANALOG_CID_START_RING, analog_config_complete(), analog_lib_handles(), analog_new(), ANALOG_SIG_NONE, analog_pvt::answeronpolarityswitch, dahdi_pvt::answeronpolarityswitch, ARRAY_LEN, ast_calloc, ast_cc_config_params_init, ast_cc_copy_config_params(), ast_copy_string(), ast_db_del(), ast_db_get(), ast_debug, ast_dsp_set_digitmode(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_free, ast_log(), ast_mutex_init, ast_smdi_interface_find(), ast_strdupa, ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), dahdi_pvt::buf_no, dahdi_pvt::buf_policy, dahdi_pvt::bufsize, dahdi_pvt::busy_quietlength, dahdi_pvt::busy_tonelength, dahdi_pvt::busycount, dahdi_pvt::busydetect, dahdi_pvt::callgroup, dahdi_pvt::callprogress, analog_pvt::callreturn, dahdi_pvt::callreturn, dahdi_pvt::callwaiting, analog_pvt::callwaitingcallerid, dahdi_pvt::callwaitingcallerid, analog_pvt::cancallforward, dahdi_pvt::cancallforward, analog_pvt::canpark, dahdi_pvt::canpark, dahdi_pvt::cc_params, dahdi_chan_conf::chan, CHAN_PSEUDO, analog_pvt::channel, sig_pri_chan::channel, sig_ss7_chan::channel, dahdi_pvt::channel, sig_ss7_chan::cic, analog_pvt::cid_name, dahdi_pvt::cid_name, analog_pvt::cid_num, dahdi_pvt::cid_num, dahdi_pvt::cid_rxgain, CID_SIG_SMDI, analog_pvt::cid_signalling, dahdi_pvt::cid_signalling, analog_pvt::cid_start, dahdi_pvt::cid_start, CID_START_DTMF_NOALERT, CID_START_POLARITY, CID_START_POLARITY_IN, dahdi_pvt::cid_subaddr, dahdi_pvt::cid_tag, dahdi_pvt::cid_ton, dahdi_pvt::confno, sig_ss7_chan::context, sig_pri_chan::context, context, dahdi_pvt::context, dahdi_iflist_insert(), dahdi_open(), dahdi_set_hook(), dahdi_sig2str(), dahdi_sig_pri_lib_handles(), dahdisig_to_analogsig(), analog_pvt::dahditrcallerid, dahdi_pvt::dahditrcallerid, dahdi_pvt::defcontext, dahdi_pvt::destroy, destroy_dahdi_pvt(), dahdi_subchannel::dfd, sig_pri_span::dialplan, sig_ss7_chan::dpc, dahdi_pvt::drings, dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, dahdi_pvt::dtmfrelax, dahdi_pvt::echocanbridged, dahdi_pvt::echocancel, analog_pvt::echotraining, dahdi_pvt::echotraining, errno, dahdi_pvt::faxbuf_no, dahdi_pvt::faxbuf_policy, ast_variable::file, dahdi_pvt::firstradio, analog_pvt::fxsoffhookstate, get_alarms(), dahdi_pvt::group, handle_alarms(), analog_pvt::hanguponpolarityswitch, dahdi_pvt::hanguponpolarityswitch, dahdi_pvt::head, sig_ss7_chan::hidecallerid, sig_pri_chan::hidecallerid, dahdi_pvt::hidecallerid, sig_pri_chan::hidecalleridname, dahdi_pvt::hidecalleridname, sig_pri_span::idledial, sig_pri_span::idleext, analog_pvt::immediate, sig_ss7_chan::immediate, sig_pri_chan::immediate, dahdi_pvt::immediate, sig_ss7_chan::inalarm, sig_pri_chan::inalarm, dahdi_pvt::inalarm, analog_pvt::inalarm, dahdi_pvt::inservice, dahdi_chan_conf::is_sig_auto, dahdi_pvt::language, dahdi_pvt::law, dahdi_pvt::law_default, sig_ss7_chan::locallyblocked, dahdi_pvt::locallyblocked, dahdi_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mailbox, dahdi_pvt::mailbox, sig_pri_span::minidle, sig_pri_span::minunused, sig_ss7_chan::mohinterpret, sig_pri_chan::mohinterpret, dahdi_pvt::mohinterpret, analog_pvt::mohsuggest, dahdi_pvt::mohsuggest, analog_pvt::msgstate, mwi_event_cb(), dahdi_pvt::mwi_event_sub, dahdi_pvt::mwimonitor_fsk, dahdi_pvt::mwimonitor_neon, dahdi_pvt::mwimonitor_rpas, ast_variable::name, ast_variable::next, dahdi_pvt::next, sig_pri_span::nodetype, sig_pri_span::numchans, analog_pvt::onhooktime, dahdi_pvt::oprmode, analog_pvt::outsigmod, dahdi_pvt::outsigmod, dahdi_pvt::parkinglot, analog_pvt::permcallwaiting, dahdi_pvt::permcallwaiting, analog_pvt::permhidecallerid, dahdi_pvt::permhidecallerid, dahdi_pvt::pickupgroup, analog_pvt::polarityonanswerdelay, dahdi_pvt::polarityonanswerdelay, sig_pri_chan::priexclusive, dahdi_pvt::priexclusive, sig_pri_chan::priindication_oob, dahdi_pvt::priindication_oob, dahdi_pvt::propconfno, analog_pvt::pulse, dahdi_pvt::pulse, sig_pri_span::pvts, dahdi_pvt::radio, distRingData::range, sig_ss7_chan::remotelyblocked, dahdi_pvt::remotelyblocked, dahdi_pvt::restrictcid, dahdi_distRings::ringnum, dahdi_pvt::ringt, analog_pvt::ringt, analog_pvt::ringt_base, dahdi_pvt::ringt_base, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, dahdi_pvt::sendcalleridafter, set_actual_gain(), dahdi_pvt::sig, sig2str, 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_FXSKS, SIG_FXSLS, SIG_MFCR2, SIG_PRI, sig_pri_chan_new(), SIG_PRI_LIB_HANDLE_CASES, sig_pri_set_alarm(), dahdi_pvt::sig_pvt, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, SIG_SS7, sig_ss7_chan_new(), sig_ss7_set_alarm(), sigtype_to_signalling(), analog_pvt::smdi_iface, dahdi_pvt::smdi_iface, dahdi_chan_conf::smdi_port, dahdi_pvt::span, analog_pvt::stripmsd, sig_ss7_chan::stripmsd, sig_pri_chan::stripmsd, dahdi_pvt::stripmsd, SUB_REAL, dahdi_pvt::subs, sig_pri_span::switchtype, analog_pvt::threewaycalling, dahdi_pvt::threewaycalling, dahdi_chan_conf::timing, dahdi_pvt::tonezone, analog_pvt::transfer, dahdi_pvt::transfer, analog_pvt::transfertobusy, dahdi_pvt::transfertobusy, sig_pri_span::trunkgroup, dahdi_pvt::txdrc, dahdi_pvt::txgain, update_conf(), analog_pvt::use_callerid, sig_ss7_chan::use_callerid, sig_pri_chan::use_callerid, dahdi_pvt::use_callerid, sig_ss7_chan::use_callingpres, sig_pri_chan::use_callingpres, dahdi_pvt::use_callingpres, analog_pvt::use_smdi, dahdi_pvt::use_smdi, dahdi_pvt::usedistinctiveringdetection, dahdi_pvt::usefaxbuffers, ast_variable::value, dahdi_pvt::vars, and dahdi_pvt::waitfordialtone.
Referenced by build_channels(), and process_dahdi().
12334 { 12335 /* Make a dahdi_pvt structure for this interface */ 12336 struct dahdi_pvt *tmp;/*!< Current channel structure initializing */ 12337 char fn[80]; 12338 struct dahdi_bufferinfo bi; 12339 12340 int res; 12341 #if defined(HAVE_PRI) 12342 int span = 0; 12343 #endif /* defined(HAVE_PRI) */ 12344 int here = 0;/*!< TRUE if the channel interface already exists. */ 12345 int x; 12346 struct analog_pvt *analog_p = NULL; 12347 struct dahdi_params p; 12348 #if defined(HAVE_PRI) 12349 struct dahdi_spaninfo si; 12350 struct sig_pri_chan *pri_chan = NULL; 12351 #endif /* defined(HAVE_PRI) */ 12352 #if defined(HAVE_SS7) 12353 struct sig_ss7_chan *ss7_chan = NULL; 12354 #endif /* defined(HAVE_SS7) */ 12355 12356 /* Search channel interface list to see if it already exists. */ 12357 for (tmp = iflist; tmp; tmp = tmp->next) { 12358 if (!tmp->destroy) { 12359 if (tmp->channel == channel) { 12360 /* The channel interface already exists. */ 12361 here = 1; 12362 break; 12363 } 12364 if (tmp->channel > channel) { 12365 /* No way it can be in the sorted list. */ 12366 tmp = NULL; 12367 break; 12368 } 12369 } 12370 } 12371 12372 if (!here && reloading != 1) { 12373 tmp = ast_calloc(1, sizeof(*tmp)); 12374 if (!tmp) { 12375 return NULL; 12376 } 12377 tmp->cc_params = ast_cc_config_params_init(); 12378 if (!tmp->cc_params) { 12379 ast_free(tmp); 12380 return NULL; 12381 } 12382 ast_mutex_init(&tmp->lock); 12383 ifcount++; 12384 for (x = 0; x < 3; x++) 12385 tmp->subs[x].dfd = -1; 12386 tmp->channel = channel; 12387 tmp->priindication_oob = conf->chan.priindication_oob; 12388 } 12389 12390 if (tmp) { 12391 int chan_sig = conf->chan.sig; 12392 12393 /* If there are variables in tmp before it is updated to match the new config, clear them */ 12394 if (reloading && tmp->vars) { 12395 ast_variables_destroy(tmp->vars); 12396 tmp->vars = NULL; 12397 } 12398 12399 12400 if (!here) { 12401 /* Can only get here if this is a new channel interface being created. */ 12402 if ((channel != CHAN_PSEUDO)) { 12403 int count = 0; 12404 12405 snprintf(fn, sizeof(fn), "%d", channel); 12406 /* Open non-blocking */ 12407 tmp->subs[SUB_REAL].dfd = dahdi_open(fn); 12408 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 */ 12409 usleep(1); 12410 tmp->subs[SUB_REAL].dfd = dahdi_open(fn); 12411 count++; 12412 } 12413 /* Allocate a DAHDI structure */ 12414 if (tmp->subs[SUB_REAL].dfd < 0) { 12415 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); 12416 destroy_dahdi_pvt(tmp); 12417 return NULL; 12418 } 12419 memset(&p, 0, sizeof(p)); 12420 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 12421 if (res < 0) { 12422 ast_log(LOG_ERROR, "Unable to get parameters: %s\n", strerror(errno)); 12423 destroy_dahdi_pvt(tmp); 12424 return NULL; 12425 } 12426 if (conf->is_sig_auto) 12427 chan_sig = sigtype_to_signalling(p.sigtype); 12428 if (p.sigtype != (chan_sig & 0x3ffff)) { 12429 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)); 12430 destroy_dahdi_pvt(tmp); 12431 return NULL; 12432 } 12433 tmp->law_default = p.curlaw; 12434 tmp->law = p.curlaw; 12435 tmp->span = p.spanno; 12436 #if defined(HAVE_PRI) 12437 span = p.spanno - 1; 12438 #endif /* defined(HAVE_PRI) */ 12439 } else { 12440 chan_sig = 0; 12441 } 12442 tmp->sig = chan_sig; 12443 tmp->outsigmod = conf->chan.outsigmod; 12444 12445 if (analog_lib_handles(chan_sig, tmp->radio, tmp->oprmode)) { 12446 analog_p = analog_new(dahdisig_to_analogsig(chan_sig), &dahdi_analog_callbacks, tmp); 12447 if (!analog_p) { 12448 destroy_dahdi_pvt(tmp); 12449 return NULL; 12450 } 12451 tmp->sig_pvt = analog_p; 12452 } 12453 #if defined(HAVE_SS7) 12454 if (chan_sig == SIG_SS7) { 12455 struct dahdi_ss7 *ss7; 12456 int clear = 0; 12457 12458 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &clear)) { 12459 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 12460 destroy_dahdi_pvt(tmp); 12461 return NULL; 12462 } 12463 12464 ss7 = ss7_resolve_linkset(cur_linkset); 12465 if (!ss7) { 12466 ast_log(LOG_ERROR, "Unable to find linkset %d\n", cur_linkset); 12467 destroy_dahdi_pvt(tmp); 12468 return NULL; 12469 } 12470 ss7->ss7.span = cur_linkset; 12471 if (cur_cicbeginswith < 0) { 12472 ast_log(LOG_ERROR, "Need to set cicbeginswith for the channels!\n"); 12473 destroy_dahdi_pvt(tmp); 12474 return NULL; 12475 } 12476 ss7_chan = sig_ss7_chan_new(tmp, &dahdi_ss7_callbacks, &ss7->ss7); 12477 if (!ss7_chan) { 12478 destroy_dahdi_pvt(tmp); 12479 return NULL; 12480 } 12481 tmp->sig_pvt = ss7_chan; 12482 tmp->ss7 = &ss7->ss7; 12483 12484 ss7_chan->channel = tmp->channel; 12485 ss7_chan->cic = cur_cicbeginswith++; 12486 12487 /* DB: Add CIC's DPC information */ 12488 ss7_chan->dpc = cur_defaultdpc; 12489 12490 ss7->ss7.pvts[ss7->ss7.numchans++] = ss7_chan; 12491 12492 ast_copy_string(ss7->ss7.internationalprefix, conf->ss7.ss7.internationalprefix, sizeof(ss7->ss7.internationalprefix)); 12493 ast_copy_string(ss7->ss7.nationalprefix, conf->ss7.ss7.nationalprefix, sizeof(ss7->ss7.nationalprefix)); 12494 ast_copy_string(ss7->ss7.subscriberprefix, conf->ss7.ss7.subscriberprefix, sizeof(ss7->ss7.subscriberprefix)); 12495 ast_copy_string(ss7->ss7.unknownprefix, conf->ss7.ss7.unknownprefix, sizeof(ss7->ss7.unknownprefix)); 12496 12497 ss7->ss7.called_nai = conf->ss7.ss7.called_nai; 12498 ss7->ss7.calling_nai = conf->ss7.ss7.calling_nai; 12499 } 12500 #endif /* defined(HAVE_SS7) */ 12501 #ifdef HAVE_OPENR2 12502 if (chan_sig == SIG_MFCR2) { 12503 struct dahdi_mfcr2 *r2_link; 12504 r2_link = dahdi_r2_get_link(conf); 12505 if (!r2_link) { 12506 ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n"); 12507 destroy_dahdi_pvt(tmp); 12508 return NULL; 12509 } 12510 if (!r2_link->protocol_context && dahdi_r2_set_context(r2_link, conf)) { 12511 ast_log(LOG_ERROR, "Cannot create OpenR2 protocol context.\n"); 12512 destroy_dahdi_pvt(tmp); 12513 return NULL; 12514 } 12515 if (r2_link->numchans == ARRAY_LEN(r2_link->pvts)) { 12516 ast_log(LOG_ERROR, "Cannot add more channels to this link!\n"); 12517 destroy_dahdi_pvt(tmp); 12518 return NULL; 12519 } 12520 r2_link->pvts[r2_link->numchans++] = tmp; 12521 tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context, 12522 tmp->subs[SUB_REAL].dfd, 12523 NULL, NULL); 12524 if (!tmp->r2chan) { 12525 openr2_liberr_t err = openr2_context_get_last_error(r2_link->protocol_context); 12526 ast_log(LOG_ERROR, "Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err)); 12527 destroy_dahdi_pvt(tmp); 12528 return NULL; 12529 } 12530 tmp->mfcr2 = r2_link; 12531 if (conf->mfcr2.call_files) { 12532 openr2_chan_enable_call_files(tmp->r2chan); 12533 } 12534 openr2_chan_set_client_data(tmp->r2chan, tmp); 12535 /* cast seems to be needed to get rid of the annoying warning regarding format attribute */ 12536 openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log); 12537 openr2_chan_set_log_level(tmp->r2chan, conf->mfcr2.loglevel); 12538 tmp->mfcr2_category = conf->mfcr2.category; 12539 tmp->mfcr2_charge_calls = conf->mfcr2.charge_calls; 12540 tmp->mfcr2_allow_collect_calls = conf->mfcr2.allow_collect_calls; 12541 tmp->mfcr2_forced_release = conf->mfcr2.forced_release; 12542 tmp->mfcr2_accept_on_offer = conf->mfcr2.accept_on_offer; 12543 tmp->mfcr2call = 0; 12544 tmp->mfcr2_dnis_index = 0; 12545 tmp->mfcr2_ani_index = 0; 12546 } 12547 #endif 12548 #ifdef HAVE_PRI 12549 if (dahdi_sig_pri_lib_handles(chan_sig)) { 12550 int offset; 12551 int matchesdchan; 12552 int x,y; 12553 int myswitchtype = 0; 12554 12555 offset = 0; 12556 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &offset)) { 12557 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 12558 destroy_dahdi_pvt(tmp); 12559 return NULL; 12560 } 12561 if (span >= NUM_SPANS) { 12562 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 12563 destroy_dahdi_pvt(tmp); 12564 return NULL; 12565 } else { 12566 si.spanno = 0; 12567 if (ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SPANSTAT,&si) == -1) { 12568 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 12569 destroy_dahdi_pvt(tmp); 12570 return NULL; 12571 } 12572 /* Store the logical span first based upon the real span */ 12573 tmp->logicalspan = pris[span].prilogicalspan; 12574 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 12575 if (span < 0) { 12576 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 12577 destroy_dahdi_pvt(tmp); 12578 return NULL; 12579 } 12580 myswitchtype = conf->pri.pri.switchtype; 12581 /* Make sure this isn't a d-channel */ 12582 matchesdchan=0; 12583 for (x = 0; x < NUM_SPANS; x++) { 12584 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 12585 if (pris[x].dchannels[y] == tmp->channel) { 12586 matchesdchan = 1; 12587 break; 12588 } 12589 } 12590 } 12591 if (!matchesdchan) { 12592 if (pris[span].pri.nodetype && (pris[span].pri.nodetype != conf->pri.pri.nodetype)) { 12593 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].pri.nodetype)); 12594 destroy_dahdi_pvt(tmp); 12595 return NULL; 12596 } 12597 if (pris[span].pri.switchtype && (pris[span].pri.switchtype != myswitchtype)) { 12598 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].pri.switchtype)); 12599 destroy_dahdi_pvt(tmp); 12600 return NULL; 12601 } 12602 if ((pris[span].pri.dialplan) && (pris[span].pri.dialplan != conf->pri.pri.dialplan)) { 12603 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)); 12604 destroy_dahdi_pvt(tmp); 12605 return NULL; 12606 } 12607 if (!ast_strlen_zero(pris[span].pri.idledial) && strcmp(pris[span].pri.idledial, conf->pri.pri.idledial)) { 12608 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.pri.idledial); 12609 destroy_dahdi_pvt(tmp); 12610 return NULL; 12611 } 12612 if (!ast_strlen_zero(pris[span].pri.idleext) && strcmp(pris[span].pri.idleext, conf->pri.pri.idleext)) { 12613 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.pri.idleext); 12614 destroy_dahdi_pvt(tmp); 12615 return NULL; 12616 } 12617 if (pris[span].pri.minunused && (pris[span].pri.minunused != conf->pri.pri.minunused)) { 12618 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.pri.minunused); 12619 destroy_dahdi_pvt(tmp); 12620 return NULL; 12621 } 12622 if (pris[span].pri.minidle && (pris[span].pri.minidle != conf->pri.pri.minidle)) { 12623 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.pri.minidle); 12624 destroy_dahdi_pvt(tmp); 12625 return NULL; 12626 } 12627 if (pris[span].pri.numchans >= ARRAY_LEN(pris[span].pri.pvts)) { 12628 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 12629 pris[span].pri.trunkgroup); 12630 destroy_dahdi_pvt(tmp); 12631 return NULL; 12632 } 12633 12634 ast_debug(4, "Adding callbacks %p to chan %d\n", &dahdi_pri_callbacks, tmp->channel); 12635 pri_chan = sig_pri_chan_new(tmp, &dahdi_pri_callbacks, &pris[span].pri, tmp->logicalspan, p.chanpos, pris[span].mastertrunkgroup); 12636 if (!pri_chan) { 12637 destroy_dahdi_pvt(tmp); 12638 return NULL; 12639 } 12640 tmp->sig_pvt = pri_chan; 12641 tmp->pri = &pris[span].pri; 12642 12643 tmp->priexclusive = conf->chan.priexclusive; 12644 12645 if (!tmp->pri->cc_params) { 12646 tmp->pri->cc_params = ast_cc_config_params_init(); 12647 if (!tmp->pri->cc_params) { 12648 destroy_dahdi_pvt(tmp); 12649 return NULL; 12650 } 12651 } 12652 ast_cc_copy_config_params(tmp->pri->cc_params, 12653 conf->chan.cc_params); 12654 12655 pris[span].pri.sig = chan_sig; 12656 pris[span].pri.nodetype = conf->pri.pri.nodetype; 12657 pris[span].pri.switchtype = myswitchtype; 12658 pris[span].pri.nsf = conf->pri.pri.nsf; 12659 pris[span].pri.dialplan = conf->pri.pri.dialplan; 12660 pris[span].pri.localdialplan = conf->pri.pri.localdialplan; 12661 pris[span].pri.pvts[pris[span].pri.numchans++] = tmp->sig_pvt; 12662 pris[span].pri.minunused = conf->pri.pri.minunused; 12663 pris[span].pri.minidle = conf->pri.pri.minidle; 12664 pris[span].pri.overlapdial = conf->pri.pri.overlapdial; 12665 pris[span].pri.qsigchannelmapping = conf->pri.pri.qsigchannelmapping; 12666 pris[span].pri.discardremoteholdretrieval = conf->pri.pri.discardremoteholdretrieval; 12667 #if defined(HAVE_PRI_SERVICE_MESSAGES) 12668 pris[span].pri.enable_service_message_support = conf->pri.pri.enable_service_message_support; 12669 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 12670 #ifdef HAVE_PRI_INBANDDISCONNECT 12671 pris[span].pri.inbanddisconnect = conf->pri.pri.inbanddisconnect; 12672 #endif 12673 #if defined(HAVE_PRI_CALL_HOLD) 12674 pris[span].pri.hold_disconnect_transfer = 12675 conf->pri.pri.hold_disconnect_transfer; 12676 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 12677 #if defined(HAVE_PRI_CCSS) 12678 pris[span].pri.cc_ptmp_recall_mode = 12679 conf->pri.pri.cc_ptmp_recall_mode; 12680 pris[span].pri.cc_qsig_signaling_link_req = 12681 conf->pri.pri.cc_qsig_signaling_link_req; 12682 pris[span].pri.cc_qsig_signaling_link_rsp = 12683 conf->pri.pri.cc_qsig_signaling_link_rsp; 12684 #endif /* defined(HAVE_PRI_CCSS) */ 12685 #if defined(HAVE_PRI_CALL_WAITING) 12686 pris[span].pri.max_call_waiting_calls = 12687 conf->pri.pri.max_call_waiting_calls; 12688 pris[span].pri.allow_call_waiting_calls = 12689 conf->pri.pri.allow_call_waiting_calls; 12690 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 12691 pris[span].pri.transfer = conf->chan.transfer; 12692 pris[span].pri.facilityenable = conf->pri.pri.facilityenable; 12693 #if defined(HAVE_PRI_L2_PERSISTENCE) 12694 pris[span].pri.l2_persistence = conf->pri.pri.l2_persistence; 12695 #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */ 12696 #if defined(HAVE_PRI_AOC_EVENTS) 12697 pris[span].pri.aoc_passthrough_flag = conf->pri.pri.aoc_passthrough_flag; 12698 pris[span].pri.aoce_delayhangup = conf->pri.pri.aoce_delayhangup; 12699 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 12700 if (chan_sig == SIG_BRI_PTMP) { 12701 pris[span].pri.layer1_ignored = conf->pri.pri.layer1_ignored; 12702 } else { 12703 /* Option does not apply to this line type. */ 12704 pris[span].pri.layer1_ignored = 0; 12705 } 12706 pris[span].pri.append_msn_to_user_tag = conf->pri.pri.append_msn_to_user_tag; 12707 pris[span].pri.inband_on_proceeding = conf->pri.pri.inband_on_proceeding; 12708 ast_copy_string(pris[span].pri.initial_user_tag, conf->chan.cid_tag, sizeof(pris[span].pri.initial_user_tag)); 12709 ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list)); 12710 #if defined(HAVE_PRI_MWI) 12711 ast_copy_string(pris[span].pri.mwi_mailboxes, 12712 conf->pri.pri.mwi_mailboxes, 12713 sizeof(pris[span].pri.mwi_mailboxes)); 12714 #endif /* defined(HAVE_PRI_MWI) */ 12715 ast_copy_string(pris[span].pri.idledial, conf->pri.pri.idledial, sizeof(pris[span].pri.idledial)); 12716 ast_copy_string(pris[span].pri.idleext, conf->pri.pri.idleext, sizeof(pris[span].pri.idleext)); 12717 ast_copy_string(pris[span].pri.internationalprefix, conf->pri.pri.internationalprefix, sizeof(pris[span].pri.internationalprefix)); 12718 ast_copy_string(pris[span].pri.nationalprefix, conf->pri.pri.nationalprefix, sizeof(pris[span].pri.nationalprefix)); 12719 ast_copy_string(pris[span].pri.localprefix, conf->pri.pri.localprefix, sizeof(pris[span].pri.localprefix)); 12720 ast_copy_string(pris[span].pri.privateprefix, conf->pri.pri.privateprefix, sizeof(pris[span].pri.privateprefix)); 12721 ast_copy_string(pris[span].pri.unknownprefix, conf->pri.pri.unknownprefix, sizeof(pris[span].pri.unknownprefix)); 12722 pris[span].pri.resetinterval = conf->pri.pri.resetinterval; 12723 12724 for (x = 0; x < PRI_MAX_TIMERS; x++) { 12725 pris[span].pri.pritimers[x] = conf->pri.pri.pritimers[x]; 12726 } 12727 12728 #if defined(HAVE_PRI_CALL_WAITING) 12729 /* Channel initial config parameters. */ 12730 pris[span].pri.ch_cfg.stripmsd = conf->chan.stripmsd; 12731 pris[span].pri.ch_cfg.hidecallerid = conf->chan.hidecallerid; 12732 pris[span].pri.ch_cfg.hidecalleridname = conf->chan.hidecalleridname; 12733 pris[span].pri.ch_cfg.immediate = conf->chan.immediate; 12734 pris[span].pri.ch_cfg.priexclusive = conf->chan.priexclusive; 12735 pris[span].pri.ch_cfg.priindication_oob = conf->chan.priindication_oob; 12736 pris[span].pri.ch_cfg.use_callerid = conf->chan.use_callerid; 12737 pris[span].pri.ch_cfg.use_callingpres = conf->chan.use_callingpres; 12738 ast_copy_string(pris[span].pri.ch_cfg.context, conf->chan.context, sizeof(pris[span].pri.ch_cfg.context)); 12739 ast_copy_string(pris[span].pri.ch_cfg.mohinterpret, conf->chan.mohinterpret, sizeof(pris[span].pri.ch_cfg.mohinterpret)); 12740 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 12741 } else { 12742 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", p.chanpos); 12743 destroy_dahdi_pvt(tmp); 12744 return NULL; 12745 } 12746 } 12747 } 12748 #endif 12749 } else { 12750 /* already exists in interface list */ 12751 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)); 12752 chan_sig = tmp->sig; 12753 if (tmp->subs[SUB_REAL].dfd > -1) { 12754 memset(&p, 0, sizeof(p)); 12755 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 12756 } 12757 } 12758 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 12759 switch (chan_sig) { 12760 case SIG_FXSKS: 12761 case SIG_FXSLS: 12762 case SIG_EM: 12763 case SIG_EM_E1: 12764 case SIG_EMWINK: 12765 case SIG_FEATD: 12766 case SIG_FEATDMF: 12767 case SIG_FEATDMF_TA: 12768 case SIG_FEATB: 12769 case SIG_E911: 12770 case SIG_SF: 12771 case SIG_SFWINK: 12772 case SIG_FGC_CAMA: 12773 case SIG_FGC_CAMAMF: 12774 case SIG_SF_FEATD: 12775 case SIG_SF_FEATDMF: 12776 case SIG_SF_FEATB: 12777 p.starttime = 250; 12778 break; 12779 } 12780 12781 if (tmp->radio) { 12782 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 12783 p.channo = channel; 12784 p.rxwinktime = 1; 12785 p.rxflashtime = 1; 12786 p.starttime = 1; 12787 p.debouncetime = 5; 12788 } else { 12789 p.channo = channel; 12790 /* Override timing settings based on config file */ 12791 if (conf->timing.prewinktime >= 0) 12792 p.prewinktime = conf->timing.prewinktime; 12793 if (conf->timing.preflashtime >= 0) 12794 p.preflashtime = conf->timing.preflashtime; 12795 if (conf->timing.winktime >= 0) 12796 p.winktime = conf->timing.winktime; 12797 if (conf->timing.flashtime >= 0) 12798 p.flashtime = conf->timing.flashtime; 12799 if (conf->timing.starttime >= 0) 12800 p.starttime = conf->timing.starttime; 12801 if (conf->timing.rxwinktime >= 0) 12802 p.rxwinktime = conf->timing.rxwinktime; 12803 if (conf->timing.rxflashtime >= 0) 12804 p.rxflashtime = conf->timing.rxflashtime; 12805 if (conf->timing.debouncetime >= 0) 12806 p.debouncetime = conf->timing.debouncetime; 12807 } 12808 12809 /* don't set parms on a pseudo-channel */ 12810 if (tmp->subs[SUB_REAL].dfd >= 0) 12811 { 12812 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_PARAMS, &p); 12813 if (res < 0) { 12814 ast_log(LOG_ERROR, "Unable to set parameters: %s\n", strerror(errno)); 12815 destroy_dahdi_pvt(tmp); 12816 return NULL; 12817 } 12818 } 12819 #if 1 12820 if (!here && (tmp->subs[SUB_REAL].dfd > -1)) { 12821 memset(&bi, 0, sizeof(bi)); 12822 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi); 12823 if (!res) { 12824 bi.txbufpolicy = conf->chan.buf_policy; 12825 bi.rxbufpolicy = conf->chan.buf_policy; 12826 bi.numbufs = conf->chan.buf_no; 12827 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi); 12828 if (res < 0) { 12829 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", channel, strerror(errno)); 12830 } 12831 } else { 12832 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", channel, strerror(errno)); 12833 } 12834 tmp->buf_policy = conf->chan.buf_policy; 12835 tmp->buf_no = conf->chan.buf_no; 12836 tmp->usefaxbuffers = conf->chan.usefaxbuffers; 12837 tmp->faxbuf_policy = conf->chan.faxbuf_policy; 12838 tmp->faxbuf_no = conf->chan.faxbuf_no; 12839 /* This is not as gnarly as it may first appear. If the ioctl above failed, we'd be setting 12840 * tmp->bufsize to zero which would cause subsequent faxbuffer-related ioctl calls to fail. 12841 * The reason the ioctl call above failed should to be determined before worrying about the 12842 * faxbuffer-related ioctl calls */ 12843 tmp->bufsize = bi.bufsize; 12844 } 12845 #endif 12846 tmp->immediate = conf->chan.immediate; 12847 tmp->transfertobusy = conf->chan.transfertobusy; 12848 if (chan_sig & __DAHDI_SIG_FXS) { 12849 tmp->mwimonitor_fsk = conf->chan.mwimonitor_fsk; 12850 tmp->mwimonitor_neon = conf->chan.mwimonitor_neon; 12851 tmp->mwimonitor_rpas = conf->chan.mwimonitor_rpas; 12852 } 12853 tmp->ringt_base = ringt_base; 12854 tmp->firstradio = 0; 12855 if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS)) 12856 tmp->permcallwaiting = conf->chan.callwaiting; 12857 else 12858 tmp->permcallwaiting = 0; 12859 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 12860 tmp->destroy = 0; 12861 tmp->drings = conf->chan.drings; 12862 12863 /* 10 is a nice default. */ 12864 if (tmp->drings.ringnum[0].range == 0) 12865 tmp->drings.ringnum[0].range = 10; 12866 if (tmp->drings.ringnum[1].range == 0) 12867 tmp->drings.ringnum[1].range = 10; 12868 if (tmp->drings.ringnum[2].range == 0) 12869 tmp->drings.ringnum[2].range = 10; 12870 12871 tmp->usedistinctiveringdetection = usedistinctiveringdetection; 12872 tmp->callwaitingcallerid = conf->chan.callwaitingcallerid; 12873 tmp->threewaycalling = conf->chan.threewaycalling; 12874 tmp->adsi = conf->chan.adsi; 12875 tmp->use_smdi = conf->chan.use_smdi; 12876 tmp->permhidecallerid = conf->chan.hidecallerid; 12877 tmp->hidecalleridname = conf->chan.hidecalleridname; 12878 tmp->callreturn = conf->chan.callreturn; 12879 tmp->echocancel = conf->chan.echocancel; 12880 tmp->echotraining = conf->chan.echotraining; 12881 tmp->pulse = conf->chan.pulse; 12882 if (tmp->echocancel.head.tap_length) { 12883 tmp->echocanbridged = conf->chan.echocanbridged; 12884 } else { 12885 if (conf->chan.echocanbridged) 12886 ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n"); 12887 tmp->echocanbridged = 0; 12888 } 12889 tmp->busydetect = conf->chan.busydetect; 12890 tmp->busycount = conf->chan.busycount; 12891 tmp->busy_tonelength = conf->chan.busy_tonelength; 12892 tmp->busy_quietlength = conf->chan.busy_quietlength; 12893 tmp->callprogress = conf->chan.callprogress; 12894 tmp->waitfordialtone = conf->chan.waitfordialtone; 12895 tmp->cancallforward = conf->chan.cancallforward; 12896 tmp->dtmfrelax = conf->chan.dtmfrelax; 12897 tmp->callwaiting = tmp->permcallwaiting; 12898 tmp->hidecallerid = tmp->permhidecallerid; 12899 tmp->channel = channel; 12900 tmp->stripmsd = conf->chan.stripmsd; 12901 tmp->use_callerid = conf->chan.use_callerid; 12902 tmp->cid_signalling = conf->chan.cid_signalling; 12903 tmp->cid_start = conf->chan.cid_start; 12904 tmp->dahditrcallerid = conf->chan.dahditrcallerid; 12905 tmp->restrictcid = conf->chan.restrictcid; 12906 tmp->use_callingpres = conf->chan.use_callingpres; 12907 if (tmp->usedistinctiveringdetection) { 12908 if (!tmp->use_callerid) { 12909 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 12910 tmp->use_callerid = 1; 12911 } 12912 } 12913 12914 if (tmp->cid_signalling == CID_SIG_SMDI) { 12915 if (!tmp->use_smdi) { 12916 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n"); 12917 tmp->use_smdi = 1; 12918 } 12919 } 12920 if (tmp->use_smdi) { 12921 tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port); 12922 if (!(tmp->smdi_iface)) { 12923 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n"); 12924 tmp->use_smdi = 0; 12925 } 12926 } 12927 12928 ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode)); 12929 tmp->amaflags = conf->chan.amaflags; 12930 if (!here) { 12931 tmp->confno = -1; 12932 tmp->propconfno = -1; 12933 } 12934 tmp->canpark = conf->chan.canpark; 12935 tmp->transfer = conf->chan.transfer; 12936 ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext)); 12937 ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language)); 12938 ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret)); 12939 ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest)); 12940 ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context)); 12941 ast_copy_string(tmp->parkinglot, conf->chan.parkinglot, sizeof(tmp->parkinglot)); 12942 tmp->cid_ton = 0; 12943 if (analog_lib_handles(tmp->sig, tmp->radio, tmp->oprmode)) { 12944 ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num)); 12945 ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name)); 12946 } else { 12947 tmp->cid_num[0] = '\0'; 12948 tmp->cid_name[0] = '\0'; 12949 } 12950 #if defined(HAVE_PRI) 12951 if (dahdi_sig_pri_lib_handles(tmp->sig)) { 12952 tmp->cid_tag[0] = '\0'; 12953 } else 12954 #endif /* defined(HAVE_PRI) */ 12955 { 12956 ast_copy_string(tmp->cid_tag, conf->chan.cid_tag, sizeof(tmp->cid_tag)); 12957 } 12958 tmp->cid_subaddr[0] = '\0'; 12959 ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox)); 12960 if (channel != CHAN_PSEUDO && !ast_strlen_zero(tmp->mailbox)) { 12961 char *mailbox, *context; 12962 mailbox = context = ast_strdupa(tmp->mailbox); 12963 strsep(&context, "@"); 12964 if (ast_strlen_zero(context)) 12965 context = "default"; 12966 tmp->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "Dahdi MWI subscription", NULL, 12967 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12968 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12969 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS, 12970 AST_EVENT_IE_END); 12971 } 12972 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 12973 tmp->mwisend_setting = conf->chan.mwisend_setting; 12974 tmp->mwisend_fsk = conf->chan.mwisend_fsk; 12975 tmp->mwisend_rpas = conf->chan.mwisend_rpas; 12976 #endif 12977 12978 tmp->group = conf->chan.group; 12979 tmp->callgroup = conf->chan.callgroup; 12980 tmp->pickupgroup= conf->chan.pickupgroup; 12981 if (conf->chan.vars) { 12982 struct ast_variable *v, *tmpvar; 12983 for (v = conf->chan.vars ; v ; v = v->next) { 12984 if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 12985 tmpvar->next = tmp->vars; 12986 tmp->vars = tmpvar; 12987 } 12988 } 12989 } 12990 tmp->cid_rxgain = conf->chan.cid_rxgain; 12991 tmp->rxgain = conf->chan.rxgain; 12992 tmp->txgain = conf->chan.txgain; 12993 tmp->txdrc = conf->chan.txdrc; 12994 tmp->rxdrc = conf->chan.rxdrc; 12995 tmp->tonezone = conf->chan.tonezone; 12996 if (tmp->subs[SUB_REAL].dfd > -1) { 12997 set_actual_gain(tmp->subs[SUB_REAL].dfd, tmp->rxgain, tmp->txgain, tmp->rxdrc, tmp->txdrc, tmp->law); 12998 if (tmp->dsp) 12999 ast_dsp_set_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 13000 update_conf(tmp); 13001 if (!here) { 13002 switch (chan_sig) { 13003 case SIG_PRI_LIB_HANDLE_CASES: 13004 case SIG_SS7: 13005 case SIG_MFCR2: 13006 break; 13007 default: 13008 /* Hang it up to be sure it's good */ 13009 dahdi_set_hook(tmp->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 13010 break; 13011 } 13012 } 13013 ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SETTONEZONE,&tmp->tonezone); 13014 if ((res = get_alarms(tmp)) != DAHDI_ALARM_NONE) { 13015 /* the dchannel is down so put the channel in alarm */ 13016 switch (tmp->sig) { 13017 #ifdef HAVE_PRI 13018 case SIG_PRI_LIB_HANDLE_CASES: 13019 sig_pri_set_alarm(tmp->sig_pvt, 1); 13020 break; 13021 #endif 13022 #if defined(HAVE_SS7) 13023 case SIG_SS7: 13024 sig_ss7_set_alarm(tmp->sig_pvt, 1); 13025 break; 13026 #endif /* defined(HAVE_SS7) */ 13027 default: 13028 /* The only sig submodule left should be sig_analog. */ 13029 analog_p = tmp->sig_pvt; 13030 if (analog_p) { 13031 analog_p->inalarm = 1; 13032 } 13033 tmp->inalarm = 1; 13034 break; 13035 } 13036 handle_alarms(tmp, res); 13037 } 13038 } 13039 13040 tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay; 13041 tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch; 13042 tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch; 13043 tmp->sendcalleridafter = conf->chan.sendcalleridafter; 13044 ast_cc_copy_config_params(tmp->cc_params, conf->chan.cc_params); 13045 13046 if (!here) { 13047 tmp->locallyblocked = 0; 13048 tmp->remotelyblocked = 0; 13049 switch (tmp->sig) { 13050 #if defined(HAVE_PRI) 13051 case SIG_PRI_LIB_HANDLE_CASES: 13052 tmp->inservice = 1;/* Inservice until actually implemented. */ 13053 #if defined(HAVE_PRI_SERVICE_MESSAGES) 13054 ((struct sig_pri_chan *) tmp->sig_pvt)->service_status = 0; 13055 if (chan_sig == SIG_PRI) { 13056 char db_chan_name[20]; 13057 char db_answer[5]; 13058 13059 /* 13060 * Initialize the active out-of-service status 13061 * and delete any record if the feature is not enabled. 13062 */ 13063 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, tmp->span, tmp->channel); 13064 if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) { 13065 unsigned *why; 13066 13067 why = &((struct sig_pri_chan *) tmp->sig_pvt)->service_status; 13068 if (tmp->pri->enable_service_message_support) { 13069 char state; 13070 13071 sscanf(db_answer, "%1c:%30u", &state, why); 13072 13073 /* Ensure that only the implemented bits could be set.*/ 13074 *why &= (SRVST_NEAREND | SRVST_FAREND); 13075 } 13076 if (!*why) { 13077 ast_db_del(db_chan_name, SRVST_DBKEY); 13078 } 13079 } 13080 } 13081 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 13082 break; 13083 #endif /* defined(HAVE_PRI) */ 13084 #if defined(HAVE_SS7) 13085 case SIG_SS7: 13086 tmp->inservice = 0; 13087 break; 13088 #endif /* defined(HAVE_SS7) */ 13089 default: 13090 /* We default to in service on protocols that don't have a reset */ 13091 tmp->inservice = 1; 13092 break; 13093 } 13094 } 13095 13096 switch (tmp->sig) { 13097 #if defined(HAVE_PRI) 13098 case SIG_PRI_LIB_HANDLE_CASES: 13099 if (pri_chan) { 13100 pri_chan->channel = tmp->channel; 13101 pri_chan->hidecallerid = tmp->hidecallerid; 13102 pri_chan->hidecalleridname = tmp->hidecalleridname; 13103 pri_chan->immediate = tmp->immediate; 13104 pri_chan->inalarm = tmp->inalarm; 13105 pri_chan->priexclusive = tmp->priexclusive; 13106 pri_chan->priindication_oob = tmp->priindication_oob; 13107 pri_chan->use_callerid = tmp->use_callerid; 13108 pri_chan->use_callingpres = tmp->use_callingpres; 13109 ast_copy_string(pri_chan->context, tmp->context, 13110 sizeof(pri_chan->context)); 13111 ast_copy_string(pri_chan->mohinterpret, tmp->mohinterpret, 13112 sizeof(pri_chan->mohinterpret)); 13113 pri_chan->stripmsd = tmp->stripmsd; 13114 } 13115 break; 13116 #endif /* defined(HAVE_PRI) */ 13117 #if defined(HAVE_SS7) 13118 case SIG_SS7: 13119 if (ss7_chan) { 13120 ss7_chan->inalarm = tmp->inalarm; 13121 13122 ss7_chan->stripmsd = tmp->stripmsd; 13123 ss7_chan->hidecallerid = tmp->hidecallerid; 13124 ss7_chan->use_callerid = tmp->use_callerid; 13125 ss7_chan->use_callingpres = tmp->use_callingpres; 13126 ss7_chan->immediate = tmp->immediate; 13127 ss7_chan->locallyblocked = tmp->locallyblocked; 13128 ss7_chan->remotelyblocked = tmp->remotelyblocked; 13129 ast_copy_string(ss7_chan->context, tmp->context, 13130 sizeof(ss7_chan->context)); 13131 ast_copy_string(ss7_chan->mohinterpret, tmp->mohinterpret, 13132 sizeof(ss7_chan->mohinterpret)); 13133 } 13134 break; 13135 #endif /* defined(HAVE_SS7) */ 13136 default: 13137 /* The only sig submodule left should be sig_analog. */ 13138 analog_p = tmp->sig_pvt; 13139 if (analog_p) { 13140 analog_p->channel = tmp->channel; 13141 analog_p->polarityonanswerdelay = conf->chan.polarityonanswerdelay; 13142 analog_p->answeronpolarityswitch = conf->chan.answeronpolarityswitch; 13143 analog_p->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch; 13144 analog_p->permcallwaiting = conf->chan.callwaiting; /* permcallwaiting possibly modified in analog_config_complete */ 13145 analog_p->callreturn = conf->chan.callreturn; 13146 analog_p->cancallforward = conf->chan.cancallforward; 13147 analog_p->canpark = conf->chan.canpark; 13148 analog_p->dahditrcallerid = conf->chan.dahditrcallerid; 13149 analog_p->immediate = conf->chan.immediate; 13150 analog_p->permhidecallerid = conf->chan.permhidecallerid; 13151 analog_p->pulse = conf->chan.pulse; 13152 analog_p->threewaycalling = conf->chan.threewaycalling; 13153 analog_p->transfer = conf->chan.transfer; 13154 analog_p->transfertobusy = conf->chan.transfertobusy; 13155 analog_p->use_callerid = tmp->use_callerid; 13156 analog_p->use_smdi = tmp->use_smdi; 13157 analog_p->smdi_iface = tmp->smdi_iface; 13158 analog_p->outsigmod = ANALOG_SIG_NONE; 13159 analog_p->echotraining = conf->chan.echotraining; 13160 analog_p->cid_signalling = conf->chan.cid_signalling; 13161 analog_p->stripmsd = conf->chan.stripmsd; 13162 switch (conf->chan.cid_start) { 13163 case CID_START_POLARITY: 13164 analog_p->cid_start = ANALOG_CID_START_POLARITY; 13165 break; 13166 case CID_START_POLARITY_IN: 13167 analog_p->cid_start = ANALOG_CID_START_POLARITY_IN; 13168 break; 13169 case CID_START_DTMF_NOALERT: 13170 analog_p->cid_start = ANALOG_CID_START_DTMF_NOALERT; 13171 break; 13172 default: 13173 analog_p->cid_start = ANALOG_CID_START_RING; 13174 break; 13175 } 13176 analog_p->callwaitingcallerid = conf->chan.callwaitingcallerid; 13177 analog_p->ringt = conf->chan.ringt; 13178 analog_p->ringt_base = ringt_base; 13179 analog_p->onhooktime = time(NULL); 13180 if (chan_sig & __DAHDI_SIG_FXO) { 13181 memset(&p, 0, sizeof(p)); 13182 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 13183 if (!res) { 13184 analog_p->fxsoffhookstate = p.rxisoffhook; 13185 } 13186 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 13187 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting); 13188 #endif 13189 } 13190 analog_p->msgstate = -1; 13191 13192 ast_copy_string(analog_p->mohsuggest, conf->chan.mohsuggest, sizeof(analog_p->mohsuggest)); 13193 ast_copy_string(analog_p->cid_num, conf->chan.cid_num, sizeof(analog_p->cid_num)); 13194 ast_copy_string(analog_p->cid_name, conf->chan.cid_name, sizeof(analog_p->cid_name)); 13195 13196 analog_config_complete(analog_p); 13197 } 13198 break; 13199 } 13200 #if defined(HAVE_PRI) 13201 if (tmp->channel == CHAN_PSEUDO) { 13202 /* 13203 * Save off pseudo channel buffer policy values for dynamic creation of 13204 * no B channel interfaces. 13205 */ 13206 dahdi_pseudo_parms.buf_no = tmp->buf_no; 13207 dahdi_pseudo_parms.buf_policy = tmp->buf_policy; 13208 dahdi_pseudo_parms.faxbuf_no = tmp->faxbuf_no; 13209 dahdi_pseudo_parms.faxbuf_policy = tmp->faxbuf_policy; 13210 } 13211 #endif /* defined(HAVE_PRI) */ 13212 } 13213 if (tmp && !here) { 13214 /* Add the new channel interface to the sorted channel interface list. */ 13215 dahdi_iflist_insert(tmp); 13216 } 13217 return tmp; 13218 }
| static void monitor_pfds_clean | ( | void * | arg | ) | [static] |
Definition at line 11709 of file chan_dahdi.c.
References ast_free.
Referenced by do_monitor().
11709 { 11710 struct pollfd **pfds = arg; 11711 ast_free(*pfds); 11712 }
| static void mwi_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 486 of file chan_dahdi.c.
Referenced by mkintf().
00487 { 00488 /* This module does not handle MWI in an event-based manner. However, it 00489 * subscribes to MWI for each mailbox that is configured so that the core 00490 * knows that we care about it. Then, chan_dahdi will get the MWI from the 00491 * event cache instead of checking the mailbox directly. */ 00492 }
| static int mwi_send_init | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 11256 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, dahdi_subchannel::dfd, has_voicemail(), LOG_WARNING, MAX_CALLERID_SIZE, MWI_SEND_SA, MWI_SEND_SPILL, mwisend_info::mwisend_current, dahdi_pvt::mwisend_data, dahdi_pvt::mwisendactive, SUB_REAL, and dahdi_pvt::subs.
Referenced by do_monitor().
11257 { 11258 int x; 11259 11260 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11261 /* Determine how this spill is to be sent */ 11262 if (pvt->mwisend_rpas) { 11263 pvt->mwisend_data.mwisend_current = MWI_SEND_SA; 11264 pvt->mwisendactive = 1; 11265 } else if (pvt->mwisend_fsk) { 11266 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 11267 pvt->mwisendactive = 1; 11268 } else { 11269 pvt->mwisendactive = 0; 11270 return 0; 11271 } 11272 #else 11273 if (mwisend_rpas) { 11274 pvt->mwisend_data.mwisend_current = MWI_SEND_SA; 11275 } else { 11276 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 11277 } 11278 pvt->mwisendactive = 1; 11279 #endif 11280 11281 if (pvt->cidspill) { 11282 ast_log(LOG_WARNING, "cidspill already exists when trying to send FSK MWI\n"); 11283 ast_free(pvt->cidspill); 11284 pvt->cidspill = NULL; 11285 pvt->cidpos = 0; 11286 pvt->cidlen = 0; 11287 } 11288 pvt->cidspill = ast_calloc(1, MAX_CALLERID_SIZE); 11289 if (!pvt->cidspill) { 11290 pvt->mwisendactive = 0; 11291 return -1; 11292 } 11293 x = DAHDI_FLUSH_BOTH; 11294 ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x); 11295 x = 3000; 11296 ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_ONHOOKTRANSFER, &x); 11297 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11298 if (pvt->mwisend_fsk) { 11299 #endif 11300 pvt->cidlen = ast_callerid_vmwi_generate(pvt->cidspill, has_voicemail(pvt), CID_MWI_TYPE_MDMF_FULL, 11301 AST_LAW(pvt), pvt->cid_name, pvt->cid_num, 0); 11302 pvt->cidpos = 0; 11303 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11304 } 11305 #endif 11306 return 0; 11307 }
| static int mwi_send_process_buffer | ( | struct dahdi_pvt * | pvt, | |
| int | num_read | |||
| ) | [static] |
Definition at line 11309 of file chan_dahdi.c.
References ast_free, ast_log(), dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, dahdi_set_hook(), dahdi_subchannel::dfd, errno, LOG_WARNING, 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::mwisendactive, mwisend_info::pause, SUB_REAL, and dahdi_pvt::subs.
Referenced by do_monitor().
11310 { 11311 struct timeval now; 11312 int res; 11313 11314 /* sanity check to catch if this had been interrupted previously 11315 * i.e. state says there is more to do but there is no spill allocated 11316 */ 11317 if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current && !pvt->cidspill) { 11318 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11319 } else if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) { 11320 /* Normal processing -- Perform mwi send action */ 11321 switch ( pvt->mwisend_data.mwisend_current) { 11322 case MWI_SEND_SA: 11323 /* Send the Ring Pulse Signal Alert */ 11324 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &AS_RP_cadence); 11325 if (res) { 11326 ast_log(LOG_WARNING, "Unable to set RP-AS ring cadence: %s\n", strerror(errno)); 11327 goto quit; 11328 } 11329 res = dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RING); 11330 pvt->mwisend_data.mwisend_current = MWI_SEND_SA_WAIT; 11331 break; 11332 case MWI_SEND_SA_WAIT: /* do nothing until I get RINGEROFF event */ 11333 break; 11334 case MWI_SEND_PAUSE: /* Wait between alert and spill - min of 500 mS*/ 11335 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11336 if (pvt->mwisend_fsk) { 11337 #endif 11338 gettimeofday(&now, NULL); 11339 if ((int)(now.tv_sec - pvt->mwisend_data.pause.tv_sec) * 1000000 + (int)now.tv_usec - (int)pvt->mwisend_data.pause.tv_usec > 500000) { 11340 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 11341 } 11342 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11343 } else { /* support for mwisendtype=nofsk */ 11344 pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP; 11345 } 11346 #endif 11347 break; 11348 case MWI_SEND_SPILL: 11349 /* We read some number of bytes. Write an equal amount of data */ 11350 if(0 < num_read) { 11351 if (num_read > pvt->cidlen - pvt->cidpos) 11352 num_read = pvt->cidlen - pvt->cidpos; 11353 res = write(pvt->subs[SUB_REAL].dfd, pvt->cidspill + pvt->cidpos, num_read); 11354 if (res > 0) { 11355 pvt->cidpos += res; 11356 if (pvt->cidpos >= pvt->cidlen) { 11357 pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP; 11358 } 11359 } else { 11360 ast_log(LOG_WARNING, "MWI FSK Send Write failed: %s\n", strerror(errno)); 11361 goto quit; 11362 } 11363 } 11364 break; 11365 case MWI_SEND_CLEANUP: 11366 /* For now, do nothing */ 11367 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11368 break; 11369 default: 11370 /* Should not get here, punt*/ 11371 goto quit; 11372 } 11373 } 11374 11375 if (MWI_SEND_DONE == pvt->mwisend_data.mwisend_current) { 11376 if (pvt->cidspill) { 11377 ast_free(pvt->cidspill); 11378 pvt->cidspill = NULL; 11379 pvt->cidpos = 0; 11380 pvt->cidlen = 0; 11381 } 11382 pvt->mwisendactive = 0; 11383 } 11384 return 0; 11385 quit: 11386 if (pvt->cidspill) { 11387 ast_free(pvt->cidspill); 11388 pvt->cidspill = NULL; 11389 pvt->cidpos = 0; 11390 pvt->cidlen = 0; 11391 } 11392 pvt->mwisendactive = 0; 11393 return -1; 11394 }
| static int mwi_send_process_event | ( | struct dahdi_pvt * | pvt, | |
| int | event | |||
| ) | [static] |
Definition at line 11396 of file chan_dahdi.c.
References ast_free, ast_log(), dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, dahdi_set_hook(), dahdi_subchannel::dfd, errno, LOG_WARNING, 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.
Referenced by do_monitor().
11397 { 11398 int handled = 0; 11399 11400 if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) { 11401 switch (event) { 11402 case DAHDI_EVENT_RINGEROFF: 11403 if(pvt->mwisend_data.mwisend_current == MWI_SEND_SA_WAIT) { 11404 handled = 1; 11405 11406 if (dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RINGOFF) ) { 11407 ast_log(LOG_WARNING, "Unable to finish RP-AS: %s mwi send aborted\n", strerror(errno)); 11408 ast_free(pvt->cidspill); 11409 pvt->cidspill = NULL; 11410 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11411 pvt->mwisendactive = 0; 11412 } else { 11413 pvt->mwisend_data.mwisend_current = MWI_SEND_PAUSE; 11414 gettimeofday(&pvt->mwisend_data.pause, NULL); 11415 } 11416 } 11417 break; 11418 /* Going off hook, I need to punt this spill */ 11419 case DAHDI_EVENT_RINGOFFHOOK: 11420 if (pvt->cidspill) { 11421 ast_free(pvt->cidspill); 11422 pvt->cidspill = NULL; 11423 pvt->cidpos = 0; 11424 pvt->cidlen = 0; 11425 } 11426 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11427 pvt->mwisendactive = 0; 11428 break; 11429 case DAHDI_EVENT_RINGERON: 11430 case DAHDI_EVENT_HOOKCOMPLETE: 11431 break; 11432 default: 11433 break; 11434 } 11435 } 11436 return handled; 11437 }
| static void* mwi_thread | ( | void * | data | ) | [static] |
Definition at line 11104 of file chan_dahdi.c.
References analog_lib_handles(), analog_ss_thread(), analog_ss_thread_start(), ast_free, 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_get(), callerid_new(), dahdi_pvt::channel, CID_MSGWAITING, CID_NOMSGWAITING, dahdi_pvt::cid_signalling, dahdi_get_event(), dahdi_new(), dahdi_subchannel::dfd, errno, event2str(), callerid_state::flags, get_alarms(), handle_alarms(), handle_clear_alarms(), dahdi_pvt::inalarm, analog_pvt::inalarm, mwi_thread_data::len, LOG_NOTICE, LOG_WARNING, dahdi_pvt::mailbox, dahdi_pvt::mwimonitoractive, name, notify_message(), 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.
Referenced by do_monitor().
11105 { 11106 struct mwi_thread_data *mtd = data; 11107 struct callerid_state *cs; 11108 pthread_t threadid; 11109 int samples = 0; 11110 char *name, *number; 11111 int flags; 11112 int i, res; 11113 unsigned int spill_done = 0; 11114 int spill_result = -1; 11115 11116 if (!(cs = callerid_new(mtd->pvt->cid_signalling))) { 11117 goto quit_no_clean; 11118 } 11119 11120 callerid_feed(cs, mtd->buf, mtd->len, AST_LAW(mtd->pvt)); 11121 11122 bump_gains(mtd->pvt); 11123 11124 for (;;) { 11125 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 11126 if ((res = ioctl(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_IOMUX, &i))) { 11127 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 11128 goto quit; 11129 } 11130 11131 if (i & DAHDI_IOMUX_SIGEVENT) { 11132 struct ast_channel *chan; 11133 11134 /* If we get an event, screen out events that we do not act on. 11135 * Otherwise, cancel and go to the simple switch to let it deal with it. 11136 */ 11137 res = dahdi_get_event(mtd->pvt->subs[SUB_REAL].dfd); 11138 11139 switch (res) { 11140 case DAHDI_EVENT_NEONMWI_ACTIVE: 11141 case DAHDI_EVENT_NEONMWI_INACTIVE: 11142 case DAHDI_EVENT_NONE: 11143 case DAHDI_EVENT_BITSCHANGED: 11144 break; 11145 case DAHDI_EVENT_NOALARM: 11146 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 11147 struct analog_pvt *analog_p = mtd->pvt->sig_pvt; 11148 11149 analog_p->inalarm = 0; 11150 } 11151 mtd->pvt->inalarm = 0; 11152 handle_clear_alarms(mtd->pvt); 11153 break; 11154 case DAHDI_EVENT_ALARM: 11155 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 11156 struct analog_pvt *analog_p = mtd->pvt->sig_pvt; 11157 11158 analog_p->inalarm = 1; 11159 } 11160 mtd->pvt->inalarm = 1; 11161 res = get_alarms(mtd->pvt); 11162 handle_alarms(mtd->pvt, res); 11163 break; /* What to do on channel alarm ???? -- fall thru intentionally?? */ 11164 default: 11165 ast_log(LOG_NOTICE, "Got event %d (%s)... Passing along to analog_ss_thread\n", res, event2str(res)); 11166 callerid_free(cs); 11167 11168 restore_gains(mtd->pvt); 11169 mtd->pvt->ringt = mtd->pvt->ringt_base; 11170 11171 if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, NULL))) { 11172 int result; 11173 11174 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 11175 result = analog_ss_thread_start(mtd->pvt->sig_pvt, chan); 11176 } else { 11177 result = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan); 11178 } 11179 if (result) { 11180 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", mtd->pvt->channel); 11181 res = tone_zone_play_tone(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11182 if (res < 0) 11183 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", mtd->pvt->channel); 11184 ast_hangup(chan); 11185 } 11186 } else { 11187 ast_log(LOG_WARNING, "Could not create channel to handle call\n"); 11188 } 11189 goto quit_no_clean; 11190 } 11191 } else if (i & DAHDI_IOMUX_READ) { 11192 if ((res = read(mtd->pvt->subs[SUB_REAL].dfd, mtd->buf, sizeof(mtd->buf))) < 0) { 11193 if (errno != ELAST) { 11194 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 11195 goto quit; 11196 } 11197 break; 11198 } 11199 samples += res; 11200 if (!spill_done) { 11201 if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) { 11202 /* 11203 * The previous diagnostic message output likely 11204 * explains why it failed. 11205 */ 11206 ast_log(LOG_WARNING, "Failed to decode CallerID\n"); 11207 break; 11208 } else if (spill_result) { 11209 spill_done = 1; 11210 } 11211 } else { 11212 /* keep reading data until the energy level drops below the threshold 11213 so we don't get another 'trigger' on the remaining carrier signal 11214 */ 11215 if (calc_energy(mtd->buf, res, AST_LAW(mtd->pvt)) <= mwilevel) 11216 break; 11217 } 11218 if (samples > (8000 * 4)) /*Termination case - time to give up*/ 11219 break; 11220 } 11221 } 11222 11223 if (spill_result == 1) { 11224 callerid_get(cs, &name, &number, &flags); 11225 if (flags & CID_MSGWAITING) { 11226 ast_log(LOG_NOTICE, "mwi: Have Messages on channel %d\n", mtd->pvt->channel); 11227 notify_message(mtd->pvt->mailbox, 1); 11228 } else if (flags & CID_NOMSGWAITING) { 11229 ast_log(LOG_NOTICE, "mwi: No Messages on channel %d\n", mtd->pvt->channel); 11230 notify_message(mtd->pvt->mailbox, 0); 11231 } else { 11232 ast_log(LOG_NOTICE, "mwi: Status unknown on channel %d\n", mtd->pvt->channel); 11233 } 11234 } 11235 11236 11237 quit: 11238 callerid_free(cs); 11239 11240 restore_gains(mtd->pvt); 11241 11242 quit_no_clean: 11243 mtd->pvt->mwimonitoractive = 0; 11244 ast_free(mtd); 11245 11246 return NULL; 11247 }
| static void my_all_subchannels_hungup | ( | void * | pvt | ) | [static] |
Definition at line 2438 of file chan_dahdi.c.
References ast_dsp_free(), ast_log(), dahdi_pvt::channel, dahdi_setlinear(), dahdi_subchannel::dfd, dahdi_pvt::didtdd, dahdi_pvt::dsp, errno, dahdi_pvt::faxhandled, dahdi_pvt::law, dahdi_pvt::law_default, LOG_WARNING, dahdi_subchannel::owner, dahdi_pvt::owner, reset_conf(), restart_monitor(), SUB_REAL, and dahdi_pvt::subs.
02439 { 02440 struct dahdi_pvt *p = pvt; 02441 int res, law; 02442 02443 p->faxhandled = 0; 02444 p->didtdd = 0; 02445 02446 if (p->dsp) { 02447 ast_dsp_free(p->dsp); 02448 p->dsp = NULL; 02449 } 02450 02451 p->law = p->law_default; 02452 law = p->law_default; 02453 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 02454 if (res < 0) 02455 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno)); 02456 02457 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 02458 02459 #if 1 02460 { 02461 int i; 02462 p->owner = NULL; 02463 /* Cleanup owners here */ 02464 for (i = 0; i < 3; i++) { 02465 p->subs[i].owner = NULL; 02466 } 02467 } 02468 #endif 02469 02470 reset_conf(p); 02471 if (num_restart_pending == 0) { 02472 restart_monitor(); 02473 } 02474 }
| static int my_allocate_sub | ( | void * | pvt, | |
| enum analog_sub | analogsub | |||
| ) | [static] |
Definition at line 2749 of file chan_dahdi.c.
References alloc_sub(), and analogsub_to_dahdisub().
02750 { 02751 struct dahdi_pvt *p = pvt; 02752 02753 return alloc_sub(p, analogsub_to_dahdisub(analogsub)); 02754 }
| static void my_answer_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2987 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, and my_set_polarity().
02988 { 02989 struct dahdi_pvt *p = pvt; 02990 02991 if (!p->answeronpolarityswitch) { 02992 return; 02993 } 02994 02995 my_set_polarity(pvt, 1); 02996 }
| static int my_callwait | ( | void * | pvt | ) | [static] |
Definition at line 1930 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().
01931 { 01932 struct dahdi_pvt *p = pvt; 01933 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 01934 if (p->cidspill) { 01935 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 01936 ast_free(p->cidspill); 01937 } 01938 01939 /* 01940 * SAS: Subscriber Alert Signal, 440Hz for 300ms 01941 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves 01942 */ 01943 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 01944 return -1; 01945 save_conference(p); 01946 /* Silence */ 01947 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 01948 if (!p->callwaitrings && p->callwaitingcallerid) { 01949 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p)); 01950 p->callwaitcas = 1; 01951 p->cidlen = 2400 + 680 + READ_SIZE * 4; 01952 } else { 01953 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p)); 01954 p->callwaitcas = 0; 01955 p->cidlen = 2400 + READ_SIZE * 4; 01956 } 01957 p->cidpos = 0; 01958 send_callerid(p); 01959 01960 return 0; 01961 }
| static void my_cancel_cidspill | ( | void * | pvt | ) | [static] |
Definition at line 2388 of file chan_dahdi.c.
References ast_free, dahdi_pvt::cidspill, and restore_conference().
02389 { 02390 struct dahdi_pvt *p = pvt; 02391 02392 ast_free(p->cidspill); 02393 p->cidspill = NULL; 02394 restore_conference(p); 02395 }
| static int my_check_confirmanswer | ( | void * | pvt | ) | [static] |
Definition at line 2371 of file chan_dahdi.c.
References dahdi_pvt::confirmanswer.
02372 { 02373 struct dahdi_pvt *p = pvt; 02374 if (p->confirmanswer) { 02375 return 1; 02376 } 02377 02378 return 0; 02379 }
| static int my_check_for_conference | ( | void * | pvt | ) | [static] |
Definition at line 2548 of file chan_dahdi.c.
References check_for_conference().
02549 { 02550 struct dahdi_pvt *p = pvt; 02551 return check_for_conference(p); 02552 }
| static int my_check_waitingfordt | ( | void * | pvt | ) | [static] |
Definition at line 2354 of file chan_dahdi.c.
References dahdi_pvt::waitingfordt.
02355 { 02356 struct dahdi_pvt *p = pvt; 02357 02358 if (p->waitingfordt.tv_usec) { 02359 return 1; 02360 } 02361 02362 return 0; 02363 }
| static int my_complete_conference_update | ( | void * | pvt, | |
| int | needconference | |||
| ) | [static] |
Definition at line 2498 of file chan_dahdi.c.
References conf_add(), dahdi_pvt::confno, GET_CHANNEL, dahdi_pvt::inconference, dahdi_subchannel::inthreeway, isslavenative(), dahdi_pvt::master, MAX_SLAVES, dahdi_pvt::slaves, SUB_REAL, and dahdi_pvt::subs.
02499 { 02500 struct dahdi_pvt *p = pvt; 02501 int needconf = needconference; 02502 int x; 02503 int useslavenative; 02504 struct dahdi_pvt *slave = NULL; 02505 02506 useslavenative = isslavenative(p, &slave); 02507 02508 /* If we have a slave, add him to our conference now. or DAX 02509 if this is slave native */ 02510 for (x = 0; x < MAX_SLAVES; x++) { 02511 if (p->slaves[x]) { 02512 if (useslavenative) 02513 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 02514 else { 02515 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 02516 needconf++; 02517 } 02518 } 02519 } 02520 /* If we're supposed to be in there, do so now */ 02521 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 02522 if (useslavenative) 02523 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 02524 else { 02525 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 02526 needconf++; 02527 } 02528 } 02529 /* If we have a master, add ourselves to his conference */ 02530 if (p->master) { 02531 if (isslavenative(p->master, NULL)) { 02532 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 02533 } else { 02534 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 02535 } 02536 } 02537 if (!needconf) { 02538 /* Nobody is left (or should be left) in our conference. 02539 Kill it. */ 02540 p->confno = -1; 02541 } 02542 02543 return 0; 02544 }
| static int my_conf_add | ( | void * | pvt, | |
| enum analog_sub | sub | |||
| ) | [static] |
Definition at line 2488 of file chan_dahdi.c.
References analogsub_to_dahdisub(), conf_add(), and dahdi_pvt::subs.
02489 { 02490 struct dahdi_pvt *p = pvt; 02491 int x = analogsub_to_dahdisub(sub); 02492 02493 return conf_add(p, &p->subs[x], x, 0); 02494 }
| static int my_conf_del | ( | void * | pvt, | |
| enum analog_sub | sub | |||
| ) | [static] |
Definition at line 2478 of file chan_dahdi.c.
References analogsub_to_dahdisub(), conf_del(), and dahdi_pvt::subs.
02479 { 02480 struct dahdi_pvt *p = pvt; 02481 int x = analogsub_to_dahdisub(sub); 02482 02483 return conf_del(p, &p->subs[x], x); 02484 }
| static int my_confmute | ( | void * | pvt, | |
| int | mute | |||
| ) | [static] |
Definition at line 2397 of file chan_dahdi.c.
References dahdi_confmute().
02398 { 02399 struct dahdi_pvt *p = pvt; 02400 return dahdi_confmute(p, mute); 02401 }
| static int my_dahdi_write | ( | struct dahdi_pvt * | p, | |
| unsigned char * | buf, | |||
| int | len, | |||
| int | idx, | |||
| int | linear | |||
| ) | [static] |
Definition at line 9366 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().
09367 { 09368 int sent=0; 09369 int size; 09370 int res; 09371 int fd; 09372 fd = p->subs[idx].dfd; 09373 while (len) { 09374 size = len; 09375 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 09376 size = (linear ? READ_SIZE * 2 : READ_SIZE); 09377 res = write(fd, buf, size); 09378 if (res != size) { 09379 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 09380 return sent; 09381 } 09382 len -= size; 09383 buf += size; 09384 } 09385 return sent; 09386 }
| static void my_deadlock_avoidance_private | ( | void * | pvt | ) | [static] |
Definition at line 2148 of file chan_dahdi.c.
References DEADLOCK_AVOIDANCE, and dahdi_pvt::lock.
02149 { 02150 struct dahdi_pvt *p = pvt; 02151 02152 DEADLOCK_AVOIDANCE(&p->lock); 02153 }
| static void my_decrease_ss_count | ( | void | ) | [static] |
Definition at line 2430 of file chan_dahdi.c.
References ast_cond_signal, ast_mutex_lock, and ast_mutex_unlock.
02431 { 02432 ast_mutex_lock(&ss_thread_lock); 02433 ss_thread_count--; 02434 ast_cond_signal(&ss_thread_complete); 02435 ast_mutex_unlock(&ss_thread_lock); 02436 }
| static int my_dial_digits | ( | void * | pvt, | |
| enum analog_sub | sub, | |||
| struct analog_dialoperation * | dop | |||
| ) | [static] |
Definition at line 3021 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, analog_dialoperation::op, dahdi_pvt::owner, and dahdi_pvt::subs.
03022 { 03023 int index = analogsub_to_dahdisub(sub); 03024 int res; 03025 struct dahdi_pvt *p = pvt; 03026 struct dahdi_dialoperation ddop; 03027 03028 if (dop->op != ANALOG_DIAL_OP_REPLACE) { 03029 ast_log(LOG_ERROR, "Fix the dial_digits callback!\n"); 03030 return -1; 03031 } 03032 03033 if (sub != ANALOG_SUB_REAL) { 03034 ast_log(LOG_ERROR, "Trying to dial_digits '%s' on channel %d subchannel %d\n", 03035 dop->dialstr, p->channel, sub); 03036 return -1; 03037 } 03038 03039 ddop.op = DAHDI_DIAL_OP_REPLACE; 03040 ast_copy_string(ddop.dialstr, dop->dialstr, sizeof(ddop.dialstr)); 03041 03042 ast_debug(1, "Channel %d: Sending '%s' to DAHDI_DIAL.\n", p->channel, ddop.dialstr); 03043 03044 res = ioctl(p->subs[index].dfd, DAHDI_DIAL, &ddop); 03045 if (res == -1) { 03046 ast_debug(1, "DAHDI_DIAL ioctl failed on %s: %s\n", p->owner->name, strerror(errno)); 03047 } 03048 03049 return res; 03050 }
| static int my_distinctive_ring | ( | struct ast_channel * | chan, | |
| void * | pvt, | |||
| int | idx, | |||
| int * | ringdata | |||
| ) | [static] |
Definition at line 1794 of file chan_dahdi.c.
References ast_copy_string(), ast_hangup(), ast_log(), ast_verb, ast_channel::context, dahdi_pvt::context, ringContextData::contextData, dahdi_get_event(), dahdi_setlinear(), dahdi_pvt::defcontext, dahdi_subchannel::dfd, dahdi_pvt::drings, errno, event2str(), analog_pvt::inalarm, dahdi_pvt::inalarm, dahdi_subchannel::linear, LOG_NOTICE, LOG_WARNING, distRingData::range, restore_gains(), distRingData::ring, RING_PATTERNS, dahdi_distRings::ringContext, dahdi_distRings::ringnum, analog_pvt::ringt, analog_pvt::ringt_base, S_OR, dahdi_pvt::sig_pvt, and dahdi_pvt::subs.
01795 { 01796 unsigned char buf[256]; 01797 int distMatches; 01798 int curRingData[RING_PATTERNS]; 01799 int receivedRingT; 01800 int counter1; 01801 int counter; 01802 int i; 01803 int res; 01804 int checkaftercid = 0; 01805 01806 struct dahdi_pvt *p = pvt; 01807 struct analog_pvt *analog_p = p->sig_pvt; 01808 01809 if (ringdata == NULL) { 01810 ringdata = curRingData; 01811 } else { 01812 checkaftercid = 1; 01813 } 01814 01815 /* We must have a ring by now, so, if configured, lets try to listen for 01816 * distinctive ringing */ 01817 if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) { 01818 /* Clear the current ring data array so we don't have old data in it. */ 01819 for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++) 01820 ringdata[receivedRingT] = 0; 01821 receivedRingT = 0; 01822 if (checkaftercid && distinctiveringaftercid) 01823 ast_verb(3, "Detecting post-CID distinctive ring\n"); 01824 /* Check to see if context is what it should be, if not set to be. */ 01825 else if (strcmp(p->context,p->defcontext) != 0) { 01826 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 01827 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 01828 } 01829 01830 for (;;) { 01831 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 01832 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 01833 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 01834 ast_hangup(chan); 01835 return 1; 01836 } 01837 if (i & DAHDI_IOMUX_SIGEVENT) { 01838 res = dahdi_get_event(p->subs[idx].dfd); 01839 if (res == DAHDI_EVENT_NOALARM) { 01840 p->inalarm = 0; 01841 analog_p->inalarm = 0; 01842 } 01843 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 01844 res = 0; 01845 /* Let us detect distinctive ring */ 01846 01847 ringdata[receivedRingT] = analog_p->ringt; 01848 01849 if (analog_p->ringt < analog_p->ringt_base/2) 01850 break; 01851 /* Increment the ringT counter so we can match it against 01852 values in chan_dahdi.conf for distinctive ring */ 01853 if (++receivedRingT == RING_PATTERNS) 01854 break; 01855 } else if (i & DAHDI_IOMUX_READ) { 01856 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 01857 if (res < 0) { 01858 if (errno != ELAST) { 01859 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 01860 ast_hangup(chan); 01861 return 1; 01862 } 01863 break; 01864 } 01865 if (analog_p->ringt > 0) { 01866 if (!(--analog_p->ringt)) { 01867 res = -1; 01868 break; 01869 } 01870 } 01871 } 01872 } 01873 } 01874 if ((checkaftercid && usedistinctiveringdetection) || !checkaftercid) { 01875 /* this only shows up if you have n of the dring patterns filled in */ 01876 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",ringdata[0],ringdata[1],ringdata[2]); 01877 for (counter = 0; counter < 3; counter++) { 01878 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */ 01879 distMatches = 0; 01880 /* this only shows up if you have n of the dring patterns filled in */ 01881 ast_verb(3, "Checking %d,%d,%d\n", 01882 p->drings.ringnum[counter].ring[0], 01883 p->drings.ringnum[counter].ring[1], 01884 p->drings.ringnum[counter].ring[2]); 01885 for (counter1 = 0; counter1 < 3; counter1++) { 01886 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 01887 if (p->drings.ringnum[counter].ring[counter1] == -1) { 01888 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 01889 ringdata[counter1]); 01890 distMatches++; 01891 } else if (ringdata[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 01892 ringdata[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 01893 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 01894 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 01895 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 01896 distMatches++; 01897 } 01898 } 01899 01900 if (distMatches == 3) { 01901 /* The ring matches, set the context to whatever is for distinctive ring.. */ 01902 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 01903 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 01904 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 01905 break; 01906 } 01907 } 01908 } 01909 /* Restore linear mode (if appropriate) for Caller*ID processing */ 01910 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 01911 restore_gains(p); 01912 01913 return 0; 01914 }
| static int my_dsp_reset_and_flush_digits | ( | void * | pvt | ) | [static] |
Definition at line 1998 of file chan_dahdi.c.
References ast_dsp_digitreset(), and dahdi_pvt::dsp.
01999 { 02000 struct dahdi_pvt *p = pvt; 02001 if (p->dsp) 02002 ast_dsp_digitreset(p->dsp); 02003 02004 return 0; 02005 }
| static int my_dsp_set_digitmode | ( | void * | pvt, | |
| enum analog_dsp_digitmode | mode | |||
| ) | [static] |
Definition at line 2007 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.
02008 { 02009 struct dahdi_pvt *p = pvt; 02010 02011 if (p->channel == CHAN_PSEUDO) 02012 ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n"); 02013 02014 if (mode == ANALOG_DIGITMODE_DTMF) { 02015 /* If we do hardware dtmf, no need for a DSP */ 02016 if (p->hardwaredtmf) { 02017 if (p->dsp) { 02018 ast_dsp_free(p->dsp); 02019 p->dsp = NULL; 02020 } 02021 return 0; 02022 } 02023 02024 if (!p->dsp) { 02025 p->dsp = ast_dsp_new(); 02026 if (!p->dsp) { 02027 ast_log(LOG_ERROR, "Unable to allocate DSP\n"); 02028 return -1; 02029 } 02030 } 02031 02032 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 02033 } else if (mode == ANALOG_DIGITMODE_MF) { 02034 if (!p->dsp) { 02035 p->dsp = ast_dsp_new(); 02036 if (!p->dsp) { 02037 ast_log(LOG_ERROR, "Unable to allocate DSP\n"); 02038 return -1; 02039 } 02040 } 02041 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 02042 } 02043 return 0; 02044 }
| static int my_flash | ( | void * | pvt | ) | [static] |
Definition at line 2946 of file chan_dahdi.c.
References dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.
| static void my_get_and_handle_alarms | ( | void * | pvt | ) | [static] |
Definition at line 2234 of file chan_dahdi.c.
References get_alarms(), and handle_alarms().
02235 { 02236 int res; 02237 struct dahdi_pvt *p = pvt; 02238 02239 res = get_alarms(p); 02240 handle_alarms(p, res); 02241 }
| static int my_get_callerid | ( | void * | pvt, | |
| char * | namebuf, | |||
| char * | numbuf, | |||
| enum analog_event * | ev, | |||
| size_t | timeout | |||
| ) | [static] |
Definition at line 1720 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_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.
01721 { 01722 struct dahdi_pvt *p = pvt; 01723 struct analog_pvt *analog_p = p->sig_pvt; 01724 struct pollfd poller; 01725 char *name, *num; 01726 int index = SUB_REAL; 01727 int res; 01728 unsigned char buf[256]; 01729 int flags; 01730 01731 poller.fd = p->subs[SUB_REAL].dfd; 01732 poller.events = POLLPRI | POLLIN; 01733 poller.revents = 0; 01734 01735 res = poll(&poller, 1, timeout); 01736 01737 if (poller.revents & POLLPRI) { 01738 *ev = dahdievent_to_analogevent(dahdi_get_event(p->subs[SUB_REAL].dfd)); 01739 return 1; 01740 } 01741 01742 if (poller.revents & POLLIN) { 01743 /*** NOTES ***/ 01744 /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function 01745 * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until 01746 * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be 01747 * a failure and die, and returning 2 means no event was received. */ 01748 res = read(p->subs[index].dfd, buf, sizeof(buf)); 01749 if (res < 0) { 01750 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 01751 return -1; 01752 } 01753 01754 if (analog_p->ringt > 0) { 01755 if (!(--analog_p->ringt)) { 01756 /* only return if we timeout from a ring event */ 01757 return -1; 01758 } 01759 } 01760 01761 if (p->cid_signalling == CID_SIG_V23_JP) { 01762 res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p)); 01763 } else { 01764 res = callerid_feed(p->cs, buf, res, AST_LAW(p)); 01765 } 01766 if (res < 0) { 01767 /* 01768 * The previous diagnostic message output likely 01769 * explains why it failed. 01770 */ 01771 ast_log(LOG_WARNING, "Failed to decode CallerID\n"); 01772 return -1; 01773 } 01774 01775 if (res == 1) { 01776 callerid_get(p->cs, &name, &num, &flags); 01777 if (name) 01778 ast_copy_string(namebuf, name, ANALOG_MAX_CID); 01779 if (num) 01780 ast_copy_string(numbuf, num, ANALOG_MAX_CID); 01781 01782 ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags); 01783 return 0; 01784 } 01785 } 01786 01787 *ev = ANALOG_EVENT_NONE; 01788 return 2; 01789 }
| static int my_get_event | ( | void * | pvt | ) | [static] |
Definition at line 2879 of file chan_dahdi.c.
References dahdi_get_event(), dahdievent_to_analogevent(), dahdi_subchannel::dfd, dahdi_pvt::fake_event, SUB_REAL, and dahdi_pvt::subs.
02880 { 02881 struct dahdi_pvt *p = pvt; 02882 int res; 02883 02884 if (p->fake_event) { 02885 res = p->fake_event; 02886 p->fake_event = 0; 02887 } else 02888 res = dahdi_get_event(p->subs[SUB_REAL].dfd); 02889 02890 return dahdievent_to_analogevent(res); 02891 }
| static const char* my_get_orig_dialstring | ( | void * | pvt | ) | [static] |
Definition at line 2416 of file chan_dahdi.c.
References dahdi_pvt::dialstring.
02417 { 02418 struct dahdi_pvt *p = pvt; 02419 02420 return p->dialstring; 02421 }
| static void* my_get_sigpvt_bridged_channel | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 2243 of file chan_dahdi.c.
References analog_lib_handles(), ast_bridged_channel(), dahdi_pvt::oprmode, dahdi_pvt::radio, dahdi_pvt::sig, dahdi_pvt::sig_pvt, ast_channel::tech, and ast_channel::tech_pvt.
02244 { 02245 struct ast_channel *bridged = ast_bridged_channel(chan); 02246 02247 if (bridged && bridged->tech == &dahdi_tech) { 02248 struct dahdi_pvt *p = bridged->tech_pvt; 02249 02250 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 02251 return p->sig_pvt; 02252 } 02253 } 02254 return NULL; 02255 }
| static int my_get_sub_fd | ( | void * | pvt, | |
| enum analog_sub | sub | |||
| ) | [static] |
Definition at line 2257 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
02258 { 02259 struct dahdi_pvt *p = pvt; 02260 int dahdi_sub = analogsub_to_dahdisub(sub); 02261 return p->subs[dahdi_sub].dfd; 02262 }
| static int my_getsigstr | ( | struct ast_channel * | chan, | |
| char * | str, | |||
| const char * | term, | |||
| int | ms | |||
| ) | [static] |
Definition at line 9843 of file chan_dahdi.c.
References ast_waitfordigit().
Referenced by analog_ss_thread().
09844 { 09845 char c; 09846 09847 *str = 0; /* start with empty output buffer */ 09848 for (;;) 09849 { 09850 /* Wait for the first digit (up to specified ms). */ 09851 c = ast_waitfordigit(chan, ms); 09852 /* if timeout, hangup or error, return as such */ 09853 if (c < 1) 09854 return c; 09855 *str++ = c; 09856 *str = 0; 09857 if (strchr(term, c)) 09858 return 1; 09859 } 09860 }
| static void my_handle_dtmf | ( | void * | pvt, | |
| struct ast_channel * | ast, | |||
| enum analog_sub | analog_index, | |||
| struct ast_frame ** | dest | |||
| ) | [static] |
Definition at line 2064 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_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.
02065 { 02066 struct ast_frame *f = *dest; 02067 struct dahdi_pvt *p = pvt; 02068 int idx = analogsub_to_dahdisub(analog_index); 02069 02070 ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n", 02071 f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End", 02072 f->subclass.integer, f->subclass.integer, ast->name); 02073 02074 if (f->subclass.integer == 'f') { 02075 if (f->frametype == AST_FRAME_DTMF_END) { 02076 /* Fax tone -- Handle and return NULL */ 02077 if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) { 02078 /* If faxbuffers are configured, use them for the fax transmission */ 02079 if (p->usefaxbuffers && !p->bufferoverrideinuse) { 02080 struct dahdi_bufferinfo bi = { 02081 .txbufpolicy = p->faxbuf_policy, 02082 .bufsize = p->bufsize, 02083 .numbufs = p->faxbuf_no 02084 }; 02085 int res; 02086 02087 if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 02088 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast->name, strerror(errno)); 02089 } else { 02090 p->bufferoverrideinuse = 1; 02091 } 02092 } 02093 p->faxhandled = 1; 02094 if (p->dsp) { 02095 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 02096 ast_dsp_set_features(p->dsp, p->dsp_features); 02097 ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast->name); 02098 } 02099 if (strcmp(ast->exten, "fax")) { 02100 const char *target_context = S_OR(ast->macrocontext, ast->context); 02101 02102 /* We need to unlock 'ast' here because ast_exists_extension has the 02103 * potential to start autoservice on the channel. Such action is prone 02104 * to deadlock. 02105 */ 02106 ast_mutex_unlock(&p->lock); 02107 ast_channel_unlock(ast); 02108 if (ast_exists_extension(ast, target_context, "fax", 1, 02109 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 02110 ast_channel_lock(ast); 02111 ast_mutex_lock(&p->lock); 02112 ast_verb(3, "Redirecting %s to fax extension\n", ast->name); 02113 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 02114 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 02115 if (ast_async_goto(ast, target_context, "fax", 1)) 02116 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context); 02117 } else { 02118 ast_channel_lock(ast); 02119 ast_mutex_lock(&p->lock); 02120 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 02121 } 02122 } else { 02123 ast_debug(1, "Already in a fax extension, not redirecting\n"); 02124 } 02125 } else { 02126 ast_debug(1, "Fax already handled\n"); 02127 } 02128 dahdi_confmute(p, 0); 02129 } 02130 p->subs[idx].f.frametype = AST_FRAME_NULL; 02131 p->subs[idx].f.subclass.integer = 0; 02132 *dest = &p->subs[idx].f; 02133 } 02134 }
| static void my_handle_notify_message | ( | struct ast_channel * | chan, | |
| void * | pvt, | |||
| int | cid_flags, | |||
| int | neon_mwievent | |||
| ) | [static] |
Definition at line 3663 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().
Referenced by analog_ss_thread().
03664 { 03665 struct dahdi_pvt *p = pvt; 03666 03667 if (neon_mwievent > -1 && !p->mwimonitor_neon) 03668 return; 03669 03670 if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) { 03671 ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox); 03672 notify_message(p->mailbox, 1); 03673 } else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) { 03674 ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox); 03675 notify_message(p->mailbox, 0); 03676 } 03677 /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */ 03678 /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */ 03679 if (neon_mwievent == -1 && p->mwimonitor_rpas) { 03680 ast_hangup(chan); 03681 return; 03682 } 03683 }
| static void my_hangup_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2998 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, dahdi_pvt::hanguponpolarityswitch, and my_set_polarity().
02999 { 03000 struct dahdi_pvt *p = pvt; 03001 03002 if (!p->hanguponpolarityswitch) { 03003 return; 03004 } 03005 03006 if (p->answeronpolarityswitch) { 03007 my_set_polarity(pvt, 0); 03008 } else { 03009 my_set_polarity(pvt, 1); 03010 } 03011 }
| static int my_has_voicemail | ( | void * | pvt | ) | [static] |
Definition at line 2758 of file chan_dahdi.c.
References has_voicemail().
02759 { 02760 struct dahdi_pvt *p = pvt; 02761 02762 return has_voicemail(p); 02763 }
| static int my_have_progressdetect | ( | void * | pvt | ) | [static] |
Definition at line 3685 of file chan_dahdi.c.
References dahdi_pvt::callprogress, CALLPROGRESS_PROGRESS, CANPROGRESSDETECT, dahdi_pvt::dsp, and dahdi_pvt::outgoing.
03686 { 03687 struct dahdi_pvt *p = pvt; 03688 03689 if ((p->callprogress & CALLPROGRESS_PROGRESS) 03690 && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 03691 return 1; 03692 } else { 03693 /* Don't have progress detection. */ 03694 return 0; 03695 } 03696 }
| static void my_increase_ss_count | ( | void | ) | [static] |
Definition at line 2423 of file chan_dahdi.c.
References ast_mutex_lock, and ast_mutex_unlock.
02424 { 02425 ast_mutex_lock(&ss_thread_lock); 02426 ss_thread_count++; 02427 ast_mutex_unlock(&ss_thread_lock); 02428 }
| static int my_is_dialing | ( | void * | pvt, | |
| enum analog_sub | sub | |||
| ) | [static] |
Definition at line 3063 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_log(), dahdi_subchannel::dfd, LOG_DEBUG, and dahdi_pvt::subs.
| static int my_is_off_hook | ( | void * | pvt | ) | [static] |
Definition at line 2893 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, dahdi_subchannel::dfd, errno, LOG_WARNING, dahdi_pvt::sig, SIG_FXSGS, SIG_FXSKS, SUB_REAL, and dahdi_pvt::subs.
02894 { 02895 struct dahdi_pvt *p = pvt; 02896 int res; 02897 struct dahdi_params par; 02898 02899 memset(&par, 0, sizeof(par)); 02900 02901 if (p->subs[SUB_REAL].dfd > -1) 02902 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par); 02903 else { 02904 /* Assume not off hook on CVRS */ 02905 res = 0; 02906 par.rxisoffhook = 0; 02907 } 02908 if (res) { 02909 ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno)); 02910 } 02911 02912 if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 02913 /* When "onhook" that means no battery on the line, and thus 02914 it is out of service..., if it's on a TDM card... If it's a channel 02915 bank, there is no telling... */ 02916 return (par.rxbits > -1) || par.rxisoffhook; 02917 } 02918 02919 return par.rxisoffhook; 02920 }
| static void my_lock_private | ( | void * | pvt | ) | [static] |
Definition at line 2136 of file chan_dahdi.c.
References ast_mutex_lock, and dahdi_pvt::lock.
02137 { 02138 struct dahdi_pvt *p = pvt; 02139 ast_mutex_lock(&p->lock); 02140 }
| 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, read] |
Definition at line 2588 of file chan_dahdi.c.
References analogsub_to_dahdisub(), and dahdi_new().
02589 { 02590 struct dahdi_pvt *p = pvt; 02591 int dsub = analogsub_to_dahdisub(sub); 02592 02593 return dahdi_new(p, state, startpbx, dsub, 0, requestor ? requestor->linkedid : ""); 02594 }
| static int my_off_hook | ( | void * | pvt | ) | [static] |
Definition at line 2955 of file chan_dahdi.c.
References dahdi_set_hook(), dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.
02956 { 02957 struct dahdi_pvt *p = pvt; 02958 return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 02959 }
| static int my_on_hook | ( | void * | pvt | ) | [static] |
Definition at line 3079 of file chan_dahdi.c.
References ANALOG_SUB_REAL, dahdi_set_hook(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
03080 { 03081 struct dahdi_pvt *p = pvt; 03082 return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK); 03083 }
| static int my_play_tone | ( | void * | pvt, | |
| enum analog_sub | sub, | |||
| enum analog_tone | tone | |||
| ) | [static] |
Definition at line 2765 of file chan_dahdi.c.
References analog_tone_to_dahditone(), analogsub_to_dahdisub(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
02766 { 02767 struct dahdi_pvt *p = pvt; 02768 int index; 02769 02770 index = analogsub_to_dahdisub(sub); 02771 02772 return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone)); 02773 }
| static int my_ring | ( | void * | pvt | ) | [static] |
Definition at line 2939 of file chan_dahdi.c.
References dahdi_ring_phone().
02940 { 02941 struct dahdi_pvt *p = pvt; 02942 02943 return dahdi_ring_phone(p); 02944 }
| static int my_send_callerid | ( | void * | pvt, | |
| int | cwcid, | |||
| struct ast_party_caller * | caller | |||
| ) | [static] |
Definition at line 1963 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.
01964 { 01965 struct dahdi_pvt *p = pvt; 01966 01967 ast_debug(2, "Starting cid spill\n"); 01968 01969 if (p->cidspill) { 01970 ast_log(LOG_WARNING, "cidspill already exists??\n"); 01971 ast_free(p->cidspill); 01972 } 01973 01974 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) { 01975 if (cwcid == 0) { 01976 p->cidlen = ast_callerid_generate(p->cidspill, 01977 caller->id.name.str, 01978 caller->id.number.str, 01979 AST_LAW(p)); 01980 } else { 01981 ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", 01982 caller->id.name.str, caller->id.number.str); 01983 p->callwaitcas = 0; 01984 p->cidcwexpire = 0; 01985 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, 01986 caller->id.name.str, 01987 caller->id.number.str, 01988 AST_LAW(p)); 01989 p->cidlen += READ_SIZE * 4; 01990 } 01991 p->cidpos = 0; 01992 p->cid_suppress_expire = 0; 01993 send_callerid(p); 01994 } 01995 return 0; 01996 }
| static void my_set_alarm | ( | void * | pvt, | |
| int | in_alarm | |||
| ) | [static] |
Definition at line 2280 of file chan_dahdi.c.
References dahdi_pvt::inalarm.
| static void my_set_cadence | ( | void * | pvt, | |
| int * | cid_rings, | |||
| struct ast_channel * | ast | |||
| ) | [static] |
Definition at line 2264 of file chan_dahdi.c.
References ast_log(), dahdi_subchannel::dfd, dahdi_pvt::distinctivering, errno, LOG_WARNING, dahdi_pvt::sendcalleridafter, SUB_REAL, and dahdi_pvt::subs.
02265 { 02266 struct dahdi_pvt *p = pvt; 02267 02268 /* Choose proper cadence */ 02269 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) { 02270 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1])) 02271 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno)); 02272 *cid_rings = cidrings[p->distinctivering - 1]; 02273 } else { 02274 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL)) 02275 ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno)); 02276 *cid_rings = p->sendcalleridafter; 02277 } 02278 }
| static void my_set_callwaiting | ( | void * | pvt, | |
| int | callwaiting_enable | |||
| ) | [static] |
Definition at line 2381 of file chan_dahdi.c.
References dahdi_pvt::callwaiting.
02382 { 02383 struct dahdi_pvt *p = pvt; 02384 02385 p->callwaiting = callwaiting_enable; 02386 }
| static void my_set_confirmanswer | ( | void * | pvt, | |
| int | flag | |||
| ) | [static] |
Definition at line 2365 of file chan_dahdi.c.
References dahdi_pvt::confirmanswer.
02366 { 02367 struct dahdi_pvt *p = pvt; 02368 p->confirmanswer = flag; 02369 }
| static void my_set_dialing | ( | void * | pvt, | |
| int | is_dialing | |||
| ) | [static] |
Definition at line 2287 of file chan_dahdi.c.
References dahdi_pvt::dialing.
| static int my_set_echocanceller | ( | void * | pvt, | |
| int | enable | |||
| ) | [static] |
Definition at line 2925 of file chan_dahdi.c.
References dahdi_disable_ec(), and dahdi_enable_ec().
02926 { 02927 struct dahdi_pvt *p = pvt; 02928 02929 if (enable) 02930 dahdi_enable_ec(p); 02931 else 02932 dahdi_disable_ec(p); 02933 02934 return 0; 02935 }
| static void my_set_inthreeway | ( | void * | pvt, | |
| enum analog_sub | sub, | |||
| int | inthreeway | |||
| ) | [static] |
Definition at line 2224 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_subchannel::inthreeway, and dahdi_pvt::subs.
02225 { 02226 struct dahdi_pvt *p = pvt; 02227 int idx = analogsub_to_dahdisub(sub); 02228 02229 p->subs[idx].inthreeway = inthreeway; 02230 }
| static int my_set_linear_mode | ( | void * | pvt, | |
| enum analog_sub | sub, | |||
| int | linear_mode | |||
| ) | [static] |
Definition at line 2212 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_setlinear(), dahdi_subchannel::dfd, dahdi_subchannel::linear, and dahdi_pvt::subs.
02213 { 02214 struct dahdi_pvt *p = pvt; 02215 int oldval; 02216 int idx = analogsub_to_dahdisub(sub); 02217 02218 dahdi_setlinear(p->subs[idx].dfd, linear_mode); 02219 oldval = p->subs[idx].linear; 02220 p->subs[idx].linear = linear_mode ? 1 : 0; 02221 return oldval; 02222 }
| static void my_set_needringing | ( | void * | pvt, | |
| int | value | |||
| ) | [static] |
Definition at line 2961 of file chan_dahdi.c.
References dahdi_subchannel::needringing, SUB_REAL, and dahdi_pvt::subs.
02962 { 02963 struct dahdi_pvt *p = pvt; 02964 p->subs[SUB_REAL].needringing = value; 02965 }
| static void my_set_new_owner | ( | void * | pvt, | |
| struct ast_channel * | new_owner | |||
| ) | [static] |
Definition at line 2409 of file chan_dahdi.c.
References dahdi_pvt::owner.
| static void my_set_outgoing | ( | void * | pvt, | |
| int | is_outgoing | |||
| ) | [static] |
Definition at line 2294 of file chan_dahdi.c.
References dahdi_pvt::outgoing.
| static void my_set_polarity | ( | void * | pvt, | |
| int | value | |||
| ) | [static] |
Definition at line 2967 of file chan_dahdi.c.
References CHAN_PSEUDO, dahdi_pvt::channel, dahdi_subchannel::dfd, dahdi_pvt::polarity, SUB_REAL, and dahdi_pvt::subs.
Referenced by my_answer_polarityswitch(), my_hangup_polarityswitch(), and my_start_polarityswitch().
| static void my_set_pulsedial | ( | void * | pvt, | |
| int | flag | |||
| ) | [static] |
Definition at line 2403 of file chan_dahdi.c.
References dahdi_pvt::pulsedial.
| static void my_set_ringtimeout | ( | void * | pvt, | |
| int | ringt | |||
| ) | [static] |
Definition at line 2337 of file chan_dahdi.c.
References dahdi_pvt::ringt.
| static void my_set_waitingfordt | ( | void * | pvt, | |
| struct ast_channel * | ast | |||
| ) | [static] |
Definition at line 2343 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.
02344 { 02345 struct dahdi_pvt *p = pvt; 02346 02347 if (p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp) { 02348 ast_log(LOG_DEBUG, "Defer dialing for %dms or dialtone\n", p->waitfordialtone); 02349 gettimeofday(&p->waitingfordt, NULL); 02350 ast_setstate(ast, AST_STATE_OFFHOOK); 02351 } 02352 }
| static int my_start | ( | void * | pvt | ) | [static] |
Definition at line 3013 of file chan_dahdi.c.
References dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.
| static int my_start_cid_detect | ( | void * | pvt, | |
| int | cid_signalling | |||
| ) | [static] |
Definition at line 1695 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.
01696 { 01697 struct dahdi_pvt *p = pvt; 01698 int index = SUB_REAL; 01699 p->cs = callerid_new(cid_signalling); 01700 if (!p->cs) { 01701 ast_log(LOG_ERROR, "Unable to alloc callerid\n"); 01702 return -1; 01703 } 01704 bump_gains(p); 01705 dahdi_setlinear(p->subs[index].dfd, 0); 01706 01707 return 0; 01708 }
| static void my_start_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2978 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, dahdi_pvt::hanguponpolarityswitch, and my_set_polarity().
02979 { 02980 struct dahdi_pvt *p = pvt; 02981 02982 if (p->answeronpolarityswitch || p->hanguponpolarityswitch) { 02983 my_set_polarity(pvt, 0); 02984 } 02985 }
| static int my_stop_callwait | ( | void * | pvt | ) | [static] |
Definition at line 1916 of file chan_dahdi.c.
References dahdi_pvt::callwaitingrepeat, dahdi_pvt::cid_suppress_expire, and dahdi_pvt::cidcwexpire.
01917 { 01918 struct dahdi_pvt *p = pvt; 01919 p->callwaitingrepeat = 0; 01920 p->cidcwexpire = 0; 01921 p->cid_suppress_expire = 0; 01922 01923 return 0; 01924 }
| static int my_stop_cid_detect | ( | void * | pvt | ) | [static] |
Definition at line 1710 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.
01711 { 01712 struct dahdi_pvt *p = pvt; 01713 int index = SUB_REAL; 01714 if (p->cs) 01715 callerid_free(p->cs); 01716 dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear); 01717 return 0; 01718 }
| 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 2554 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().
02555 { 02556 struct dahdi_pvt *p = pvt; 02557 int da, db; 02558 int tchan; 02559 int tinthreeway; 02560 02561 da = analogsub_to_dahdisub(a); 02562 db = analogsub_to_dahdisub(b); 02563 02564 tchan = p->subs[da].chan; 02565 p->subs[da].chan = p->subs[db].chan; 02566 p->subs[db].chan = tchan; 02567 02568 tinthreeway = p->subs[da].inthreeway; 02569 p->subs[da].inthreeway = p->subs[db].inthreeway; 02570 p->subs[db].inthreeway = tinthreeway; 02571 02572 p->subs[da].owner = ast_a; 02573 p->subs[db].owner = ast_b; 02574 02575 if (ast_a) 02576 ast_channel_set_fd(ast_a, 0, p->subs[da].dfd); 02577 if (ast_b) 02578 ast_channel_set_fd(ast_b, 0, p->subs[db].dfd); 02579 02580 wakeup_sub(p, a); 02581 wakeup_sub(p, b); 02582 02583 return; 02584 }
| static int my_train_echocanceller | ( | void * | pvt | ) | [static] |
Definition at line 3054 of file chan_dahdi.c.
References dahdi_train_ec().
03055 { 03056 struct dahdi_pvt *p = pvt; 03057 03058 dahdi_train_ec(p); 03059 03060 return 0; 03061 }
| static int my_unallocate_sub | ( | void * | pvt, | |
| enum analog_sub | analogsub | |||
| ) | [static] |
Definition at line 2740 of file chan_dahdi.c.
References analogsub_to_dahdisub(), and unalloc_sub().
02741 { 02742 struct dahdi_pvt *p = pvt; 02743 02744 return unalloc_sub(p, analogsub_to_dahdisub(analogsub)); 02745 }
| static void my_unlock_private | ( | void * | pvt | ) | [static] |
Definition at line 2142 of file chan_dahdi.c.
References ast_mutex_unlock, and dahdi_pvt::lock.
02143 { 02144 struct dahdi_pvt *p = pvt; 02145 ast_mutex_unlock(&p->lock); 02146 }
| static int my_wait_event | ( | void * | pvt | ) | [static] |
Definition at line 2872 of file chan_dahdi.c.
References dahdi_wait_event(), dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.
02873 { 02874 struct dahdi_pvt *p = pvt; 02875 02876 return dahdi_wait_event(p->subs[SUB_REAL].dfd); 02877 }
| static int my_wink | ( | void * | pvt, | |
| enum analog_sub | sub | |||
| ) | [static] |
Definition at line 2048 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_log(), dahdi_wink(), LOG_ERROR, and SUB_REAL.
02049 { 02050 struct dahdi_pvt *p = pvt; 02051 int index = analogsub_to_dahdisub(sub); 02052 if (index != SUB_REAL) { 02053 ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n"); 02054 } 02055 return dahdi_wink(p, index); 02056 }
| static void notify_message | ( | char * | mailbox_full, | |
| int | thereornot | |||
| ) | [static] |
Send MWI state change.
This function does two things:
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 3634 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, and mailbox.
Referenced by handle_init_event(), mwi_thread(), and my_handle_notify_message().
03635 { 03636 char s[sizeof(mwimonitornotify) + 80]; 03637 struct ast_event *event; 03638 char *mailbox, *context; 03639 03640 /* Strip off @default */ 03641 context = mailbox = ast_strdupa(mailbox_full); 03642 strsep(&context, "@"); 03643 if (ast_strlen_zero(context)) 03644 context = "default"; 03645 03646 if (!(event = ast_event_new(AST_EVENT_MWI, 03647 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 03648 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 03649 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot, 03650 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot, 03651 AST_EVENT_IE_END))) { 03652 return; 03653 } 03654 03655 ast_event_queue_and_cache(event); 03656 03657 if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) { 03658 snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot); 03659 ast_safe_system(s); 03660 } 03661 }
| static int parse_buffers_policy | ( | const char * | parse, | |
| int * | num_buffers, | |||
| int * | policy | |||
| ) | [static] |
Definition at line 7052 of file chan_dahdi.c.
References ast_log(), and LOG_WARNING.
Referenced by dahdi_func_write(), and process_dahdi().
07053 { 07054 int res; 07055 char policy_str[21] = ""; 07056 07057 if ((res = sscanf(parse, "%30d,%20s", num_buffers, policy_str)) != 2) { 07058 ast_log(LOG_WARNING, "Parsing buffer string '%s' failed.\n", parse); 07059 return 1; 07060 } 07061 if (*num_buffers < 0) { 07062 ast_log(LOG_WARNING, "Invalid buffer count given '%d'.\n", *num_buffers); 07063 return -1; 07064 } 07065 if (!strcasecmp(policy_str, "full")) { 07066 *policy = DAHDI_POLICY_WHEN_FULL; 07067 } else if (!strcasecmp(policy_str, "immediate")) { 07068 *policy = DAHDI_POLICY_IMMEDIATE; 07069 #if defined(HAVE_DAHDI_HALF_FULL) 07070 } else if (!strcasecmp(policy_str, "half")) { 07071 *policy = DAHDI_POLICY_HALF_FULL; 07072 #endif 07073 } else { 07074 ast_log(LOG_WARNING, "Invalid policy name given '%s'.\n", policy_str); 07075 return -1; 07076 } 07077 07078 return 0; 07079 }
| static char* parse_spanchan | ( | char * | chanstr, | |
| char ** | subdir | |||
| ) | [static] |
Definition at line 16853 of file chan_dahdi.c.
References string_replace().
Referenced by build_channels().
16854 { 16855 char *p; 16856 16857 if ((p = strrchr(chanstr, '!')) == NULL) { 16858 *subdir = NULL; 16859 return chanstr; 16860 } 16861 *p++ = '\0'; 16862 string_replace(chanstr, '!', '/'); 16863 *subdir = chanstr; 16864 return p; 16865 }
| static int process_dahdi | ( | struct dahdi_chan_conf * | confp, | |
| const char * | cat, | |||
| struct ast_variable * | v, | |||
| int | reload, | |||
| int | options | |||
| ) | [static] |
Definition at line 16996 of file chan_dahdi.c.
References dahdi_pvt::accountcode, dahdi_pvt::adsi, dahdi_pvt::amaflags, dahdi_pvt::answeronpolarityswitch, ast_callerid_split(), ast_cc_config_params_destroy(), ast_cc_is_config_param(), ast_cc_set_param(), ast_cdr_amaflags2int(), ast_copy_string(), ast_get_group(), ast_jb_read_conf(), ast_log(), AST_MAX_EXTENSION, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_new(), ast_variables_destroy(), ast_verb, dahdi_pvt::buf_no, dahdi_pvt::buf_policy, build_channels(), dahdi_pvt::busy_quietlength, dahdi_pvt::busy_tonelength, dahdi_pvt::busycount, dahdi_pvt::busydetect, dahdi_pvt::callgroup, dahdi_pvt::callprogress, CALLPROGRESS_FAX, CALLPROGRESS_FAX_INCOMING, CALLPROGRESS_FAX_OUTGOING, CALLPROGRESS_PROGRESS, dahdi_pvt::callreturn, dahdi_pvt::callwaiting, dahdi_pvt::callwaitingcallerid, dahdi_pvt::cancallforward, dahdi_pvt::canpark, dahdi_pvt::cc_params, dahdi_chan_conf::chan, CHAN_PSEUDO, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_rxgain, CID_SIG_BELL, 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, CID_START_RING, dahdi_pvt::cid_tag, dahdi_pvt::context, ringContextData::contextData, dahdi_chan_conf_default(), DAHDI_CHAN_MAPPING_LOGICAL, DAHDI_CHAN_MAPPING_PHYSICAL, DAHDI_OVERLAPDIAL_BOTH, DAHDI_OVERLAPDIAL_INCOMING, DAHDI_OVERLAPDIAL_NONE, DAHDI_OVERLAPDIAL_OUTGOING, dahdi_pvt::dahditrcallerid, dahdi_pvt::destroy, dahdi_pvt::drings, DSP_DIGITMODE_RELAXDTMF, dahdi_pvt::dtmfrelax, dahdi_pvt::echocanbridged, dahdi_pvt::echotraining, errno, dahdi_pvt::faxbuf_no, dahdi_pvt::faxbuf_policy, global_jbconf, dahdi_pvt::group, dahdi_pvt::hanguponpolarityswitch, dahdi_pvt::hidecallerid, dahdi_pvt::hidecalleridname, dahdi_chan_conf::ignore_failed_channels, dahdi_pvt::immediate, dahdi_chan_conf::is_sig_auto, dahdi_pvt::language, ast_variable::lineno, LINKSET_FLAG_EXPLICITACM, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, dahdi_pvt::mailbox, dahdi_pvt::manages_span_alarms, mkintf(), dahdi_pvt::mohinterpret, dahdi_pvt::mohsuggest, dahdi_pvt::mwimonitor_fsk, dahdi_pvt::mwimonitor_neon, dahdi_pvt::mwimonitor_rpas, ast_variable::name, dahdi_pvt::next, ast_variable::next, NUM_CADENCE_MAX, dahdi_pvt::outsigmod, dahdi_pvt::parkinglot, parse_buffers_policy(), dahdi_pvt::pickupgroup, dahdi_pvt::polarityonanswerdelay, dahdi_pvt::priexclusive, dahdi_pvt::priindication_oob, PROC_DAHDI_OPT_NOCHAN, PROC_DAHDI_OPT_NOWARN, process_echocancel(), dahdi_pvt::pulse, dahdi_pvt::radio, distRingData::range, READ_SIZE, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, dahdi_pvt::restrictcid, distRingData::ring, dahdi_distRings::ringContext, dahdi_distRings::ringnum, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, dahdi_pvt::sendcalleridafter, dahdi_pvt::sig, 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_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, SIG_SF, SIG_SF_FEATB, SIG_SFWINK, SIG_SS7, dahdi_chan_conf::smdi_port, dahdi_pvt::span, SS7_NAI_DYNAMIC, dahdi_pvt::stripmsd, dahdi_pvt::threewaycalling, timer, dahdi_chan_conf::timing, dahdi_pvt::tonezone, dahdi_pvt::transfer, dahdi_pvt::transfertobusy, dahdi_pvt::txdrc, dahdi_pvt::txgain, dahdi_pvt::use_callerid, dahdi_pvt::use_callingpres, dahdi_pvt::use_smdi, dahdi_pvt::usefaxbuffers, ast_variable::value, dahdi_pvt::vars, and dahdi_pvt::waitfordialtone.
Referenced by setup_dahdi_int().
16997 { 16998 struct dahdi_pvt *tmp; 16999 int y; 17000 int found_pseudo = 0; 17001 struct ast_variable *dahdichan = NULL; 17002 17003 for (; v; v = v->next) { 17004 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 17005 continue; 17006 17007 /* Create the interface list */ 17008 if (!strcasecmp(v->name, "channel") || !strcasecmp(v->name, "channels")) { 17009 if (options & PROC_DAHDI_OPT_NOCHAN) { 17010 ast_log(LOG_WARNING, "Channel '%s' ignored.\n", v->value); 17011 continue; 17012 } 17013 if (build_channels(confp, v->value, reload, v->lineno, &found_pseudo)) { 17014 if (confp->ignore_failed_channels) { 17015 ast_log(LOG_WARNING, "Channel '%s' failure ignored: ignore_failed_channels.\n", v->value); 17016 continue; 17017 } else { 17018 return -1; 17019 } 17020 } 17021 ast_log(LOG_DEBUG, "Channel '%s' configured.\n", v->value); 17022 } else if (!strcasecmp(v->name, "ignore_failed_channels")) { 17023 confp->ignore_failed_channels = ast_true(v->value); 17024 } else if (!strcasecmp(v->name, "buffers")) { 17025 if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) { 17026 ast_log(LOG_WARNING, "Using default buffer policy.\n"); 17027 confp->chan.buf_no = numbufs; 17028 confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE; 17029 } 17030 } else if (!strcasecmp(v->name, "faxbuffers")) { 17031 if (!parse_buffers_policy(v->value, &confp->chan.faxbuf_no, &confp->chan.faxbuf_policy)) { 17032 confp->chan.usefaxbuffers = 1; 17033 } 17034 } else if (!strcasecmp(v->name, "dahdichan")) { 17035 /* Only process the last dahdichan value. */ 17036 dahdichan = v; 17037 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 17038 usedistinctiveringdetection = ast_true(v->value); 17039 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) { 17040 distinctiveringaftercid = ast_true(v->value); 17041 } else if (!strcasecmp(v->name, "dring1context")) { 17042 ast_copy_string(confp->chan.drings.ringContext[0].contextData,v->value,sizeof(confp->chan.drings.ringContext[0].contextData)); 17043 } else if (!strcasecmp(v->name, "dring2context")) { 17044 ast_copy_string(confp->chan.drings.ringContext[1].contextData,v->value,sizeof(confp->chan.drings.ringContext[1].contextData)); 17045 } else if (!strcasecmp(v->name, "dring3context")) { 17046 ast_copy_string(confp->chan.drings.ringContext[2].contextData,v->value,sizeof(confp->chan.drings.ringContext[2].contextData)); 17047 } else if (!strcasecmp(v->name, "dring1range")) { 17048 confp->chan.drings.ringnum[0].range = atoi(v->value); 17049 } else if (!strcasecmp(v->name, "dring2range")) { 17050 confp->chan.drings.ringnum[1].range = atoi(v->value); 17051 } else if (!strcasecmp(v->name, "dring3range")) { 17052 confp->chan.drings.ringnum[2].range = atoi(v->value); 17053 } else if (!strcasecmp(v->name, "dring1")) { 17054 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]); 17055 } else if (!strcasecmp(v->name, "dring2")) { 17056 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]); 17057 } else if (!strcasecmp(v->name, "dring3")) { 17058 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]); 17059 } else if (!strcasecmp(v->name, "usecallerid")) { 17060 confp->chan.use_callerid = ast_true(v->value); 17061 } else if (!strcasecmp(v->name, "cidsignalling")) { 17062 if (!strcasecmp(v->value, "bell")) 17063 confp->chan.cid_signalling = CID_SIG_BELL; 17064 else if (!strcasecmp(v->value, "v23")) 17065 confp->chan.cid_signalling = CID_SIG_V23; 17066 else if (!strcasecmp(v->value, "dtmf")) 17067 confp->chan.cid_signalling = CID_SIG_DTMF; 17068 else if (!strcasecmp(v->value, "smdi")) 17069 confp->chan.cid_signalling = CID_SIG_SMDI; 17070 else if (!strcasecmp(v->value, "v23_jp")) 17071 confp->chan.cid_signalling = CID_SIG_V23_JP; 17072 else if (ast_true(v->value)) 17073 confp->chan.cid_signalling = CID_SIG_BELL; 17074 } else if (!strcasecmp(v->name, "cidstart")) { 17075 if (!strcasecmp(v->value, "ring")) 17076 confp->chan.cid_start = CID_START_RING; 17077 else if (!strcasecmp(v->value, "polarity_in")) 17078 confp->chan.cid_start = CID_START_POLARITY_IN; 17079 else if (!strcasecmp(v->value, "polarity")) 17080 confp->chan.cid_start = CID_START_POLARITY; 17081 else if (!strcasecmp(v->value, "dtmf")) 17082 confp->chan.cid_start = CID_START_DTMF_NOALERT; 17083 else if (ast_true(v->value)) 17084 confp->chan.cid_start = CID_START_RING; 17085 } else if (!strcasecmp(v->name, "threewaycalling")) { 17086 confp->chan.threewaycalling = ast_true(v->value); 17087 } else if (!strcasecmp(v->name, "cancallforward")) { 17088 confp->chan.cancallforward = ast_true(v->value); 17089 } else if (!strcasecmp(v->name, "relaxdtmf")) { 17090 if (ast_true(v->value)) 17091 confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 17092 else 17093 confp->chan.dtmfrelax = 0; 17094 } else if (!strcasecmp(v->name, "mailbox")) { 17095 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox)); 17096 } else if (!strcasecmp(v->name, "hasvoicemail")) { 17097 if (ast_true(v->value) && ast_strlen_zero(confp->chan.mailbox)) { 17098 ast_copy_string(confp->chan.mailbox, cat, sizeof(confp->chan.mailbox)); 17099 } 17100 } else if (!strcasecmp(v->name, "adsi")) { 17101 confp->chan.adsi = ast_true(v->value); 17102 } else if (!strcasecmp(v->name, "usesmdi")) { 17103 confp->chan.use_smdi = ast_true(v->value); 17104 } else if (!strcasecmp(v->name, "smdiport")) { 17105 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port)); 17106 } else if (!strcasecmp(v->name, "transfer")) { 17107 confp->chan.transfer = ast_true(v->value); 17108 } else if (!strcasecmp(v->name, "canpark")) { 17109 confp->chan.canpark = ast_true(v->value); 17110 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 17111 confp->chan.echocanbridged = ast_true(v->value); 17112 } else if (!strcasecmp(v->name, "busydetect")) { 17113 confp->chan.busydetect = ast_true(v->value); 17114 } else if (!strcasecmp(v->name, "busycount")) { 17115 confp->chan.busycount = atoi(v->value); 17116 } else if (!strcasecmp(v->name, "busypattern")) { 17117 if (sscanf(v->value, "%30d,%30d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) { 17118 ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength at line %d.\n", v->lineno); 17119 } 17120 } else if (!strcasecmp(v->name, "callprogress")) { 17121 confp->chan.callprogress &= ~CALLPROGRESS_PROGRESS; 17122 if (ast_true(v->value)) 17123 confp->chan.callprogress |= CALLPROGRESS_PROGRESS; 17124 } else if (!strcasecmp(v->name, "waitfordialtone")) { 17125 confp->chan.waitfordialtone = atoi(v->value); 17126 } else if (!strcasecmp(v->name, "faxdetect")) { 17127 confp->chan.callprogress &= ~CALLPROGRESS_FAX; 17128 if (!strcasecmp(v->value, "incoming")) { 17129 confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING; 17130 } else if (!strcasecmp(v->value, "outgoing")) { 17131 confp->chan.callprogress |= CALLPROGRESS_FAX_OUTGOING; 17132 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 17133 confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING; 17134 } else if (!strcasecmp(v->name, "echocancel")) { 17135 process_echocancel(confp, v->value, v->lineno); 17136 } else if (!strcasecmp(v->name, "echotraining")) { 17137 if (sscanf(v->value, "%30d", &y) == 1) { 17138 if ((y < 10) || (y > 4000)) { 17139 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d.\n", v->lineno); 17140 } else { 17141 confp->chan.echotraining = y; 17142 } 17143 } else if (ast_true(v->value)) { 17144 confp->chan.echotraining = 400; 17145 } else 17146 confp->chan.echotraining = 0; 17147 } else if (!strcasecmp(v->name, "hidecallerid")) { 17148 confp->chan.hidecallerid = ast_true(v->value); 17149 } else if (!strcasecmp(v->name, "hidecalleridname")) { 17150 confp->chan.hidecalleridname = ast_true(v->value); 17151 } else if (!strcasecmp(v->name, "pulsedial")) { 17152 confp->chan.pulse = ast_true(v->value); 17153 } else if (!strcasecmp(v->name, "callreturn")) { 17154 confp->chan.callreturn = ast_true(v->value); 17155 } else if (!strcasecmp(v->name, "callwaiting")) { 17156 confp->chan.callwaiting = ast_true(v->value); 17157 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 17158 confp->chan.callwaitingcallerid = ast_true(v->value); 17159 } else if (!strcasecmp(v->name, "context")) { 17160 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context)); 17161 } else if (!strcasecmp(v->name, "language")) { 17162 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language)); 17163 } else if (!strcasecmp(v->name, "progzone")) { 17164 ast_copy_string(progzone, v->value, sizeof(progzone)); 17165 } else if (!strcasecmp(v->name, "mohinterpret") 17166 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) { 17167 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret)); 17168 } else if (!strcasecmp(v->name, "mohsuggest")) { 17169 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest)); 17170 } else if (!strcasecmp(v->name, "parkinglot")) { 17171 ast_copy_string(confp->chan.parkinglot, v->value, sizeof(confp->chan.parkinglot)); 17172 } else if (!strcasecmp(v->name, "stripmsd")) { 17173 ast_log(LOG_NOTICE, "Configuration option \"%s\" has been deprecated. Please use dialplan instead\n", v->name); 17174 confp->chan.stripmsd = atoi(v->value); 17175 } else if (!strcasecmp(v->name, "jitterbuffers")) { 17176 numbufs = atoi(v->value); 17177 } else if (!strcasecmp(v->name, "group")) { 17178 confp->chan.group = ast_get_group(v->value); 17179 } else if (!strcasecmp(v->name, "callgroup")) { 17180 if (!strcasecmp(v->value, "none")) 17181 confp->chan.callgroup = 0; 17182 else 17183 confp->chan.callgroup = ast_get_group(v->value); 17184 } else if (!strcasecmp(v->name, "pickupgroup")) { 17185 if (!strcasecmp(v->value, "none")) 17186 confp->chan.pickupgroup = 0; 17187 else 17188 confp->chan.pickupgroup = ast_get_group(v->value); 17189 } else if (!strcasecmp(v->name, "setvar")) { 17190 char *varname = ast_strdupa(v->value), *varval = NULL; 17191 struct ast_variable *tmpvar; 17192 if (varname && (varval = strchr(varname, '='))) { 17193 *varval++ = '\0'; 17194 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 17195 tmpvar->next = confp->chan.vars; 17196 confp->chan.vars = tmpvar; 17197 } 17198 } 17199 } else if (!strcasecmp(v->name, "immediate")) { 17200 confp->chan.immediate = ast_true(v->value); 17201 } else if (!strcasecmp(v->name, "transfertobusy")) { 17202 confp->chan.transfertobusy = ast_true(v->value); 17203 } else if (!strcasecmp(v->name, "mwimonitor")) { 17204 confp->chan.mwimonitor_neon = 0; 17205 confp->chan.mwimonitor_fsk = 0; 17206 confp->chan.mwimonitor_rpas = 0; 17207 if (strcasestr(v->value, "fsk")) { 17208 confp->chan.mwimonitor_fsk = 1; 17209 } 17210 if (strcasestr(v->value, "rpas")) { 17211 confp->chan.mwimonitor_rpas = 1; 17212 } 17213 if (strcasestr(v->value, "neon")) { 17214 confp->chan.mwimonitor_neon = 1; 17215 } 17216 /* If set to true or yes, assume that simple fsk is desired */ 17217 if (ast_true(v->value)) { 17218 confp->chan.mwimonitor_fsk = 1; 17219 } 17220 } else if (!strcasecmp(v->name, "cid_rxgain")) { 17221 if (sscanf(v->value, "%30f", &confp->chan.cid_rxgain) != 1) { 17222 ast_log(LOG_WARNING, "Invalid cid_rxgain: %s at line %d.\n", v->value, v->lineno); 17223 } 17224 } else if (!strcasecmp(v->name, "rxgain")) { 17225 if (sscanf(v->value, "%30f", &confp->chan.rxgain) != 1) { 17226 ast_log(LOG_WARNING, "Invalid rxgain: %s at line %d.\n", v->value, v->lineno); 17227 } 17228 } else if (!strcasecmp(v->name, "txgain")) { 17229 if (sscanf(v->value, "%30f", &confp->chan.txgain) != 1) { 17230 ast_log(LOG_WARNING, "Invalid txgain: %s at line %d.\n", v->value, v->lineno); 17231 } 17232 } else if (!strcasecmp(v->name, "txdrc")) { 17233 if (sscanf(v->value, "%f", &confp->chan.txdrc) != 1) { 17234 ast_log(LOG_WARNING, "Invalid txdrc: %s\n", v->value); 17235 } 17236 } else if (!strcasecmp(v->name, "rxdrc")) { 17237 if (sscanf(v->value, "%f", &confp->chan.rxdrc) != 1) { 17238 ast_log(LOG_WARNING, "Invalid rxdrc: %s\n", v->value); 17239 } 17240 } else if (!strcasecmp(v->name, "tonezone")) { 17241 if (sscanf(v->value, "%30d", &confp->chan.tonezone) != 1) { 17242 ast_log(LOG_WARNING, "Invalid tonezone: %s at line %d.\n", v->value, v->lineno); 17243 } 17244 } else if (!strcasecmp(v->name, "callerid")) { 17245 if (!strcasecmp(v->value, "asreceived")) { 17246 confp->chan.cid_num[0] = '\0'; 17247 confp->chan.cid_name[0] = '\0'; 17248 } else { 17249 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num)); 17250 } 17251 } else if (!strcasecmp(v->name, "fullname")) { 17252 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name)); 17253 } else if (!strcasecmp(v->name, "cid_number")) { 17254 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num)); 17255 } else if (!strcasecmp(v->name, "cid_tag")) { 17256 ast_copy_string(confp->chan.cid_tag, v->value, sizeof(confp->chan.cid_tag)); 17257 } else if (!strcasecmp(v->name, "useincomingcalleridondahditransfer")) { 17258 confp->chan.dahditrcallerid = ast_true(v->value); 17259 } else if (!strcasecmp(v->name, "restrictcid")) { 17260 confp->chan.restrictcid = ast_true(v->value); 17261 } else if (!strcasecmp(v->name, "usecallingpres")) { 17262 confp->chan.use_callingpres = ast_true(v->value); 17263 } else if (!strcasecmp(v->name, "accountcode")) { 17264 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode)); 17265 } else if (!strcasecmp(v->name, "amaflags")) { 17266 y = ast_cdr_amaflags2int(v->value); 17267 if (y < 0) 17268 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d.\n", v->value, v->lineno); 17269 else 17270 confp->chan.amaflags = y; 17271 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 17272 confp->chan.polarityonanswerdelay = atoi(v->value); 17273 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 17274 confp->chan.answeronpolarityswitch = ast_true(v->value); 17275 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 17276 confp->chan.hanguponpolarityswitch = ast_true(v->value); 17277 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 17278 confp->chan.sendcalleridafter = atoi(v->value); 17279 } else if (!strcasecmp(v->name, "mwimonitornotify")) { 17280 ast_copy_string(mwimonitornotify, v->value, sizeof(mwimonitornotify)); 17281 } else if (ast_cc_is_config_param(v->name)) { 17282 ast_cc_set_param(confp->chan.cc_params, v->name, v->value); 17283 } else if (!strcasecmp(v->name, "mwisendtype")) { 17284 #ifndef HAVE_DAHDI_LINEREVERSE_VMWI /* backward compatibility for older dahdi VMWI implementation */ 17285 if (!strcasecmp(v->value, "rpas")) { /* Ring Pulse Alert Signal */ 17286 mwisend_rpas = 1; 17287 } else { 17288 mwisend_rpas = 0; 17289 } 17290 #else 17291 /* Default is fsk, to turn it off you must specify nofsk */ 17292 memset(&confp->chan.mwisend_setting, 0, sizeof(confp->chan.mwisend_setting)); 17293 if (strcasestr(v->value, "nofsk")) { /* NoFSK */ 17294 confp->chan.mwisend_fsk = 0; 17295 } else { /* Default FSK */ 17296 confp->chan.mwisend_fsk = 1; 17297 } 17298 if (strcasestr(v->value, "rpas")) { /* Ring Pulse Alert Signal, normally followed by FSK */ 17299 confp->chan.mwisend_rpas = 1; 17300 } else { 17301 confp->chan.mwisend_rpas = 0; 17302 } 17303 if (strcasestr(v->value, "lrev")) { /* Line Reversal */ 17304 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV; 17305 } 17306 if (strcasestr(v->value, "hvdc")) { /* HV 90VDC */ 17307 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC; 17308 } 17309 if ( (strcasestr(v->value, "neon")) || (strcasestr(v->value, "hvac")) ){ /* 90V DC pulses */ 17310 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC; 17311 } 17312 #endif 17313 } else if (reload != 1) { 17314 if (!strcasecmp(v->name, "signalling") || !strcasecmp(v->name, "signaling")) { 17315 int orig_radio = confp->chan.radio; 17316 int orig_outsigmod = confp->chan.outsigmod; 17317 int orig_auto = confp->is_sig_auto; 17318 17319 confp->chan.radio = 0; 17320 confp->chan.outsigmod = -1; 17321 confp->is_sig_auto = 0; 17322 if (!strcasecmp(v->value, "em")) { 17323 confp->chan.sig = SIG_EM; 17324 } else if (!strcasecmp(v->value, "em_e1")) { 17325 confp->chan.sig = SIG_EM_E1; 17326 } else if (!strcasecmp(v->value, "em_w")) { 17327 confp->chan.sig = SIG_EMWINK; 17328 } else if (!strcasecmp(v->value, "fxs_ls")) { 17329 confp->chan.sig = SIG_FXSLS; 17330 } else if (!strcasecmp(v->value, "fxs_gs")) { 17331 confp->chan.sig = SIG_FXSGS; 17332 } else if (!strcasecmp(v->value, "fxs_ks")) { 17333 confp->chan.sig = SIG_FXSKS; 17334 } else if (!strcasecmp(v->value, "fxo_ls")) { 17335 confp->chan.sig = SIG_FXOLS; 17336 } else if (!strcasecmp(v->value, "fxo_gs")) { 17337 confp->chan.sig = SIG_FXOGS; 17338 } else if (!strcasecmp(v->value, "fxo_ks")) { 17339 confp->chan.sig = SIG_FXOKS; 17340 } else if (!strcasecmp(v->value, "fxs_rx")) { 17341 confp->chan.sig = SIG_FXSKS; 17342 confp->chan.radio = 1; 17343 } else if (!strcasecmp(v->value, "fxo_rx")) { 17344 confp->chan.sig = SIG_FXOLS; 17345 confp->chan.radio = 1; 17346 } else if (!strcasecmp(v->value, "fxs_tx")) { 17347 confp->chan.sig = SIG_FXSLS; 17348 confp->chan.radio = 1; 17349 } else if (!strcasecmp(v->value, "fxo_tx")) { 17350 confp->chan.sig = SIG_FXOGS; 17351 confp->chan.radio = 1; 17352 } else if (!strcasecmp(v->value, "em_rx")) { 17353 confp->chan.sig = SIG_EM; 17354 confp->chan.radio = 1; 17355 } else if (!strcasecmp(v->value, "em_tx")) { 17356 confp->chan.sig = SIG_EM; 17357 confp->chan.radio = 1; 17358 } else if (!strcasecmp(v->value, "em_rxtx")) { 17359 confp->chan.sig = SIG_EM; 17360 confp->chan.radio = 2; 17361 } else if (!strcasecmp(v->value, "em_txrx")) { 17362 confp->chan.sig = SIG_EM; 17363 confp->chan.radio = 2; 17364 } else if (!strcasecmp(v->value, "sf")) { 17365 confp->chan.sig = SIG_SF; 17366 } else if (!strcasecmp(v->value, "sf_w")) { 17367 confp->chan.sig = SIG_SFWINK; 17368 } else if (!strcasecmp(v->value, "sf_featd")) { 17369 confp->chan.sig = SIG_FEATD; 17370 } else if (!strcasecmp(v->value, "sf_featdmf")) { 17371 confp->chan.sig = SIG_FEATDMF; 17372 } else if (!strcasecmp(v->value, "sf_featb")) { 17373 confp->chan.sig = SIG_SF_FEATB; 17374 } else if (!strcasecmp(v->value, "sf")) { 17375 confp->chan.sig = SIG_SF; 17376 } else if (!strcasecmp(v->value, "sf_rx")) { 17377 confp->chan.sig = SIG_SF; 17378 confp->chan.radio = 1; 17379 } else if (!strcasecmp(v->value, "sf_tx")) { 17380 confp->chan.sig = SIG_SF; 17381 confp->chan.radio = 1; 17382 } else if (!strcasecmp(v->value, "sf_rxtx")) { 17383 confp->chan.sig = SIG_SF; 17384 confp->chan.radio = 2; 17385 } else if (!strcasecmp(v->value, "sf_txrx")) { 17386 confp->chan.sig = SIG_SF; 17387 confp->chan.radio = 2; 17388 } else if (!strcasecmp(v->value, "featd")) { 17389 confp->chan.sig = SIG_FEATD; 17390 } else if (!strcasecmp(v->value, "featdmf")) { 17391 confp->chan.sig = SIG_FEATDMF; 17392 } else if (!strcasecmp(v->value, "featdmf_ta")) { 17393 confp->chan.sig = SIG_FEATDMF_TA; 17394 } else if (!strcasecmp(v->value, "e911")) { 17395 confp->chan.sig = SIG_E911; 17396 } else if (!strcasecmp(v->value, "fgccama")) { 17397 confp->chan.sig = SIG_FGC_CAMA; 17398 } else if (!strcasecmp(v->value, "fgccamamf")) { 17399 confp->chan.sig = SIG_FGC_CAMAMF; 17400 } else if (!strcasecmp(v->value, "featb")) { 17401 confp->chan.sig = SIG_FEATB; 17402 #ifdef HAVE_PRI 17403 } else if (!strcasecmp(v->value, "pri_net")) { 17404 confp->chan.sig = SIG_PRI; 17405 confp->pri.pri.nodetype = PRI_NETWORK; 17406 } else if (!strcasecmp(v->value, "pri_cpe")) { 17407 confp->chan.sig = SIG_PRI; 17408 confp->pri.pri.nodetype = PRI_CPE; 17409 } else if (!strcasecmp(v->value, "bri_cpe")) { 17410 confp->chan.sig = SIG_BRI; 17411 confp->pri.pri.nodetype = PRI_CPE; 17412 } else if (!strcasecmp(v->value, "bri_net")) { 17413 confp->chan.sig = SIG_BRI; 17414 confp->pri.pri.nodetype = PRI_NETWORK; 17415 } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) { 17416 confp->chan.sig = SIG_BRI_PTMP; 17417 confp->pri.pri.nodetype = PRI_CPE; 17418 } else if (!strcasecmp(v->value, "bri_net_ptmp")) { 17419 #if defined(HAVE_PRI_CALL_HOLD) 17420 confp->chan.sig = SIG_BRI_PTMP; 17421 confp->pri.pri.nodetype = PRI_NETWORK; 17422 #else 17423 ast_log(LOG_WARNING, "How cool would it be if someone implemented this mode! For now, sucks for you. (line %d)\n", v->lineno); 17424 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 17425 #endif 17426 #if defined(HAVE_SS7) 17427 } else if (!strcasecmp(v->value, "ss7")) { 17428 confp->chan.sig = SIG_SS7; 17429 #endif /* defined(HAVE_SS7) */ 17430 #ifdef HAVE_OPENR2 17431 } else if (!strcasecmp(v->value, "mfcr2")) { 17432 confp->chan.sig = SIG_MFCR2; 17433 #endif 17434 } else if (!strcasecmp(v->value, "auto")) { 17435 confp->is_sig_auto = 1; 17436 } else { 17437 confp->chan.outsigmod = orig_outsigmod; 17438 confp->chan.radio = orig_radio; 17439 confp->is_sig_auto = orig_auto; 17440 ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno); 17441 } 17442 } else if (!strcasecmp(v->name, "outsignalling") || !strcasecmp(v->name, "outsignaling")) { 17443 if (!strcasecmp(v->value, "em")) { 17444 confp->chan.outsigmod = SIG_EM; 17445 } else if (!strcasecmp(v->value, "em_e1")) { 17446 confp->chan.outsigmod = SIG_EM_E1; 17447 } else if (!strcasecmp(v->value, "em_w")) { 17448 confp->chan.outsigmod = SIG_EMWINK; 17449 } else if (!strcasecmp(v->value, "sf")) { 17450 confp->chan.outsigmod = SIG_SF; 17451 } else if (!strcasecmp(v->value, "sf_w")) { 17452 confp->chan.outsigmod = SIG_SFWINK; 17453 } else if (!strcasecmp(v->value, "sf_featd")) { 17454 confp->chan.outsigmod = SIG_FEATD; 17455 } else if (!strcasecmp(v->value, "sf_featdmf")) { 17456 confp->chan.outsigmod = SIG_FEATDMF; 17457 } else if (!strcasecmp(v->value, "sf_featb")) { 17458 confp->chan.outsigmod = SIG_SF_FEATB; 17459 } else if (!strcasecmp(v->value, "sf")) { 17460 confp->chan.outsigmod = SIG_SF; 17461 } else if (!strcasecmp(v->value, "featd")) { 17462 confp->chan.outsigmod = SIG_FEATD; 17463 } else if (!strcasecmp(v->value, "featdmf")) { 17464 confp->chan.outsigmod = SIG_FEATDMF; 17465 } else if (!strcasecmp(v->value, "featdmf_ta")) { 17466 confp->chan.outsigmod = SIG_FEATDMF_TA; 17467 } else if (!strcasecmp(v->value, "e911")) { 17468 confp->chan.outsigmod = SIG_E911; 17469 } else if (!strcasecmp(v->value, "fgccama")) { 17470 confp->chan.outsigmod = SIG_FGC_CAMA; 17471 } else if (!strcasecmp(v->value, "fgccamamf")) { 17472 confp->chan.outsigmod = SIG_FGC_CAMAMF; 17473 } else if (!strcasecmp(v->value, "featb")) { 17474 confp->chan.outsigmod = SIG_FEATB; 17475 } else { 17476 ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno); 17477 } 17478 #ifdef HAVE_PRI 17479 } else if (!strcasecmp(v->name, "pridialplan")) { 17480 if (!strcasecmp(v->value, "national")) { 17481 confp->pri.pri.dialplan = PRI_NATIONAL_ISDN + 1; 17482 } else if (!strcasecmp(v->value, "unknown")) { 17483 confp->pri.pri.dialplan = PRI_UNKNOWN + 1; 17484 } else if (!strcasecmp(v->value, "private")) { 17485 confp->pri.pri.dialplan = PRI_PRIVATE + 1; 17486 } else if (!strcasecmp(v->value, "international")) { 17487 confp->pri.pri.dialplan = PRI_INTERNATIONAL_ISDN + 1; 17488 } else if (!strcasecmp(v->value, "local")) { 17489 confp->pri.pri.dialplan = PRI_LOCAL_ISDN + 1; 17490 } else if (!strcasecmp(v->value, "dynamic")) { 17491 confp->pri.pri.dialplan = -1; 17492 } else if (!strcasecmp(v->value, "redundant")) { 17493 confp->pri.pri.dialplan = -2; 17494 } else { 17495 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 17496 } 17497 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 17498 if (!strcasecmp(v->value, "national")) { 17499 confp->pri.pri.localdialplan = PRI_NATIONAL_ISDN + 1; 17500 } else if (!strcasecmp(v->value, "unknown")) { 17501 confp->pri.pri.localdialplan = PRI_UNKNOWN + 1; 17502 } else if (!strcasecmp(v->value, "private")) { 17503 confp->pri.pri.localdialplan = PRI_PRIVATE + 1; 17504 } else if (!strcasecmp(v->value, "international")) { 17505 confp->pri.pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1; 17506 } else if (!strcasecmp(v->value, "local")) { 17507 confp->pri.pri.localdialplan = PRI_LOCAL_ISDN + 1; 17508 } else if (!strcasecmp(v->value, "dynamic")) { 17509 confp->pri.pri.localdialplan = -1; 17510 } else if (!strcasecmp(v->value, "redundant")) { 17511 confp->pri.pri.localdialplan = -2; 17512 } else { 17513 ast_log(LOG_WARNING, "Unknown PRI localdialplan '%s' at line %d.\n", v->value, v->lineno); 17514 } 17515 } else if (!strcasecmp(v->name, "switchtype")) { 17516 if (!strcasecmp(v->value, "national")) 17517 confp->pri.pri.switchtype = PRI_SWITCH_NI2; 17518 else if (!strcasecmp(v->value, "ni1")) 17519 confp->pri.pri.switchtype = PRI_SWITCH_NI1; 17520 else if (!strcasecmp(v->value, "dms100")) 17521 confp->pri.pri.switchtype = PRI_SWITCH_DMS100; 17522 else if (!strcasecmp(v->value, "4ess")) 17523 confp->pri.pri.switchtype = PRI_SWITCH_ATT4ESS; 17524 else if (!strcasecmp(v->value, "5ess")) 17525 confp->pri.pri.switchtype = PRI_SWITCH_LUCENT5E; 17526 else if (!strcasecmp(v->value, "euroisdn")) 17527 confp->pri.pri.switchtype = PRI_SWITCH_EUROISDN_E1; 17528 else if (!strcasecmp(v->value, "qsig")) 17529 confp->pri.pri.switchtype = PRI_SWITCH_QSIG; 17530 else { 17531 ast_log(LOG_ERROR, "Unknown switchtype '%s' at line %d.\n", v->value, v->lineno); 17532 return -1; 17533 } 17534 } else if (!strcasecmp(v->name, "msn")) { 17535 ast_copy_string(confp->pri.pri.msn_list, v->value, 17536 sizeof(confp->pri.pri.msn_list)); 17537 } else if (!strcasecmp(v->name, "nsf")) { 17538 if (!strcasecmp(v->value, "sdn")) 17539 confp->pri.pri.nsf = PRI_NSF_SDN; 17540 else if (!strcasecmp(v->value, "megacom")) 17541 confp->pri.pri.nsf = PRI_NSF_MEGACOM; 17542 else if (!strcasecmp(v->value, "tollfreemegacom")) 17543 confp->pri.pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM; 17544 else if (!strcasecmp(v->value, "accunet")) 17545 confp->pri.pri.nsf = PRI_NSF_ACCUNET; 17546 else if (!strcasecmp(v->value, "none")) 17547 confp->pri.pri.nsf = PRI_NSF_NONE; 17548 else { 17549 ast_log(LOG_WARNING, "Unknown network-specific facility '%s' at line %d.\n", v->value, v->lineno); 17550 confp->pri.pri.nsf = PRI_NSF_NONE; 17551 } 17552 } else if (!strcasecmp(v->name, "priindication")) { 17553 if (!strcasecmp(v->value, "outofband")) 17554 confp->chan.priindication_oob = 1; 17555 else if (!strcasecmp(v->value, "inband")) 17556 confp->chan.priindication_oob = 0; 17557 else 17558 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d.\n", 17559 v->value, v->lineno); 17560 } else if (!strcasecmp(v->name, "priexclusive")) { 17561 confp->chan.priexclusive = ast_true(v->value); 17562 } else if (!strcasecmp(v->name, "internationalprefix")) { 17563 ast_copy_string(confp->pri.pri.internationalprefix, v->value, sizeof(confp->pri.pri.internationalprefix)); 17564 } else if (!strcasecmp(v->name, "nationalprefix")) { 17565 ast_copy_string(confp->pri.pri.nationalprefix, v->value, sizeof(confp->pri.pri.nationalprefix)); 17566 } else if (!strcasecmp(v->name, "localprefix")) { 17567 ast_copy_string(confp->pri.pri.localprefix, v->value, sizeof(confp->pri.pri.localprefix)); 17568 } else if (!strcasecmp(v->name, "privateprefix")) { 17569 ast_copy_string(confp->pri.pri.privateprefix, v->value, sizeof(confp->pri.pri.privateprefix)); 17570 } else if (!strcasecmp(v->name, "unknownprefix")) { 17571 ast_copy_string(confp->pri.pri.unknownprefix, v->value, sizeof(confp->pri.pri.unknownprefix)); 17572 } else if (!strcasecmp(v->name, "resetinterval")) { 17573 if (!strcasecmp(v->value, "never")) 17574 confp->pri.pri.resetinterval = -1; 17575 else if (atoi(v->value) >= 60) 17576 confp->pri.pri.resetinterval = atoi(v->value); 17577 else 17578 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n", 17579 v->value, v->lineno); 17580 } else if (!strcasecmp(v->name, "minunused")) { 17581 confp->pri.pri.minunused = atoi(v->value); 17582 } else if (!strcasecmp(v->name, "minidle")) { 17583 confp->pri.pri.minidle = atoi(v->value); 17584 } else if (!strcasecmp(v->name, "idleext")) { 17585 ast_copy_string(confp->pri.pri.idleext, v->value, sizeof(confp->pri.pri.idleext)); 17586 } else if (!strcasecmp(v->name, "idledial")) { 17587 ast_copy_string(confp->pri.pri.idledial, v->value, sizeof(confp->pri.pri.idledial)); 17588 } else if (!strcasecmp(v->name, "overlapdial")) { 17589 if (ast_true(v->value)) { 17590 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH; 17591 } else if (!strcasecmp(v->value, "incoming")) { 17592 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_INCOMING; 17593 } else if (!strcasecmp(v->value, "outgoing")) { 17594 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_OUTGOING; 17595 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) { 17596 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH; 17597 } else { 17598 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_NONE; 17599 } 17600 #ifdef HAVE_PRI_PROG_W_CAUSE 17601 } else if (!strcasecmp(v->name, "qsigchannelmapping")) { 17602 if (!strcasecmp(v->value, "logical")) { 17603 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_LOGICAL; 17604 } else if (!strcasecmp(v->value, "physical")) { 17605 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL; 17606 } else { 17607 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL; 17608 } 17609 #endif 17610 } else if (!strcasecmp(v->name, "discardremoteholdretrieval")) { 17611 confp->pri.pri.discardremoteholdretrieval = ast_true(v->value); 17612 #if defined(HAVE_PRI_SERVICE_MESSAGES) 17613 } else if (!strcasecmp(v->name, "service_message_support")) { 17614 /* assuming switchtype for this channel group has been configured already */ 17615 if ((confp->pri.pri.switchtype == PRI_SWITCH_ATT4ESS 17616 || confp->pri.pri.switchtype == PRI_SWITCH_LUCENT5E 17617 || confp->pri.pri.switchtype == PRI_SWITCH_NI2) && ast_true(v->value)) { 17618 confp->pri.pri.enable_service_message_support = 1; 17619 } else { 17620 confp->pri.pri.enable_service_message_support = 0; 17621 } 17622 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 17623 #ifdef HAVE_PRI_INBANDDISCONNECT 17624 } else if (!strcasecmp(v->name, "inbanddisconnect")) { 17625 confp->pri.pri.inbanddisconnect = ast_true(v->value); 17626 #endif 17627 } else if (!strcasecmp(v->name, "pritimer")) { 17628 #ifdef PRI_GETSET_TIMERS 17629 char tmp[20]; 17630 char *timerc; 17631 char *c; 17632 int timer; 17633 int timeridx; 17634 17635 ast_copy_string(tmp, v->value, sizeof(tmp)); 17636 c = tmp; 17637 timerc = strsep(&c, ","); 17638 if (!ast_strlen_zero(timerc) && !ast_strlen_zero(c)) { 17639 timeridx = pri_timer2idx(timerc); 17640 timer = atoi(c); 17641 if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) { 17642 ast_log(LOG_WARNING, 17643 "'%s' is not a valid ISDN timer at line %d.\n", timerc, 17644 v->lineno); 17645 } else if (!timer) { 17646 ast_log(LOG_WARNING, 17647 "'%s' is not a valid value for ISDN timer '%s' at line %d.\n", 17648 c, timerc, v->lineno); 17649 } else { 17650 confp->pri.pri.pritimers[timeridx] = timer; 17651 } 17652 } else { 17653 ast_log(LOG_WARNING, 17654 "'%s' is not a valid ISDN timer configuration string at line %d.\n", 17655 v->value, v->lineno); 17656 } 17657 #endif /* PRI_GETSET_TIMERS */ 17658 } else if (!strcasecmp(v->name, "facilityenable")) { 17659 confp->pri.pri.facilityenable = ast_true(v->value); 17660 #if defined(HAVE_PRI_AOC_EVENTS) 17661 } else if (!strcasecmp(v->name, "aoc_enable")) { 17662 confp->pri.pri.aoc_passthrough_flag = 0; 17663 if (strchr(v->value, 's') || strchr(v->value, 'S')) { 17664 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_S; 17665 } 17666 if (strchr(v->value, 'd') || strchr(v->value, 'D')) { 17667 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_D; 17668 } 17669 if (strchr(v->value, 'e') || strchr(v->value, 'E')) { 17670 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_E; 17671 } 17672 } else if (!strcasecmp(v->name, "aoce_delayhangup")) { 17673 confp->pri.pri.aoce_delayhangup = ast_true(v->value); 17674 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 17675 #if defined(HAVE_PRI_CALL_HOLD) 17676 } else if (!strcasecmp(v->name, "hold_disconnect_transfer")) { 17677 confp->pri.pri.hold_disconnect_transfer = ast_true(v->value); 17678 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 17679 #if defined(HAVE_PRI_CCSS) 17680 } else if (!strcasecmp(v->name, "cc_ptmp_recall_mode")) { 17681 if (!strcasecmp(v->value, "global")) { 17682 confp->pri.pri.cc_ptmp_recall_mode = 0;/* globalRecall */ 17683 } else if (!strcasecmp(v->value, "specific")) { 17684 confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */ 17685 } else { 17686 confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */ 17687 } 17688 } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_req")) { 17689 if (!strcasecmp(v->value, "release")) { 17690 confp->pri.pri.cc_qsig_signaling_link_req = 0;/* release */ 17691 } else if (!strcasecmp(v->value, "retain")) { 17692 confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */ 17693 } else if (!strcasecmp(v->value, "do_not_care")) { 17694 confp->pri.pri.cc_qsig_signaling_link_req = 2;/* do-not-care */ 17695 } else { 17696 confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */ 17697 } 17698 } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_rsp")) { 17699 if (!strcasecmp(v->value, "release")) { 17700 confp->pri.pri.cc_qsig_signaling_link_rsp = 0;/* release */ 17701 } else if (!strcasecmp(v->value, "retain")) { 17702 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */ 17703 } else { 17704 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */ 17705 } 17706 #endif /* defined(HAVE_PRI_CCSS) */ 17707 #if defined(HAVE_PRI_CALL_WAITING) 17708 } else if (!strcasecmp(v->name, "max_call_waiting_calls")) { 17709 confp->pri.pri.max_call_waiting_calls = atoi(v->value); 17710 if (confp->pri.pri.max_call_waiting_calls < 0) { 17711 /* Negative values are not allowed. */ 17712 confp->pri.pri.max_call_waiting_calls = 0; 17713 } 17714 } else if (!strcasecmp(v->name, "allow_call_waiting_calls")) { 17715 confp->pri.pri.allow_call_waiting_calls = ast_true(v->value); 17716 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 17717 #if defined(HAVE_PRI_MWI) 17718 } else if (!strcasecmp(v->name, "mwi_mailboxes")) { 17719 ast_copy_string(confp->pri.pri.mwi_mailboxes, v->value, 17720 sizeof(confp->pri.pri.mwi_mailboxes)); 17721 #endif /* defined(HAVE_PRI_MWI) */ 17722 } else if (!strcasecmp(v->name, "append_msn_to_cid_tag")) { 17723 confp->pri.pri.append_msn_to_user_tag = ast_true(v->value); 17724 } else if (!strcasecmp(v->name, "inband_on_proceeding")) { 17725 confp->pri.pri.inband_on_proceeding = ast_true(v->value); 17726 } else if (!strcasecmp(v->name, "layer1_presence")) { 17727 if (!strcasecmp(v->value, "required")) { 17728 confp->pri.pri.layer1_ignored = 0; 17729 } else if (!strcasecmp(v->value, "ignore")) { 17730 confp->pri.pri.layer1_ignored = 1; 17731 } else { 17732 /* Default */ 17733 confp->pri.pri.layer1_ignored = 0; 17734 } 17735 #if defined(HAVE_PRI_L2_PERSISTENCE) 17736 } else if (!strcasecmp(v->name, "layer2_persistence")) { 17737 if (!strcasecmp(v->value, "keep_up")) { 17738 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_KEEP_UP; 17739 } else if (!strcasecmp(v->value, "leave_down")) { 17740 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_LEAVE_DOWN; 17741 } else { 17742 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_DEFAULT; 17743 } 17744 #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */ 17745 #endif /* HAVE_PRI */ 17746 #if defined(HAVE_SS7) 17747 } else if (!strcasecmp(v->name, "ss7type")) { 17748 if (!strcasecmp(v->value, "itu")) { 17749 cur_ss7type = SS7_ITU; 17750 } else if (!strcasecmp(v->value, "ansi")) { 17751 cur_ss7type = SS7_ANSI; 17752 } else 17753 ast_log(LOG_WARNING, "'%s' is an unknown ss7 switch type at line %d.!\n", v->value, v->lineno); 17754 } else if (!strcasecmp(v->name, "linkset")) { 17755 cur_linkset = atoi(v->value); 17756 } else if (!strcasecmp(v->name, "pointcode")) { 17757 cur_pointcode = parse_pointcode(v->value); 17758 } else if (!strcasecmp(v->name, "adjpointcode")) { 17759 cur_adjpointcode = parse_pointcode(v->value); 17760 } else if (!strcasecmp(v->name, "defaultdpc")) { 17761 cur_defaultdpc = parse_pointcode(v->value); 17762 } else if (!strcasecmp(v->name, "cicbeginswith")) { 17763 cur_cicbeginswith = atoi(v->value); 17764 } else if (!strcasecmp(v->name, "networkindicator")) { 17765 if (!strcasecmp(v->value, "national")) 17766 cur_networkindicator = SS7_NI_NAT; 17767 else if (!strcasecmp(v->value, "national_spare")) 17768 cur_networkindicator = SS7_NI_NAT_SPARE; 17769 else if (!strcasecmp(v->value, "international")) 17770 cur_networkindicator = SS7_NI_INT; 17771 else if (!strcasecmp(v->value, "international_spare")) 17772 cur_networkindicator = SS7_NI_INT_SPARE; 17773 else 17774 cur_networkindicator = -1; 17775 } else if (!strcasecmp(v->name, "ss7_internationalprefix")) { 17776 ast_copy_string(confp->ss7.ss7.internationalprefix, v->value, sizeof(confp->ss7.ss7.internationalprefix)); 17777 } else if (!strcasecmp(v->name, "ss7_nationalprefix")) { 17778 ast_copy_string(confp->ss7.ss7.nationalprefix, v->value, sizeof(confp->ss7.ss7.nationalprefix)); 17779 } else if (!strcasecmp(v->name, "ss7_subscriberprefix")) { 17780 ast_copy_string(confp->ss7.ss7.subscriberprefix, v->value, sizeof(confp->ss7.ss7.subscriberprefix)); 17781 } else if (!strcasecmp(v->name, "ss7_unknownprefix")) { 17782 ast_copy_string(confp->ss7.ss7.unknownprefix, v->value, sizeof(confp->ss7.ss7.unknownprefix)); 17783 } else if (!strcasecmp(v->name, "ss7_called_nai")) { 17784 if (!strcasecmp(v->value, "national")) { 17785 confp->ss7.ss7.called_nai = SS7_NAI_NATIONAL; 17786 } else if (!strcasecmp(v->value, "international")) { 17787 confp->ss7.ss7.called_nai = SS7_NAI_INTERNATIONAL; 17788 } else if (!strcasecmp(v->value, "subscriber")) { 17789 confp->ss7.ss7.called_nai = SS7_NAI_SUBSCRIBER; 17790 } else if (!strcasecmp(v->value, "unknown")) { 17791 confp->ss7.ss7.called_nai = SS7_NAI_UNKNOWN; 17792 } else if (!strcasecmp(v->value, "dynamic")) { 17793 confp->ss7.ss7.called_nai = SS7_NAI_DYNAMIC; 17794 } else { 17795 ast_log(LOG_WARNING, "Unknown SS7 called_nai '%s' at line %d.\n", v->value, v->lineno); 17796 } 17797 } else if (!strcasecmp(v->name, "ss7_calling_nai")) { 17798 if (!strcasecmp(v->value, "national")) { 17799 confp->ss7.ss7.calling_nai = SS7_NAI_NATIONAL; 17800 } else if (!strcasecmp(v->value, "international")) { 17801 confp->ss7.ss7.calling_nai = SS7_NAI_INTERNATIONAL; 17802 } else if (!strcasecmp(v->value, "subscriber")) { 17803 confp->ss7.ss7.calling_nai = SS7_NAI_SUBSCRIBER; 17804 } else if (!strcasecmp(v->value, "unknown")) { 17805 confp->ss7.ss7.calling_nai = SS7_NAI_UNKNOWN; 17806 } else if (!strcasecmp(v->value, "dynamic")) { 17807 confp->ss7.ss7.calling_nai = SS7_NAI_DYNAMIC; 17808 } else { 17809 ast_log(LOG_WARNING, "Unknown SS7 calling_nai '%s' at line %d.\n", v->value, v->lineno); 17810 } 17811 } else if (!strcasecmp(v->name, "sigchan")) { 17812 int sigchan, res; 17813 sigchan = atoi(v->value); 17814 res = linkset_addsigchan(sigchan); 17815 if (res < 0) 17816 return -1; 17817 17818 } else if (!strcasecmp(v->name, "ss7_explicitacm")) { 17819 struct dahdi_ss7 *link; 17820 link = ss7_resolve_linkset(cur_linkset); 17821 if (!link) { 17822 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1); 17823 return -1; 17824 } 17825 if (ast_true(v->value)) 17826 link->ss7.flags |= LINKSET_FLAG_EXPLICITACM; 17827 #endif /* defined(HAVE_SS7) */ 17828 #ifdef HAVE_OPENR2 17829 } else if (!strcasecmp(v->name, "mfcr2_advanced_protocol_file")) { 17830 ast_copy_string(confp->mfcr2.r2proto_file, v->value, sizeof(confp->mfcr2.r2proto_file)); 17831 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); 17832 } else if (!strcasecmp(v->name, "mfcr2_logdir")) { 17833 ast_copy_string(confp->mfcr2.logdir, v->value, sizeof(confp->mfcr2.logdir)); 17834 } else if (!strcasecmp(v->name, "mfcr2_variant")) { 17835 confp->mfcr2.variant = openr2_proto_get_variant(v->value); 17836 if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) { 17837 ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d, defaulting to ITU.\n", v->value, v->lineno); 17838 confp->mfcr2.variant = OR2_VAR_ITU; 17839 } 17840 } else if (!strcasecmp(v->name, "mfcr2_mfback_timeout")) { 17841 confp->mfcr2.mfback_timeout = atoi(v->value); 17842 if (!confp->mfcr2.mfback_timeout) { 17843 ast_log(LOG_WARNING, "MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n"); 17844 confp->mfcr2.mfback_timeout = -1; 17845 } else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) { 17846 ast_log(LOG_WARNING, "MF timeout less than 500ms is not recommended, you have been warned!\n"); 17847 } 17848 } else if (!strcasecmp(v->name, "mfcr2_metering_pulse_timeout")) { 17849 confp->mfcr2.metering_pulse_timeout = atoi(v->value); 17850 if (confp->mfcr2.metering_pulse_timeout > 500) { 17851 ast_log(LOG_WARNING, "Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n"); 17852 } 17853 } else if (!strcasecmp(v->name, "mfcr2_get_ani_first")) { 17854 confp->mfcr2.get_ani_first = ast_true(v->value) ? 1 : 0; 17855 } else if (!strcasecmp(v->name, "mfcr2_double_answer")) { 17856 confp->mfcr2.double_answer = ast_true(v->value) ? 1 : 0; 17857 } else if (!strcasecmp(v->name, "mfcr2_charge_calls")) { 17858 confp->mfcr2.charge_calls = ast_true(v->value) ? 1 : 0; 17859 } else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) { 17860 confp->mfcr2.accept_on_offer = ast_true(v->value) ? 1 : 0; 17861 } else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) { 17862 confp->mfcr2.allow_collect_calls = ast_true(v->value) ? 1 : 0; 17863 } else if (!strcasecmp(v->name, "mfcr2_forced_release")) { 17864 confp->mfcr2.forced_release = ast_true(v->value) ? 1 : 0; 17865 } else if (!strcasecmp(v->name, "mfcr2_immediate_accept")) { 17866 confp->mfcr2.immediate_accept = ast_true(v->value) ? 1 : 0; 17867 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 17868 } else if (!strcasecmp(v->name, "mfcr2_skip_category")) { 17869 confp->mfcr2.skip_category_request = ast_true(v->value) ? 1 : 0; 17870 #endif 17871 } else if (!strcasecmp(v->name, "mfcr2_call_files")) { 17872 confp->mfcr2.call_files = ast_true(v->value) ? 1 : 0; 17873 } else if (!strcasecmp(v->name, "mfcr2_max_ani")) { 17874 confp->mfcr2.max_ani = atoi(v->value); 17875 if (confp->mfcr2.max_ani >= AST_MAX_EXTENSION){ 17876 confp->mfcr2.max_ani = AST_MAX_EXTENSION - 1; 17877 } 17878 } else if (!strcasecmp(v->name, "mfcr2_max_dnis")) { 17879 confp->mfcr2.max_dnis = atoi(v->value); 17880 if (confp->mfcr2.max_dnis >= AST_MAX_EXTENSION){ 17881 confp->mfcr2.max_dnis = AST_MAX_EXTENSION - 1; 17882 } 17883 } else if (!strcasecmp(v->name, "mfcr2_category")) { 17884 confp->mfcr2.category = openr2_proto_get_category(v->value); 17885 if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) { 17886 confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER; 17887 ast_log(LOG_WARNING, "Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n", 17888 v->value, v->lineno); 17889 } 17890 } else if (!strcasecmp(v->name, "mfcr2_logging")) { 17891 openr2_log_level_t tmplevel; 17892 char *clevel; 17893 char *logval = ast_strdupa(v->value); 17894 while (logval) { 17895 clevel = strsep(&logval,","); 17896 if (-1 == (tmplevel = openr2_log_get_level(clevel))) { 17897 ast_log(LOG_WARNING, "Ignoring invalid logging level: '%s' at line %d.\n", clevel, v->lineno); 17898 continue; 17899 } 17900 confp->mfcr2.loglevel |= tmplevel; 17901 } 17902 #endif /* HAVE_OPENR2 */ 17903 } else if (!strcasecmp(v->name, "cadence")) { 17904 /* setup to scan our argument */ 17905 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 17906 int i; 17907 struct dahdi_ring_cadence new_cadence; 17908 int cid_location = -1; 17909 int firstcadencepos = 0; 17910 char original_args[80]; 17911 int cadence_is_ok = 1; 17912 17913 ast_copy_string(original_args, v->value, sizeof(original_args)); 17914 /* 16 cadences allowed (8 pairs) */ 17915 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]); 17916 17917 /* Cadence must be even (on/off) */ 17918 if (element_count % 2 == 1) { 17919 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s at line %d.\n", original_args, v->lineno); 17920 cadence_is_ok = 0; 17921 } 17922 17923 /* Ring cadences cannot be negative */ 17924 for (i = 0; i < element_count; i++) { 17925 if (c[i] == 0) { 17926 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s at line %d.\n", original_args, v->lineno); 17927 cadence_is_ok = 0; 17928 break; 17929 } else if (c[i] < 0) { 17930 if (i % 2 == 1) { 17931 /* Silence duration, negative possibly okay */ 17932 if (cid_location == -1) { 17933 cid_location = i; 17934 c[i] *= -1; 17935 } else { 17936 ast_log(LOG_ERROR, "CID location specified twice: %s at line %d.\n", original_args, v->lineno); 17937 cadence_is_ok = 0; 17938 break; 17939 } 17940 } else { 17941 if (firstcadencepos == 0) { 17942 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 17943 /* duration will be passed negative to the DAHDI driver */ 17944 } else { 17945 ast_log(LOG_ERROR, "First cadence position specified twice: %s at line %d.\n", original_args, v->lineno); 17946 cadence_is_ok = 0; 17947 break; 17948 } 17949 } 17950 } 17951 } 17952 17953 /* Substitute our scanned cadence */ 17954 for (i = 0; i < 16; i++) { 17955 new_cadence.ringcadence[i] = c[i]; 17956 } 17957 17958 if (cadence_is_ok) { 17959 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 17960 if (element_count < 2) { 17961 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s at line %d.\n", original_args, v->lineno); 17962 } else { 17963 if (cid_location == -1) { 17964 /* user didn't say; default to first pause */ 17965 cid_location = 1; 17966 } else { 17967 /* convert element_index to cidrings value */ 17968 cid_location = (cid_location + 1) / 2; 17969 } 17970 /* ---we like their cadence; try to install it--- */ 17971 if (!user_has_defined_cadences++) 17972 /* this is the first user-defined cadence; clear the default user cadences */ 17973 num_cadence = 0; 17974 if ((num_cadence+1) >= NUM_CADENCE_MAX) 17975 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s at line %d.\n", NUM_CADENCE_MAX, original_args, v->lineno); 17976 else { 17977 cadences[num_cadence] = new_cadence; 17978 cidrings[num_cadence++] = cid_location; 17979 ast_verb(3, "cadence 'r%d' added: %s\n",num_cadence,original_args); 17980 } 17981 } 17982 } 17983 } else if (!strcasecmp(v->name, "ringtimeout")) { 17984 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 17985 } else if (!strcasecmp(v->name, "prewink")) { 17986 confp->timing.prewinktime = atoi(v->value); 17987 } else if (!strcasecmp(v->name, "preflash")) { 17988 confp->timing.preflashtime = atoi(v->value); 17989 } else if (!strcasecmp(v->name, "wink")) { 17990 confp->timing.winktime = atoi(v->value); 17991 } else if (!strcasecmp(v->name, "flash")) { 17992 confp->timing.flashtime = atoi(v->value); 17993 } else if (!strcasecmp(v->name, "start")) { 17994 confp->timing.starttime = atoi(v->value); 17995 } else if (!strcasecmp(v->name, "rxwink")) { 17996 confp->timing.rxwinktime = atoi(v->value); 17997 } else if (!strcasecmp(v->name, "rxflash")) { 17998 confp->timing.rxflashtime = atoi(v->value); 17999 } else if (!strcasecmp(v->name, "debounce")) { 18000 confp->timing.debouncetime = atoi(v->value); 18001 } else if (!strcasecmp(v->name, "toneduration")) { 18002 int toneduration; 18003 int ctlfd; 18004 int res; 18005 struct dahdi_dialparams dps; 18006 18007 ctlfd = open("/dev/dahdi/ctl", O_RDWR); 18008 if (ctlfd == -1) { 18009 ast_log(LOG_ERROR, "Unable to open /dev/dahdi/ctl to set toneduration at line %d.\n", v->lineno); 18010 return -1; 18011 } 18012 18013 toneduration = atoi(v->value); 18014 if (toneduration > -1) { 18015 memset(&dps, 0, sizeof(dps)); 18016 18017 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 18018 res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps); 18019 if (res < 0) { 18020 ast_log(LOG_ERROR, "Invalid tone duration: %d ms at line %d: %s\n", toneduration, v->lineno, strerror(errno)); 18021 close(ctlfd); 18022 return -1; 18023 } 18024 } 18025 close(ctlfd); 18026 } else if (!strcasecmp(v->name, "defaultcic")) { 18027 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 18028 } else if (!strcasecmp(v->name, "defaultozz")) { 18029 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 18030 } else if (!strcasecmp(v->name, "mwilevel")) { 18031 mwilevel = atoi(v->value); 18032 } else if (!strcasecmp(v->name, "dtmfcidlevel")) { 18033 dtmfcid_level = atoi(v->value); 18034 } else if (!strcasecmp(v->name, "reportalarms")) { 18035 if (!strcasecmp(v->value, "all")) 18036 report_alarms = REPORT_CHANNEL_ALARMS | REPORT_SPAN_ALARMS; 18037 if (!strcasecmp(v->value, "none")) 18038 report_alarms = 0; 18039 else if (!strcasecmp(v->value, "channels")) 18040 report_alarms = REPORT_CHANNEL_ALARMS; 18041 else if (!strcasecmp(v->value, "spans")) 18042 report_alarms = REPORT_SPAN_ALARMS; 18043 } 18044 } else if (!(options & PROC_DAHDI_OPT_NOWARN) ) 18045 ast_log(LOG_WARNING, "Ignoring any changes to '%s' (on reload) at line %d.\n", v->name, v->lineno); 18046 } 18047 18048 /* Since confp has already filled invidual dahdi_pvt objects with channels at this point, clear the variables in confp's pvt. */ 18049 if (confp->chan.vars) { 18050 ast_variables_destroy(confp->chan.vars); 18051 confp->chan.vars = NULL; 18052 } 18053 18054 if (dahdichan) { 18055 /* Process the deferred dahdichan value. */ 18056 if (build_channels(confp, dahdichan->value, reload, dahdichan->lineno, 18057 &found_pseudo)) { 18058 if (confp->ignore_failed_channels) { 18059 ast_log(LOG_WARNING, 18060 "Dahdichan '%s' failure ignored: ignore_failed_channels.\n", 18061 dahdichan->value); 18062 } else { 18063 return -1; 18064 } 18065 } 18066 } 18067 18068 /* mark the first channels of each DAHDI span to watch for their span alarms */ 18069 for (tmp = iflist, y=-1; tmp; tmp = tmp->next) { 18070 if (!tmp->destroy && tmp->span != y) { 18071 tmp->manages_span_alarms = 1; 18072 y = tmp->span; 18073 } else { 18074 tmp->manages_span_alarms = 0; 18075 } 18076 } 18077 18078 /*< \todo why check for the pseudo in the per-channel section. 18079 * Any actual use for manual setup of the pseudo channel? */ 18080 if (!found_pseudo && reload != 1 && !(options & PROC_DAHDI_OPT_NOCHAN)) { 18081 /* use the default configuration for a channel, so 18082 that any settings from real configured channels 18083 don't "leak" into the pseudo channel config 18084 */ 18085 struct dahdi_chan_conf conf = dahdi_chan_conf_default(); 18086 18087 if (conf.chan.cc_params) { 18088 tmp = mkintf(CHAN_PSEUDO, &conf, reload); 18089 } else { 18090 tmp = NULL; 18091 } 18092 if (tmp) { 18093 ast_verb(3, "Automatically generated pseudo channel\n"); 18094 } else { 18095 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 18096 } 18097 ast_cc_config_params_destroy(conf.chan.cc_params); 18098 } 18099 return 0; 18100 }
| static void process_echocancel | ( | struct dahdi_chan_conf * | confp, | |
| const char * | data, | |||
| unsigned int | line | |||
| ) | [static] |
Definition at line 16940 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, LOG_WARNING, name, dahdi_pvt::params, and value.
Referenced by process_dahdi().
16941 { 16942 char *parse = ast_strdupa(data); 16943 char *params[DAHDI_MAX_ECHOCANPARAMS + 1]; 16944 unsigned int param_count; 16945 unsigned int x; 16946 16947 if (!(param_count = ast_app_separate_args(parse, ',', params, ARRAY_LEN(params)))) 16948 return; 16949 16950 memset(&confp->chan.echocancel, 0, sizeof(confp->chan.echocancel)); 16951 16952 /* first parameter is tap length, process it here */ 16953 16954 x = ast_strlen_zero(params[0]) ? 0 : atoi(params[0]); 16955 16956 if ((x == 32) || (x == 64) || (x == 128) || (x == 256) || (x == 512) || (x == 1024)) 16957 confp->chan.echocancel.head.tap_length = x; 16958 else if ((confp->chan.echocancel.head.tap_length = ast_true(params[0]))) 16959 confp->chan.echocancel.head.tap_length = 128; 16960 16961 /* now process any remaining parameters */ 16962 16963 for (x = 1; x < param_count; x++) { 16964 struct { 16965 char *name; 16966 char *value; 16967 } param; 16968 16969 if (ast_app_separate_args(params[x], '=', (char **) ¶m, 2) < 1) { 16970 ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %d: '%s'\n", line, params[x]); 16971 continue; 16972 } 16973 16974 if (ast_strlen_zero(param.name) || (strlen(param.name) > sizeof(confp->chan.echocancel.params[0].name)-1)) { 16975 ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %d: '%s'\n", line, param.name); 16976 continue; 16977 } 16978 16979 strcpy(confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].name, param.name); 16980 16981 if (param.value) { 16982 if (sscanf(param.value, "%30d", &confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].value) != 1) { 16983 ast_log(LOG_WARNING, "Invalid echocancel parameter value supplied at line %d: '%s'\n", line, param.value); 16984 continue; 16985 } 16986 } 16987 confp->chan.echocancel.head.param_count++; 16988 } 16989 }
| static int reload | ( | void | ) | [static] |
Definition at line 18778 of file chan_dahdi.c.
References ast_log(), LOG_WARNING, and setup_dahdi().
18779 { 18780 int res = 0; 18781 18782 res = setup_dahdi(1); 18783 if (res) { 18784 ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n"); 18785 return -1; 18786 } 18787 return 0; 18788 }
| static int reset_conf | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4820 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, dahdi_pvt::confno, dahdi_subchannel::curconf, dahdi_subchannel::dfd, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_hangup(), and my_all_subchannels_hungup().
04821 { 04822 p->confno = -1; 04823 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf)); 04824 if (p->subs[SUB_REAL].dfd > -1) { 04825 struct dahdi_confinfo zi; 04826 04827 memset(&zi, 0, sizeof(zi)); 04828 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi)) 04829 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno)); 04830 } 04831 return 0; 04832 }
| static int restart_monitor | ( | void | ) | [static] |
Definition at line 11999 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, and LOG_WARNING.
Referenced by dahdi_hangup(), dahdi_request(), my_all_subchannels_hungup(), and setup_dahdi_int().
12000 { 12001 /* If we're supposed to be stopped -- stay stopped */ 12002 if (monitor_thread == AST_PTHREADT_STOP) 12003 return 0; 12004 ast_mutex_lock(&monlock); 12005 if (monitor_thread == pthread_self()) { 12006 ast_mutex_unlock(&monlock); 12007 ast_log(LOG_WARNING, "Cannot kill myself\n"); 12008 return -1; 12009 } 12010 if (monitor_thread != AST_PTHREADT_NULL) { 12011 /* Wake up the thread */ 12012 pthread_kill(monitor_thread, SIGURG); 12013 } else { 12014 /* Start a new monitor */ 12015 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 12016 ast_mutex_unlock(&monlock); 12017 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 12018 return -1; 12019 } 12020 } 12021 ast_mutex_unlock(&monlock); 12022 return 0; 12023 }
| static int restore_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5245 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_subchannel::dfd, 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().
05246 { 05247 int res; 05248 if (p->saveconf.confmode) { 05249 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf); 05250 p->saveconf.confmode = 0; 05251 if (res) { 05252 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno)); 05253 return -1; 05254 } 05255 ast_debug(1, "Restored conferencing\n"); 05256 } 05257 return 0; 05258 }
| static int restore_gains | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5152 of file chan_dahdi.c.
References ast_log(), dahdi_subchannel::dfd, 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(), mwi_thread(), and my_distinctive_ring().
| static int revert_fax_buffers | ( | struct dahdi_pvt * | p, | |
| struct ast_channel * | ast | |||
| ) | [static] |
Definition at line 6143 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::buf_no, dahdi_pvt::buf_policy, dahdi_pvt::bufferoverrideinuse, dahdi_pvt::bufsize, dahdi_subchannel::dfd, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_hangup().
06144 { 06145 if (p->bufferoverrideinuse) { 06146 /* faxbuffers are in use, revert them */ 06147 struct dahdi_bufferinfo bi = { 06148 .txbufpolicy = p->buf_policy, 06149 .rxbufpolicy = p->buf_policy, 06150 .bufsize = p->bufsize, 06151 .numbufs = p->buf_no 06152 }; 06153 int bpres; 06154 06155 if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 06156 ast_log(LOG_WARNING, "Channel '%s' unable to revert buffer policy: %s\n", ast->name, strerror(errno)); 06157 } 06158 p->bufferoverrideinuse = 0; 06159 return bpres; 06160 } 06161 06162 return -1; 06163 }
| static int save_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5219 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_subchannel::dfd, errno, LOG_WARNING, dahdi_pvt::saveconf, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_callwait(), dahdi_handle_event(), and my_callwait().
05220 { 05221 struct dahdi_confinfo c; 05222 int res; 05223 if (p->saveconf.confmode) { 05224 ast_log(LOG_WARNING, "Can't save conference -- already in use\n"); 05225 return -1; 05226 } 05227 p->saveconf.chan = 0; 05228 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf); 05229 if (res) { 05230 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno)); 05231 p->saveconf.confmode = 0; 05232 return -1; 05233 } 05234 memset(&c, 0, sizeof(c)); 05235 c.confmode = DAHDI_CONF_NORMAL; 05236 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c); 05237 if (res) { 05238 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno)); 05239 return -1; 05240 } 05241 ast_debug(1, "Disabled conferencing\n"); 05242 return 0; 05243 }
| static int send_callerid | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5303 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(), dahdi_subchannel::dfd, 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().
05304 { 05305 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */ 05306 int res; 05307 /* Take out of linear mode if necessary */ 05308 if (p->subs[SUB_REAL].linear) { 05309 p->subs[SUB_REAL].linear = 0; 05310 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 05311 } 05312 while (p->cidpos < p->cidlen) { 05313 res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos); 05314 ast_debug(4, "writing callerid at pos %d of %d, res = %d\n", p->cidpos, p->cidlen, res); 05315 if (res < 0) { 05316 if (errno == EAGAIN) 05317 return 0; 05318 else { 05319 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 05320 return -1; 05321 } 05322 } 05323 if (!res) 05324 return 0; 05325 p->cidpos += res; 05326 } 05327 p->cid_suppress_expire = CALLWAITING_SUPPRESS_SAMPLES; 05328 ast_free(p->cidspill); 05329 p->cidspill = NULL; 05330 if (p->callwaitcas) { 05331 /* Wait for CID/CW to expire */ 05332 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES; 05333 p->cid_suppress_expire = p->cidcwexpire; 05334 } else 05335 restore_conference(p); 05336 return 0; 05337 }
| static int send_cwcidspill | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5260 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().
05261 { 05262 p->callwaitcas = 0; 05263 p->cidcwexpire = 0; 05264 p->cid_suppress_expire = 0; 05265 if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) 05266 return -1; 05267 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p)); 05268 /* Make sure we account for the end */ 05269 p->cidlen += READ_SIZE * 4; 05270 p->cidpos = 0; 05271 send_callerid(p); 05272 ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num); 05273 return 0; 05274 }
| static int set_actual_gain | ( | int | fd, | |
| float | rxgain, | |||
| float | txgain, | |||
| float | rxdrc, | |||
| float | txdrc, | |||
| int | law | |||
| ) | [static] |
Definition at line 5133 of file chan_dahdi.c.
References set_actual_rxgain(), and set_actual_txgain().
Referenced by bump_gains(), dahdi_call(), mkintf(), and restore_gains().
05134 { 05135 return set_actual_txgain(fd, txgain, txdrc, law) | set_actual_rxgain(fd, rxgain, rxdrc, law); 05136 }
| static int set_actual_rxgain | ( | int | fd, | |
| float | gain, | |||
| float | drc, | |||
| int | law | |||
| ) | [static] |
Definition at line 5116 of file chan_dahdi.c.
References ast_debug, errno, and fill_rxgain().
Referenced by dahdi_set_swgain(), dahdi_setoption(), and set_actual_gain().
05117 { 05118 struct dahdi_gains g; 05119 int res; 05120 05121 memset(&g, 0, sizeof(g)); 05122 res = ioctl(fd, DAHDI_GETGAINS, &g); 05123 if (res) { 05124 ast_debug(1, "Failed to read gains: %s\n", strerror(errno)); 05125 return res; 05126 } 05127 05128 fill_rxgain(&g, gain, drc, law); 05129 05130 return ioctl(fd, DAHDI_SETGAINS, &g); 05131 }
| static int set_actual_txgain | ( | int | fd, | |
| float | gain, | |||
| float | drc, | |||
| int | law | |||
| ) | [static] |
Definition at line 5099 of file chan_dahdi.c.
References ast_debug, errno, and fill_txgain().
Referenced by dahdi_set_swgain(), dahdi_setoption(), and set_actual_gain().
05100 { 05101 struct dahdi_gains g; 05102 int res; 05103 05104 memset(&g, 0, sizeof(g)); 05105 res = ioctl(fd, DAHDI_GETGAINS, &g); 05106 if (res) { 05107 ast_debug(1, "Failed to read gains: %s\n", strerror(errno)); 05108 return res; 05109 } 05110 05111 fill_txgain(&g, gain, drc, law); 05112 05113 return ioctl(fd, DAHDI_SETGAINS, &g); 05114 }
| static int setup_dahdi | ( | int | reload | ) | [static] |
Definition at line 18421 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 dahdi_restart(), load_module(), and reload().
18422 { 18423 int res; 18424 struct dahdi_chan_conf default_conf = dahdi_chan_conf_default(); 18425 struct dahdi_chan_conf base_conf = dahdi_chan_conf_default(); 18426 struct dahdi_chan_conf conf = dahdi_chan_conf_default(); 18427 18428 if (default_conf.chan.cc_params && base_conf.chan.cc_params && conf.chan.cc_params) { 18429 res = setup_dahdi_int(reload, &default_conf, &base_conf, &conf); 18430 } else { 18431 res = -1; 18432 } 18433 ast_cc_config_params_destroy(default_conf.chan.cc_params); 18434 ast_cc_config_params_destroy(base_conf.chan.cc_params); 18435 ast_cc_config_params_destroy(conf.chan.cc_params); 18436 18437 return res; 18438 }
| 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 18134 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_pthread_create, ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, deep_copy_dahdi_chan_conf(), global_jbconf, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sig_ss7_linkset::master, ast_variable::name, ast_variable::next, PROC_DAHDI_OPT_NOCHAN, PROC_DAHDI_OPT_NOWARN, process_dahdi(), restart_monitor(), sig_pri_start_pri(), sig_ss7_linkset::ss7, ss7_linkset(), and ast_variable::value.
Referenced by setup_dahdi().
18135 { 18136 struct ast_config *cfg; 18137 struct ast_config *ucfg; 18138 struct ast_variable *v; 18139 struct ast_flags config_flags = { reload == 1 ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 18140 const char *chans; 18141 const char *cat; 18142 int res; 18143 18144 #ifdef HAVE_PRI 18145 char *c; 18146 int spanno; 18147 int i; 18148 int logicalspan; 18149 int trunkgroup; 18150 int dchannels[SIG_PRI_NUM_DCHANS]; 18151 #endif 18152 int have_cfg_now; 18153 static int had_cfg_before = 1;/* So initial load will complain if we don't have cfg. */ 18154 18155 cfg = ast_config_load(config, config_flags); 18156 have_cfg_now = !!cfg; 18157 if (!cfg) { 18158 /* Error if we have no config file */ 18159 if (had_cfg_before) { 18160 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 18161 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 18162 } 18163 cfg = ast_config_new();/* Dummy config */ 18164 if (!cfg) { 18165 return 0; 18166 } 18167 ucfg = ast_config_load("users.conf", config_flags); 18168 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 18169 ast_config_destroy(cfg); 18170 return 0; 18171 } 18172 if (ucfg == CONFIG_STATUS_FILEINVALID) { 18173 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n"); 18174 ast_config_destroy(cfg); 18175 return 0; 18176 } 18177 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 18178 ucfg = ast_config_load("users.conf", config_flags); 18179 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 18180 return 0; 18181 } 18182 if (ucfg == CONFIG_STATUS_FILEINVALID) { 18183 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n"); 18184 return 0; 18185 } 18186 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 18187 cfg = ast_config_load(config, config_flags); 18188 have_cfg_now = !!cfg; 18189 if (!cfg) { 18190 if (had_cfg_before) { 18191 /* We should have been able to load the config. */ 18192 ast_log(LOG_ERROR, "Bad. Unable to load config %s\n", config); 18193 ast_config_destroy(ucfg); 18194 return 0; 18195 } 18196 cfg = ast_config_new();/* Dummy config */ 18197 if (!cfg) { 18198 ast_config_destroy(ucfg); 18199 return 0; 18200 } 18201 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 18202 ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config); 18203 ast_config_destroy(ucfg); 18204 return 0; 18205 } 18206 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 18207 ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config); 18208 return 0; 18209 } else { 18210 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 18211 ucfg = ast_config_load("users.conf", config_flags); 18212 if (ucfg == CONFIG_STATUS_FILEINVALID) { 18213 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n"); 18214 ast_config_destroy(cfg); 18215 return 0; 18216 } 18217 } 18218 had_cfg_before = have_cfg_now; 18219 18220 /* It's a little silly to lock it, but we might as well just to be sure */ 18221 ast_mutex_lock(&iflock); 18222 #ifdef HAVE_PRI 18223 if (reload != 1) { 18224 /* Process trunkgroups first */ 18225 v = ast_variable_browse(cfg, "trunkgroups"); 18226 while (v) { 18227 if (!strcasecmp(v->name, "trunkgroup")) { 18228 trunkgroup = atoi(v->value); 18229 if (trunkgroup > 0) { 18230 if ((c = strchr(v->value, ','))) { 18231 i = 0; 18232 memset(dchannels, 0, sizeof(dchannels)); 18233 while (c && (i < SIG_PRI_NUM_DCHANS)) { 18234 dchannels[i] = atoi(c + 1); 18235 if (dchannels[i] < 0) { 18236 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); 18237 } else 18238 i++; 18239 c = strchr(c + 1, ','); 18240 } 18241 if (i) { 18242 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 18243 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); 18244 } else 18245 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"); 18246 } else 18247 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno); 18248 } else 18249 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno); 18250 } else 18251 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->lineno); 18252 } else if (!strcasecmp(v->name, "spanmap")) { 18253 spanno = atoi(v->value); 18254 if (spanno > 0) { 18255 if ((c = strchr(v->value, ','))) { 18256 trunkgroup = atoi(c + 1); 18257 if (trunkgroup > 0) { 18258 if ((c = strchr(c + 1, ','))) 18259 logicalspan = atoi(c + 1); 18260 else 18261 logicalspan = 0; 18262 if (logicalspan >= 0) { 18263 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 18264 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 18265 } else 18266 ast_verb(2, "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 18267 } else 18268 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); 18269 } else 18270 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of chan_dahdi.conf\n", v->lineno); 18271 } else 18272 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of chan_dahdi.conf\n", v->lineno); 18273 } else 18274 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of chan_dahdi.conf\n", v->lineno); 18275 } else { 18276 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 18277 } 18278 v = v->next; 18279 } 18280 } 18281 #endif 18282 18283 /* Copy the default jb config over global_jbconf */ 18284 memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf)); 18285 18286 mwimonitornotify[0] = '\0'; 18287 18288 v = ast_variable_browse(cfg, "channels"); 18289 if ((res = process_dahdi(base_conf, 18290 "" /* Must be empty for the channels category. Silly voicemail mailbox. */, 18291 v, reload, 0))) { 18292 ast_mutex_unlock(&iflock); 18293 ast_config_destroy(cfg); 18294 if (ucfg) { 18295 ast_config_destroy(ucfg); 18296 } 18297 return res; 18298 } 18299 18300 /* Now get configuration from all normal sections in chan_dahdi.conf: */ 18301 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 18302 /* [channels] and [trunkgroups] are used. Let's also reserve 18303 * [globals] and [general] for future use 18304 */ 18305 if (!strcasecmp(cat, "general") || 18306 !strcasecmp(cat, "trunkgroups") || 18307 !strcasecmp(cat, "globals") || 18308 !strcasecmp(cat, "channels")) { 18309 continue; 18310 } 18311 18312 chans = ast_variable_retrieve(cfg, cat, "dahdichan"); 18313 if (ast_strlen_zero(chans)) { 18314 /* Section is useless without a dahdichan value present. */ 18315 continue; 18316 } 18317 18318 /* Copy base_conf to conf. */ 18319 deep_copy_dahdi_chan_conf(conf, base_conf); 18320 18321 if ((res = process_dahdi(conf, cat, ast_variable_browse(cfg, cat), reload, PROC_DAHDI_OPT_NOCHAN))) { 18322 ast_mutex_unlock(&iflock); 18323 ast_config_destroy(cfg); 18324 if (ucfg) { 18325 ast_config_destroy(ucfg); 18326 } 18327 return res; 18328 } 18329 } 18330 18331 ast_config_destroy(cfg); 18332 18333 if (ucfg) { 18334 /* Reset base_conf, so things don't leak from chan_dahdi.conf */ 18335 deep_copy_dahdi_chan_conf(base_conf, default_conf); 18336 process_dahdi(base_conf, 18337 "" /* Must be empty for the general category. Silly voicemail mailbox. */, 18338 ast_variable_browse(ucfg, "general"), 1, 0); 18339 18340 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 18341 if (!strcasecmp(cat, "general")) { 18342 continue; 18343 } 18344 18345 chans = ast_variable_retrieve(ucfg, cat, "dahdichan"); 18346 if (ast_strlen_zero(chans)) { 18347 /* Section is useless without a dahdichan value present. */ 18348 continue; 18349 } 18350 18351 /* Copy base_conf to conf. */ 18352 deep_copy_dahdi_chan_conf(conf, base_conf); 18353 18354 if ((res = process_dahdi(conf, cat, ast_variable_browse(ucfg, cat), reload, PROC_DAHDI_OPT_NOCHAN | PROC_DAHDI_OPT_NOWARN))) { 18355 ast_config_destroy(ucfg); 18356 ast_mutex_unlock(&iflock); 18357 return res; 18358 } 18359 } 18360 ast_config_destroy(ucfg); 18361 } 18362 ast_mutex_unlock(&iflock); 18363 18364 #ifdef HAVE_PRI 18365 if (reload != 1) { 18366 int x; 18367 for (x = 0; x < NUM_SPANS; x++) { 18368 if (pris[x].pri.pvts[0]) { 18369 prepare_pri(pris + x); 18370 if (sig_pri_start_pri(&pris[x].pri)) { 18371 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 18372 return -1; 18373 } else 18374 ast_verb(2, "Starting D-Channel on span %d\n", x + 1); 18375 } 18376 } 18377 } 18378 #endif 18379 #if defined(HAVE_SS7) 18380 if (reload != 1) { 18381 int x; 18382 for (x = 0; x < NUM_SPANS; x++) { 18383 if (linksets[x].ss7.ss7) { 18384 linksets[x].ss7.calls = &dahdi_ss7_callbacks; 18385 if (ast_pthread_create(&linksets[x].ss7.master, NULL, ss7_linkset, &linksets[x].ss7)) { 18386 ast_log(LOG_ERROR, "Unable to start SS7 linkset on span %d\n", x + 1); 18387 return -1; 18388 } else 18389 ast_verb(2, "Starting SS7 linkset on span %d\n", x + 1); 18390 } 18391 } 18392 } 18393 #endif /* defined(HAVE_SS7) */ 18394 #ifdef HAVE_OPENR2 18395 if (reload != 1) { 18396 int x; 18397 for (x = 0; x < r2links_count; x++) { 18398 if (ast_pthread_create(&r2links[x]->r2master, NULL, mfcr2_monitor, r2links[x])) { 18399 ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1); 18400 return -1; 18401 } else { 18402 ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1); 18403 } 18404 } 18405 } 18406 #endif 18407 /* And start the monitor for the first time */ 18408 restart_monitor(); 18409 return 0; 18410 }
| static int sigtype_to_signalling | ( | int | sigtype | ) | [static] |
Definition at line 12282 of file chan_dahdi.c.
Referenced by mkintf().
12283 { 12284 return sigtype; 12285 }
| static void string_replace | ( | char * | str, | |
| int | char1, | |||
| int | char2 | |||
| ) | [static] |
Definition at line 16844 of file chan_dahdi.c.
Referenced by parse_spanchan().
| static void swap_subs | ( | struct dahdi_pvt * | p, | |
| int | a, | |||
| int | b | |||
| ) | [static] |
Definition at line 4315 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(), and dahdi_hangup().
04316 { 04317 int tchan; 04318 int tinthreeway; 04319 struct ast_channel *towner; 04320 04321 ast_debug(1, "Swapping %d and %d\n", a, b); 04322 04323 tchan = p->subs[a].chan; 04324 towner = p->subs[a].owner; 04325 tinthreeway = p->subs[a].inthreeway; 04326 04327 p->subs[a].chan = p->subs[b].chan; 04328 p->subs[a].owner = p->subs[b].owner; 04329 p->subs[a].inthreeway = p->subs[b].inthreeway; 04330 04331 p->subs[b].chan = tchan; 04332 p->subs[b].owner = towner; 04333 p->subs[b].inthreeway = tinthreeway; 04334 04335 if (p->subs[a].owner) 04336 ast_channel_set_fd(p->subs[a].owner, 0, p->subs[a].dfd); 04337 if (p->subs[b].owner) 04338 ast_channel_set_fd(p->subs[b].owner, 0, p->subs[b].dfd); 04339 wakeup_sub(p, a); 04340 wakeup_sub(p, b); 04341 }
| static int unalloc_sub | ( | struct dahdi_pvt * | p, | |
| int | x | |||
| ) | [static] |
Definition at line 4461 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(), and my_unallocate_sub().
04462 { 04463 if (!x) { 04464 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel); 04465 return -1; 04466 } 04467 ast_debug(1, "Released sub %d of channel %d\n", x, p->channel); 04468 dahdi_close_sub(p, x); 04469 p->subs[x].linear = 0; 04470 p->subs[x].chan = 0; 04471 p->subs[x].owner = NULL; 04472 p->subs[x].inthreeway = 0; 04473 p->polarity = POLARITY_IDLE; 04474 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf)); 04475 return 0; 04476 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 16828 of file chan_dahdi.c.
References __unload_module(), ast_mutex_destroy, and sig_ss7_linkset::lock.
16829 { 16830 #if defined(HAVE_PRI) || defined(HAVE_SS7) 16831 int y; 16832 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 16833 #ifdef HAVE_PRI 16834 for (y = 0; y < NUM_SPANS; y++) 16835 ast_mutex_destroy(&pris[y].pri.lock); 16836 #endif 16837 #if defined(HAVE_SS7) 16838 for (y = 0; y < NUM_SPANS; y++) 16839 ast_mutex_destroy(&linksets[y].ss7.lock); 16840 #endif /* defined(HAVE_SS7) */ 16841 return __unload_module(); 16842 }
| static int update_conf | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4834 of file chan_dahdi.c.
References ast_debug, dahdi_pvt::channel, conf_add(), conf_del(), dahdi_pvt::confno, dahdi_subchannel::dfd, GET_CHANNEL, dahdi_pvt::inconference, dahdi_subchannel::inthreeway, isslavenative(), dahdi_pvt::master, MAX_SLAVES, dahdi_pvt::slaves, SUB_REAL, and dahdi_pvt::subs.
Referenced by __dahdi_exception(), dahdi_bridge(), dahdi_fixup(), dahdi_handle_event(), dahdi_hangup(), dahdi_unlink(), and mkintf().
04835 { 04836 int needconf = 0; 04837 int x; 04838 int useslavenative; 04839 struct dahdi_pvt *slave = NULL; 04840 04841 useslavenative = isslavenative(p, &slave); 04842 /* Start with the obvious, general stuff */ 04843 for (x = 0; x < 3; x++) { 04844 /* Look for three way calls */ 04845 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) { 04846 conf_add(p, &p->subs[x], x, 0); 04847 needconf++; 04848 } else { 04849 conf_del(p, &p->subs[x], x); 04850 } 04851 } 04852 /* If we have a slave, add him to our conference now. or DAX 04853 if this is slave native */ 04854 for (x = 0; x < MAX_SLAVES; x++) { 04855 if (p->slaves[x]) { 04856 if (useslavenative) 04857 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 04858 else { 04859 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 04860 needconf++; 04861 } 04862 } 04863 } 04864 /* If we're supposed to be in there, do so now */ 04865 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 04866 if (useslavenative) 04867 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 04868 else { 04869 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 04870 needconf++; 04871 } 04872 } 04873 /* If we have a master, add ourselves to his conference */ 04874 if (p->master) { 04875 if (isslavenative(p->master, NULL)) { 04876 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 04877 } else { 04878 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 04879 } 04880 } 04881 if (!needconf) { 04882 /* Nobody is left (or should be left) in our conference. 04883 Kill it. */ 04884 p->confno = -1; 04885 } 04886 ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 04887 return 0; 04888 }
| static void wakeup_sub | ( | struct dahdi_pvt * | p, | |
| int | a | |||
| ) | [static] |
Definition at line 3822 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().
03823 { 03824 dahdi_lock_sub_owner(p, a); 03825 if (p->subs[a].owner) { 03826 ast_queue_frame(p->subs[a].owner, &ast_null_frame); 03827 ast_channel_unlock(p->subs[a].owner); 03828 } 03829 }
| int alarm |
Definition at line 4611 of file chan_dahdi.c.
struct { ... } alarms[] [static] |
Referenced by alarm2str().
struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}} [static] |
Definition at line 412 of file chan_dahdi.c.
struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] [static] |
Definition at line 393 of file chan_dahdi.c.
int cidrings[NUM_CADENCE_MAX] [static] |
cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on.
Definition at line 404 of file chan_dahdi.c.
const char config[] = "chan_dahdi.conf" [static] |
Definition at line 347 of file chan_dahdi.c.
struct analog_callback dahdi_analog_callbacks [static] |
Definition at line 3698 of file chan_dahdi.c.
struct ast_data_handler dahdi_channels_data_provider [static] |
{
.version = AST_DATA_HANDLER_VERSION,
.get = dahdi_channels_data_provider_get
}
Definition at line 18581 of file chan_dahdi.c.
struct ast_cli_entry dahdi_cli[] [static] |
Definition at line 15896 of file chan_dahdi.c.
struct ast_data_entry dahdi_data_providers[] [static] |
{
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 18591 of file chan_dahdi.c.
struct ast_data_handler dahdi_status_data_provider [static] |
{
.version = AST_DATA_HANDLER_VERSION,
.get = dahdi_status_data_provider_get
}
Definition at line 18576 of file chan_dahdi.c.
struct ast_channel_tech dahdi_tech [static] |
Definition at line 1500 of file chan_dahdi.c.
struct ast_data_handler dahdi_version_data_provider [static] |
{
.version = AST_DATA_HANDLER_VERSION,
.get = dahdi_version_data_provider_get
}
Definition at line 18586 of file chan_dahdi.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 296 of file chan_dahdi.c.
char defaultcic[64] = "" [static] |
Definition at line 420 of file chan_dahdi.c.
char defaultozz[64] = "" [static] |
Definition at line 421 of file chan_dahdi.c.
int distinctiveringaftercid = 0 [static] |
Definition at line 432 of file chan_dahdi.c.
int dtmfcid_level = 256 [static] |
Definition at line 437 of file chan_dahdi.c.
const char* const events[] [static] |
Definition at line 4588 of file chan_dahdi.c.
int firstdigittimeout = 16000 [static] |
Wait up to 16 seconds for first digit (FXO logic).
Definition at line 449 of file chan_dahdi.c.
Referenced by disa_exec().
int gendigittimeout = 8000 [static] |
How long to wait for following digits (FXO logic).
Definition at line 452 of file chan_dahdi.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 304 of file chan_dahdi.c.
Referenced by dahdi_new(), process_dahdi(), and setup_dahdi_int().
int ifcount = 0 [static] |
Definition at line 461 of file chan_dahdi.c.
Main interface list end
Definition at line 1308 of file chan_dahdi.c.
Main interface list start
Definition at line 1307 of file chan_dahdi.c.
const char* const lbostr[] [static] |
Definition at line 283 of file chan_dahdi.c.
int matchdigittimeout = 3000 [static] |
How long to wait for an extra digit, if there is an ambiguous match.
Definition at line 455 of file chan_dahdi.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 473 of file chan_dahdi.c.
int mwilevel = 512 [static] |
Definition at line 436 of file chan_dahdi.c.
char mwimonitornotify[PATH_MAX] = "" [static] |
Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled
Definition at line 424 of file chan_dahdi.c.
int mwisend_rpas = 0 [static] |
Definition at line 426 of file chan_dahdi.c.
| char* name |
Definition at line 4612 of file chan_dahdi.c.
int num_cadence = 4 [static] |
Definition at line 390 of file chan_dahdi.c.
int num_restart_pending = 0 [static] |
Definition at line 478 of file chan_dahdi.c.
int numbufs = 4 [static] |
Definition at line 434 of file chan_dahdi.c.
char progzone[10] = "" [static] |
Definition at line 429 of file chan_dahdi.c.
int report_alarms = REPORT_CHANNEL_ALARMS [static] |
Definition at line 441 of file chan_dahdi.c.
int ringt_base = DEFAULT_RINGT [static] |
Configured ring timeout base.
Definition at line 534 of file chan_dahdi.c.
struct dahdi_pvt* round_robin[32] [static] |
Round robin search locations.
Definition at line 3769 of file chan_dahdi.c.
ast_cond_t ss_thread_complete [static] |
Definition at line 474 of file chan_dahdi.c.
int ss_thread_count = 0 [static] |
Definition at line 477 of file chan_dahdi.c.
const char* const subnames[] [static] |
{
"Real",
"Callwait",
"Threeway"
}
Definition at line 635 of file chan_dahdi.c.
const char tdesc[] = "DAHDI Telephony Driver" [static] |
Definition at line 326 of file chan_dahdi.c.
int usedistinctiveringdetection = 0 [static] |
Definition at line 431 of file chan_dahdi.c.
int user_has_defined_cadences = 0 [static] |
Definition at line 391 of file chan_dahdi.c.
1.6.1