#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 %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n" |
| #define | FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n" |
| #define | FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\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 void | __reg_module (void) |
| static int | __unload_module (void) |
| static void | __unreg_module (void) |
| static int | _dahdi_get_index (struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line) |
| static int | action_dahdidialoffhook (struct mansession *s, const struct message *m) |
| static int | action_dahdidndoff (struct mansession *s, const struct message *m) |
| static int | action_dahdidndon (struct mansession *s, const struct message *m) |
| static int | action_dahdirestart (struct mansession *s, const struct message *m) |
| static int | action_dahdishowchannels (struct mansession *s, const struct message *m) |
| static int | action_transfer (struct mansession *s, const struct message *m) |
| static int | action_transferhangup (struct mansession *s, const struct message *m) |
| static char * | alarm2str (int alm) |
| static int | alloc_sub (struct dahdi_pvt *p, int x) |
| static int | analog_lib_handles (int signalling, int radio, int oprmode) |
| static void * | analog_ss_thread (void *data) |
| static int | analog_tone_to_dahditone (enum analog_tone tone) |
| static int | analogsub_to_dahdisub (enum analog_sub analogsub) |
| AST_DATA_STRUCTURE (dahdi_pvt, DATA_EXPORT_DAHDI_PVT) | |
| static int | attempt_transfer (struct dahdi_pvt *p) |
| static int | available (struct dahdi_pvt **pvt, int is_specific_channel) |
| static int | build_channels (struct dahdi_chan_conf *conf, const char *value, int reload, int lineno, int *found_pseudo) |
| static int | bump_gains (struct dahdi_pvt *p) |
| static int | calc_energy (const unsigned char *buf, int len, enum ast_format_id 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, const 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 (const char *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, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *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 | 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 *cidrings, 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_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 void | parse_busy_pattern (struct ast_variable *v, struct ast_dsp_busy_pattern *busy_cadence) |
| 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 | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = tdesc , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_smdi", } |
| struct { | |
| int alarm | |
| char * name | |
| } | alarms [] |
| static struct dahdi_ring_cadence | AS_RP_cadence = {{250, 10000}} |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct dahdi_ring_cadence | cadences [NUM_CADENCE_MAX] |
| static int | cidrings [NUM_CADENCE_MAX] |
| cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on. | |
| static const char | config [] = "chan_dahdi.conf" |
| static 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 ast_mutex_t | iflock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } |
| Protect the interface list (of dahdi_pvt's). | |
| static const char *const | lbostr [] |
| static int | matchdigittimeout = 3000 |
| How long to wait for an extra digit, if there is an ambiguous match. | |
| static pthread_t | monitor_thread = AST_PTHREADT_NULL |
| This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
| static ast_mutex_t | monlock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } |
| Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
| static int | mwilevel = 512 |
| static char | mwimonitornotify [PATH_MAX] = "" |
| static int | 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 ast_mutex_t | restart_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } |
| static int | ringt_base = DEFAULT_RINGT |
| Configured ring timeout base. | |
| static struct dahdi_pvt * | round_robin [32] |
| static ast_cond_t | ss_thread_complete |
| static int | ss_thread_count = 0 |
| static ast_mutex_t | ss_thread_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } |
| static const char *const | subnames [] |
| static const char | tdesc [] = "DAHDI Telephony Driver" |
| static int | usedistinctiveringdetection = 0 |
| static int | user_has_defined_cadences = 0 |
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 328 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 395 of file chan_dahdi.c.
Referenced by dahdi_handle_dtmf(), my_handle_dtmf(), and process_dahdi().
| #define CALLPROGRESS_FAX_INCOMING 4 |
| #define CALLPROGRESS_FAX_OUTGOING 2 |
| #define CALLPROGRESS_PROGRESS 1 |
Definition at line 392 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 530 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 529 of file chan_dahdi.c.
| #define CALLWAITING_SUPPRESS_SAMPLES ((100 * 8) / READ_SIZE) |
| #define CANBUSYDETECT | ( | p | ) | (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */) |
| #define CANPROGRESSDETECT | ( | p | ) | (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */) |
Definition at line 426 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 390 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 677 of file chan_dahdi.c.
| #define CONF_USER_THIRDCALL (1 << 1) |
Definition at line 678 of file chan_dahdi.c.
| #define dahdi_get_index | ( | ast, | |||
| p, | |||||
| nullok | ) | _dahdi_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__) |
Definition at line 3737 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 1254 of file chan_dahdi.c.
| #define DEFAULT_CIDRINGS 1 |
Typically, how many rings before we should send Caller*ID.
Definition at line 326 of file chan_dahdi.c.
Referenced by dahdi_chan_conf_default().
| #define DEFAULT_RINGT ((8000 * 8) / READ_SIZE) |
8,000 ms
Definition at line 534 of file chan_dahdi.c.
| #define END_SILENCE_LEN 400 |
Referenced by dahdi_sendtext().
| #define FORMAT "%-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n" |
| #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\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(), gtalk_show_settings(), 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_calendars_types(), handle_show_routes(), handle_show_version_files(), jingle_show_channels(), show_channels_cb(), show_chanstats_cb(), sip_show_domains(), sip_show_inuse(), sip_show_mwi(), sip_show_registry(), sip_show_tcp(), and sip_show_users().
| #define FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n" |
| #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n" |
Referenced by __iax2_show_peers(), _sip_show_peers(), dahdi_show_channels(), dahdi_show_status(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), handle_cli_core_show_file_formats(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_registry(), handle_cli_iax2_show_users(), handle_core_show_image_formats(), handle_manager_show_settings(), handle_show_calendar(), sip_show_channels(), sip_show_channelstats(), sip_show_inuse(), sip_show_registry(), and sip_show_tcp().
| #define GET_CHANNEL | ( | p | ) | ((p)->channel) |
Definition at line 1551 of file chan_dahdi.c.
Referenced by my_complete_conference_update(), and update_conf().
| #define HANGUP 1 |
Definition at line 15881 of file chan_dahdi.c.
Referenced by action_transferhangup(), and dahdi_fake_event().
| #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) |
Referenced by build_alerting(), build_connect(), build_connect_acknowledge(), build_disconnect(), build_facility(), build_hold(), build_hold_acknowledge(), build_hold_reject(), build_proceeding(), build_progress(), build_release(), build_release_complete(), build_restart(), build_resume(), build_resume_acknowledge(), build_resume_reject(), build_retrieve(), build_retrieve_acknowledge(), build_retrieve_reject(), build_setup(), build_setup_acknowledge(), build_suspend(), build_suspend_acknowledge(), build_suspend_reject(), build_user_information(), dahdi_sendtext(), parse_alerting(), parse_connect(), parse_disconnect(), parse_facility(), parse_proceeding(), parse_progress(), parse_release(), parse_release_complete(), parse_restart(), parse_setup(), and parse_setup_acknowledge().
| #define HEADER_MS 50 |
Referenced by dahdi_sendtext().
| #define ISTRUNK | ( | p | ) |
Value:
Definition at line 422 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 526 of file chan_dahdi.c.
| #define MASK_INUSE (1 << 1) |
Channel currently in use
Definition at line 527 of file chan_dahdi.c.
| #define MAX_CHANLIST_LEN 80 |
The length of the parameters list of 'dahdichan'.
Definition at line 16966 of file chan_dahdi.c.
| #define MAX_SLAVES 4 |
Definition at line 680 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 533 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 332 of file chan_dahdi.c.
Referenced by analog_ss_thread(), and dahdi_new().
| #define NUM_CADENCE_MAX 25 |
| #define NUM_SPANS 32 |
| #define POLARITY_IDLE 0 |
Definition at line 637 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 638 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 17101 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 17103 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 524 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 447 of file chan_dahdi.c.
Referenced by handle_alarms(), handle_clear_alarms(), and process_dahdi().
| #define REPORT_SPAN_ALARMS 2 |
Definition at line 448 of file chan_dahdi.c.
Referenced by handle_alarms(), handle_clear_alarms(), and process_dahdi().
| #define sig2str dahdi_sig2str |
Definition at line 4663 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) |
| #define SIG_BRI_PTMP (0X4000000 | DAHDI_SIG_CLEAR) |
| #define SIG_E911 (0x1000000 | DAHDI_SIG_EM) |
Definition at line 362 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 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_EM_E1 DAHDI_SIG_EM_E1 |
Definition at line 382 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 358 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 361 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 359 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 360 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 363 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 364 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 365 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 370 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 371 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 369 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 367 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 368 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 366 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 376 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 372 of file chan_dahdi.c.
Referenced by dahdi_indicate(), dahdi_sig2str(), mkintf(), and process_dahdi().
| #define SIG_PRI_LIB_HANDLE_CASES |
Value:
SIG_PRI: \ case SIG_BRI: \ case SIG_BRI_PTMP
Definition at line 1553 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 377 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 381 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 379 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 380 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 378 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 375 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 |
| #define SUB_CALLWAIT 1 |
Call-Waiting call on hold
Definition at line 633 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 632 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 634 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 15880 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 701 of file chan_dahdi.c.
00701 { 00702 DAHDI_IFLIST_NONE, /*!< The dahdi_pvt is not in any list. */ 00703 DAHDI_IFLIST_MAIN, /*!< The dahdi_pvt is in the main interface list */ 00704 #if defined(HAVE_PRI) 00705 DAHDI_IFLIST_NO_B_CHAN, /*!< The dahdi_pvt is in a no B channel interface list */ 00706 #endif /* defined(HAVE_PRI) */ 00707 };
| 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 685 of file chan_dahdi.c.
00685 { 00686 MWI_SEND_NULL = 0, 00687 MWI_SEND_SA, 00688 MWI_SEND_SA_WAIT, 00689 MWI_SEND_PAUSE, 00690 MWI_SEND_SPILL, 00691 MWI_SEND_CLEANUP, 00692 MWI_SEND_DONE, 00693 } mwisend_states;
| static struct ast_frame* __dahdi_exception | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 8792 of file chan_dahdi.c.
References ast_channel::_state, ast_bridged_channel(), ast_channel_name(), AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_NULL, ast_log(), ast_queue_control(), ast_set_hangupsource(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_tv(), ast_tvnow(), ast_verb, dahdi_pvt::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, LOG_WARNING, ast_frame::mallocd, 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().
08793 { 08794 int res; 08795 int idx; 08796 struct ast_frame *f; 08797 int usedindex = -1; 08798 struct dahdi_pvt *p = ast->tech_pvt; 08799 08800 idx = dahdi_get_index(ast, p, 1); 08801 08802 p->subs[idx].f.frametype = AST_FRAME_NULL; 08803 p->subs[idx].f.datalen = 0; 08804 p->subs[idx].f.samples = 0; 08805 p->subs[idx].f.mallocd = 0; 08806 p->subs[idx].f.offset = 0; 08807 p->subs[idx].f.subclass.integer = 0; 08808 p->subs[idx].f.delivery = ast_tv(0,0); 08809 p->subs[idx].f.src = "dahdi_exception"; 08810 p->subs[idx].f.data.ptr = NULL; 08811 08812 08813 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) { 08814 /* If nobody owns us, absorb the event appropriately, otherwise 08815 we loop indefinitely. This occurs when, during call waiting, the 08816 other end hangs up our channel so that it no longer exists, but we 08817 have neither FLASH'd nor ONHOOK'd to signify our desire to 08818 change to the other channel. */ 08819 if (p->fake_event) { 08820 res = p->fake_event; 08821 p->fake_event = 0; 08822 } else 08823 res = dahdi_get_event(p->subs[SUB_REAL].dfd); 08824 /* Switch to real if there is one and this isn't something really silly... */ 08825 if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) && 08826 (res != DAHDI_EVENT_HOOKCOMPLETE)) { 08827 ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res); 08828 p->owner = p->subs[SUB_REAL].owner; 08829 if (p->owner && ast_bridged_channel(p->owner)) 08830 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08831 p->subs[SUB_REAL].needunhold = 1; 08832 } 08833 switch (res) { 08834 case DAHDI_EVENT_ONHOOK: 08835 dahdi_disable_ec(p); 08836 if (p->owner) { 08837 ast_verb(3, "Channel %s still has call, ringing phone\n", ast_channel_name(p->owner)); 08838 dahdi_ring_phone(p); 08839 p->callwaitingrepeat = 0; 08840 p->cidcwexpire = 0; 08841 p->cid_suppress_expire = 0; 08842 } else 08843 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 08844 update_conf(p); 08845 break; 08846 case DAHDI_EVENT_RINGOFFHOOK: 08847 dahdi_enable_ec(p); 08848 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 08849 if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { 08850 p->subs[SUB_REAL].needanswer = 1; 08851 p->dialing = 0; 08852 } 08853 break; 08854 case DAHDI_EVENT_HOOKCOMPLETE: 08855 case DAHDI_EVENT_RINGERON: 08856 case DAHDI_EVENT_RINGEROFF: 08857 /* Do nothing */ 08858 break; 08859 case DAHDI_EVENT_WINKFLASH: 08860 p->flashtime = ast_tvnow(); 08861 if (p->owner) { 08862 ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, ast_channel_name(p->owner)); 08863 if (p->owner->_state != AST_STATE_UP) { 08864 /* Answer if necessary */ 08865 usedindex = dahdi_get_index(p->owner, p, 0); 08866 if (usedindex > -1) { 08867 p->subs[usedindex].needanswer = 1; 08868 } 08869 ast_setstate(p->owner, AST_STATE_UP); 08870 } 08871 p->callwaitingrepeat = 0; 08872 p->cidcwexpire = 0; 08873 p->cid_suppress_expire = 0; 08874 if (ast_bridged_channel(p->owner)) 08875 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08876 p->subs[SUB_REAL].needunhold = 1; 08877 } else 08878 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n"); 08879 update_conf(p); 08880 break; 08881 default: 08882 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res)); 08883 } 08884 f = &p->subs[idx].f; 08885 return f; 08886 } 08887 if (!(p->radio || (p->oprmode < 0))) 08888 ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel); 08889 /* If it's not us, return NULL immediately */ 08890 if (ast != p->owner) { 08891 ast_log(LOG_WARNING, "We're %s, not %s\n", ast_channel_name(ast), ast_channel_name(p->owner)); 08892 f = &p->subs[idx].f; 08893 return f; 08894 } 08895 f = dahdi_handle_event(ast); 08896 08897 /* tell the cdr this zap device hung up */ 08898 if (f == NULL) { 08899 ast_set_hangupsource(ast, ast_channel_name(ast), 0); 08900 } 08901 08902 return f; 08903 }
| static void __reg_module | ( | void | ) | [static] |
Definition at line 19032 of file chan_dahdi.c.
| static int __unload_module | ( | void | ) | [static] |
Definition at line 16761 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_format_cap_destroy(), ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_unregister_application(), ast_channel_tech::capabilities, destroy_all_channels(), iflock, sig_ss7_linkset::master, monlock, 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().
16762 { 16763 struct dahdi_pvt *p; 16764 #if defined(HAVE_PRI) || defined(HAVE_SS7) 16765 int i, j; 16766 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 16767 16768 #ifdef HAVE_PRI 16769 for (i = 0; i < NUM_SPANS; i++) { 16770 if (pris[i].pri.master != AST_PTHREADT_NULL) 16771 pthread_cancel(pris[i].pri.master); 16772 } 16773 ast_cli_unregister_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli)); 16774 ast_unregister_application(dahdi_send_keypad_facility_app); 16775 #ifdef HAVE_PRI_PROG_W_CAUSE 16776 ast_unregister_application(dahdi_send_callrerouting_facility_app); 16777 #endif 16778 #endif 16779 #if defined(HAVE_SS7) 16780 for (i = 0; i < NUM_SPANS; i++) { 16781 if (linksets[i].ss7.master != AST_PTHREADT_NULL) 16782 pthread_cancel(linksets[i].ss7.master); 16783 } 16784 ast_cli_unregister_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli)); 16785 #endif /* defined(HAVE_SS7) */ 16786 #if defined(HAVE_OPENR2) 16787 dahdi_r2_destroy_links(); 16788 ast_cli_unregister_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli)); 16789 ast_unregister_application(dahdi_accept_r2_call_app); 16790 #endif 16791 16792 ast_cli_unregister_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli)); 16793 ast_manager_unregister("DAHDIDialOffhook"); 16794 ast_manager_unregister("DAHDIHangup"); 16795 ast_manager_unregister("DAHDITransfer"); 16796 ast_manager_unregister("DAHDIDNDoff"); 16797 ast_manager_unregister("DAHDIDNDon"); 16798 ast_manager_unregister("DAHDIShowChannels"); 16799 ast_manager_unregister("DAHDIRestart"); 16800 #if defined(HAVE_PRI) 16801 ast_manager_unregister("PRIShowSpans"); 16802 #endif /* defined(HAVE_PRI) */ 16803 ast_data_unregister(NULL); 16804 ast_channel_unregister(&dahdi_tech); 16805 16806 /* Hangup all interfaces if they have an owner */ 16807 ast_mutex_lock(&iflock); 16808 for (p = iflist; p; p = p->next) { 16809 if (p->owner) 16810 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 16811 } 16812 ast_mutex_unlock(&iflock); 16813 16814 ast_mutex_lock(&monlock); 16815 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 16816 pthread_cancel(monitor_thread); 16817 pthread_kill(monitor_thread, SIGURG); 16818 pthread_join(monitor_thread, NULL); 16819 } 16820 monitor_thread = AST_PTHREADT_STOP; 16821 ast_mutex_unlock(&monlock); 16822 16823 destroy_all_channels(); 16824 16825 #if defined(HAVE_PRI) 16826 for (i = 0; i < NUM_SPANS; i++) { 16827 if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) 16828 pthread_join(pris[i].pri.master, NULL); 16829 for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) { 16830 dahdi_close_pri_fd(&(pris[i]), j); 16831 } 16832 sig_pri_stop_pri(&pris[i].pri); 16833 } 16834 #if defined(HAVE_PRI_CCSS) 16835 ast_cc_agent_unregister(&dahdi_pri_cc_agent_callbacks); 16836 ast_cc_monitor_unregister(&dahdi_pri_cc_monitor_callbacks); 16837 #endif /* defined(HAVE_PRI_CCSS) */ 16838 sig_pri_unload(); 16839 #endif 16840 16841 #if defined(HAVE_SS7) 16842 for (i = 0; i < NUM_SPANS; i++) { 16843 if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) 16844 pthread_join(linksets[i].ss7.master, NULL); 16845 for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) { 16846 dahdi_close_ss7_fd(&(linksets[i]), j); 16847 } 16848 } 16849 #endif /* defined(HAVE_SS7) */ 16850 ast_cond_destroy(&ss_thread_complete); 16851 16852 dahdi_tech.capabilities = ast_format_cap_destroy(dahdi_tech.capabilities); 16853 return 0; 16854 }
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 19032 of file chan_dahdi.c.
| static int _dahdi_get_index | ( | struct ast_channel * | ast, | |
| struct dahdi_pvt * | p, | |||
| int | nullok, | |||
| const char * | fname, | |||
| unsigned long | line | |||
| ) | [static] |
Definition at line 3738 of file chan_dahdi.c.
References ast_channel_name(), ast_log(), dahdi_pvt::channel, LOG_WARNING, dahdi_subchannel::owner, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, and dahdi_pvt::subs.
03739 { 03740 int res; 03741 if (p->subs[SUB_REAL].owner == ast) 03742 res = 0; 03743 else if (p->subs[SUB_CALLWAIT].owner == ast) 03744 res = 1; 03745 else if (p->subs[SUB_THREEWAY].owner == ast) 03746 res = 2; 03747 else { 03748 res = -1; 03749 if (!nullok) 03750 ast_log(LOG_WARNING, 03751 "Unable to get index for '%s' on channel %d (%s(), line %lu)\n", 03752 ast ? ast_channel_name(ast) : "", p->channel, fname, line); 03753 } 03754 return res; 03755 }
| static int action_dahdidialoffhook | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 16018 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().
16019 { 16020 struct dahdi_pvt *p; 16021 const char *channel = astman_get_header(m, "DAHDIChannel"); 16022 const char *number = astman_get_header(m, "Number"); 16023 int i; 16024 16025 if (ast_strlen_zero(channel)) { 16026 astman_send_error(s, m, "No channel specified"); 16027 return 0; 16028 } 16029 if (ast_strlen_zero(number)) { 16030 astman_send_error(s, m, "No number 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 (!p->owner) { 16039 astman_send_error(s, m, "Channel does not have it's owner"); 16040 return 0; 16041 } 16042 for (i = 0; i < strlen(number); i++) { 16043 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = number[i] }; 16044 dahdi_queue_frame(p, &f); 16045 } 16046 astman_send_ack(s, m, "DAHDIDialOffhook"); 16047 return 0; 16048 }
| static int action_dahdidndoff | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 15953 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().
15954 { 15955 struct dahdi_pvt *p; 15956 const char *channel = astman_get_header(m, "DAHDIChannel"); 15957 15958 if (ast_strlen_zero(channel)) { 15959 astman_send_error(s, m, "No channel specified"); 15960 return 0; 15961 } 15962 p = find_channel_from_str(channel); 15963 if (!p) { 15964 astman_send_error(s, m, "No such channel"); 15965 return 0; 15966 } 15967 dahdi_dnd(p, 0); 15968 astman_send_ack(s, m, "DND Disabled"); 15969 return 0; 15970 }
| static int action_dahdidndon | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 15934 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().
15935 { 15936 struct dahdi_pvt *p; 15937 const char *channel = astman_get_header(m, "DAHDIChannel"); 15938 15939 if (ast_strlen_zero(channel)) { 15940 astman_send_error(s, m, "No channel specified"); 15941 return 0; 15942 } 15943 p = find_channel_from_str(channel); 15944 if (!p) { 15945 astman_send_error(s, m, "No such channel"); 15946 return 0; 15947 } 15948 dahdi_dnd(p, 1); 15949 astman_send_ack(s, m, "DND Enabled"); 15950 return 0; 15951 }
| static int action_dahdirestart | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 15232 of file chan_dahdi.c.
References astman_send_ack(), astman_send_error(), and dahdi_restart().
Referenced by load_module().
15233 { 15234 if (dahdi_restart() != 0) { 15235 astman_send_error(s, m, "Failed rereading DAHDI configuration"); 15236 return 1; 15237 } 15238 astman_send_ack(s, m, "DAHDIRestart: Success"); 15239 return 0; 15240 }
| static int action_dahdishowchannels | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 16050 of file chan_dahdi.c.
References alarm2str(), ast_channel_accountcode(), ast_channel_name(), ast_channel_uniqueid(), 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(), dahdi_pvt::description, get_alarms(), iflock, dahdi_pvt::next, dahdi_pvt::owner, dahdi_pvt::sig, and sig2str.
Referenced by load_module().
16051 { 16052 struct dahdi_pvt *tmp = NULL; 16053 const char *id = astman_get_header(m, "ActionID"); 16054 const char *dahdichannel = astman_get_header(m, "DAHDIChannel"); 16055 char idText[256] = ""; 16056 int channels = 0; 16057 int dahdichanquery; 16058 16059 if (!dahdichannel || sscanf(dahdichannel, "%30d", &dahdichanquery) != 1) { 16060 /* Not numeric string. */ 16061 dahdichanquery = -1; 16062 } 16063 16064 astman_send_ack(s, m, "DAHDI channel status will follow"); 16065 if (!ast_strlen_zero(id)) 16066 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 16067 16068 ast_mutex_lock(&iflock); 16069 16070 for (tmp = iflist; tmp; tmp = tmp->next) { 16071 if (tmp->channel > 0) { 16072 int alm; 16073 16074 /* If a specific channel is queried for, only deliver status for that channel */ 16075 if (dahdichanquery > 0 && tmp->channel != dahdichanquery) 16076 continue; 16077 16078 alm = get_alarms(tmp); 16079 channels++; 16080 if (tmp->owner) { 16081 /* Add data if we have a current call */ 16082 astman_append(s, 16083 "Event: DAHDIShowChannels\r\n" 16084 "DAHDIChannel: %d\r\n" 16085 "Channel: %s\r\n" 16086 "Uniqueid: %s\r\n" 16087 "AccountCode: %s\r\n" 16088 "Signalling: %s\r\n" 16089 "SignallingCode: %d\r\n" 16090 "Context: %s\r\n" 16091 "DND: %s\r\n" 16092 "Alarm: %s\r\n" 16093 "Description: %s\r\n" 16094 "%s" 16095 "\r\n", 16096 tmp->channel, 16097 ast_channel_name(tmp->owner), 16098 ast_channel_uniqueid(tmp->owner), 16099 ast_channel_accountcode(tmp->owner), 16100 sig2str(tmp->sig), 16101 tmp->sig, 16102 tmp->context, 16103 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled", 16104 alarm2str(alm), 16105 tmp->description, idText); 16106 } else { 16107 astman_append(s, 16108 "Event: DAHDIShowChannels\r\n" 16109 "DAHDIChannel: %d\r\n" 16110 "Signalling: %s\r\n" 16111 "SignallingCode: %d\r\n" 16112 "Context: %s\r\n" 16113 "DND: %s\r\n" 16114 "Alarm: %s\r\n" 16115 "Description: %s\r\n" 16116 "%s" 16117 "\r\n", 16118 tmp->channel, sig2str(tmp->sig), tmp->sig, 16119 tmp->context, 16120 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled", 16121 alarm2str(alm), 16122 tmp->description, idText); 16123 } 16124 } 16125 } 16126 16127 ast_mutex_unlock(&iflock); 16128 16129 astman_append(s, 16130 "Event: DAHDIShowChannelsComplete\r\n" 16131 "%s" 16132 "Items: %d\r\n" 16133 "\r\n", 16134 idText, 16135 channels); 16136 return 0; 16137 }
| static int action_transfer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 15972 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().
15973 { 15974 struct dahdi_pvt *p; 15975 const char *channel = astman_get_header(m, "DAHDIChannel"); 15976 15977 if (ast_strlen_zero(channel)) { 15978 astman_send_error(s, m, "No channel specified"); 15979 return 0; 15980 } 15981 p = find_channel_from_str(channel); 15982 if (!p) { 15983 astman_send_error(s, m, "No such channel"); 15984 return 0; 15985 } 15986 if (!analog_lib_handles(p->sig, 0, 0)) { 15987 astman_send_error(s, m, "Channel signaling is not analog"); 15988 return 0; 15989 } 15990 dahdi_fake_event(p,TRANSFER); 15991 astman_send_ack(s, m, "DAHDITransfer"); 15992 return 0; 15993 }
| static int action_transferhangup | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 15995 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().
15996 { 15997 struct dahdi_pvt *p; 15998 const char *channel = astman_get_header(m, "DAHDIChannel"); 15999 16000 if (ast_strlen_zero(channel)) { 16001 astman_send_error(s, m, "No channel specified"); 16002 return 0; 16003 } 16004 p = find_channel_from_str(channel); 16005 if (!p) { 16006 astman_send_error(s, m, "No such channel"); 16007 return 0; 16008 } 16009 if (!analog_lib_handles(p->sig, 0, 0)) { 16010 astman_send_error(s, m, "Channel signaling is not analog"); 16011 return 0; 16012 } 16013 dahdi_fake_event(p,HANGUP); 16014 astman_send_ack(s, m, "DAHDIHangup"); 16015 return 0; 16016 }
| static char* alarm2str | ( | int | alm | ) | [static] |
Definition at line 4580 of file chan_dahdi.c.
References alarms, and ARRAY_LEN.
Referenced by action_dahdishowchannels(), and handle_alarms().
04581 { 04582 int x; 04583 for (x = 0; x < ARRAY_LEN(alarms); x++) { 04584 if (alarms[x].alarm & alm) 04585 return alarms[x].name; 04586 } 04587 return alm ? "Unknown Alarm" : "No Alarm"; 04588 }
| static int alloc_sub | ( | struct dahdi_pvt * | p, | |
| int | x | |||
| ) | [static] |
Definition at line 4384 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(), build_device(), dahdi_handle_event(), HandleCallOutgoing(), my_allocate_sub(), and rcv_mac_addr().
04385 { 04386 struct dahdi_bufferinfo bi; 04387 int res; 04388 if (p->subs[x].dfd >= 0) { 04389 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel); 04390 return -1; 04391 } 04392 04393 p->subs[x].dfd = dahdi_open("/dev/dahdi/pseudo"); 04394 if (p->subs[x].dfd <= -1) { 04395 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 04396 return -1; 04397 } 04398 04399 res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi); 04400 if (!res) { 04401 bi.txbufpolicy = p->buf_policy; 04402 bi.rxbufpolicy = p->buf_policy; 04403 bi.numbufs = p->buf_no; 04404 res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi); 04405 if (res < 0) { 04406 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno)); 04407 } 04408 } else 04409 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno)); 04410 04411 if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) { 04412 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno)); 04413 dahdi_close_sub(p, x); 04414 p->subs[x].dfd = -1; 04415 return -1; 04416 } 04417 ast_debug(1, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan); 04418 return 0; 04419 }
| static int analog_lib_handles | ( | int | signalling, | |
| int | radio, | |||
| int | oprmode | |||
| ) | [static] |
Definition at line 4665 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(), and mwi_thread().
04666 { 04667 switch (signalling) { 04668 case SIG_FXOLS: 04669 case SIG_FXOGS: 04670 case SIG_FXOKS: 04671 case SIG_FXSLS: 04672 case SIG_FXSGS: 04673 case SIG_FXSKS: 04674 case SIG_EMWINK: 04675 case SIG_EM: 04676 case SIG_EM_E1: 04677 case SIG_FEATD: 04678 case SIG_FEATDMF: 04679 case SIG_E911: 04680 case SIG_FGC_CAMA: 04681 case SIG_FGC_CAMAMF: 04682 case SIG_FEATB: 04683 case SIG_SFWINK: 04684 case SIG_SF: 04685 case SIG_SF_FEATD: 04686 case SIG_SF_FEATDMF: 04687 case SIG_FEATDMF_TA: 04688 case SIG_SF_FEATB: 04689 break; 04690 default: 04691 /* The rest of the function should cover the remainder of signalling types */ 04692 return 0; 04693 } 04694 04695 if (radio) 04696 return 0; 04697 04698 if (oprmode) 04699 return 0; 04700 04701 return 1; 04702 }
| static void * analog_ss_thread | ( | void * | data | ) | [static] |
Definition at line 9917 of file chan_dahdi.c.
References ast_channel::_state, alloc_sub(), ARRAY_LEN, ast_bridged_channel(), ast_canmatch_extension(), ast_channel_language(), ast_channel_name(), 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_format_set(), AST_FRAME_DTMF, ast_frfree, ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log(), ast_masq_park_call_exten(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), ast_party_name_free(), ast_party_name_init(), ast_party_number_free(), ast_party_number_init(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_read(), ast_safe_sleep(), ast_set_callerid(), ast_set_flag, ast_setstate(), ast_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_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_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, ss_thread_lock, ast_party_number::str, strsep(), 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().
09918 { 09919 struct ast_channel *chan = data; 09920 struct dahdi_pvt *p = chan->tech_pvt; 09921 char exten[AST_MAX_EXTENSION] = ""; 09922 char exten2[AST_MAX_EXTENSION] = ""; 09923 unsigned char buf[256]; 09924 char dtmfcid[300]; 09925 char dtmfbuf[300]; 09926 struct callerid_state *cs = NULL; 09927 char *name = NULL, *number = NULL; 09928 int distMatches; 09929 int curRingData[3]; 09930 int receivedRingT; 09931 int counter1; 09932 int counter; 09933 int samples = 0; 09934 struct ast_smdi_md_message *smdi_msg = NULL; 09935 int flags = 0; 09936 int i; 09937 int timeout; 09938 int getforward = 0; 09939 char *s1, *s2; 09940 int len = 0; 09941 int res; 09942 int idx; 09943 struct ast_format tmpfmt; 09944 09945 ast_mutex_lock(&ss_thread_lock); 09946 ss_thread_count++; 09947 ast_mutex_unlock(&ss_thread_lock); 09948 /* in the bizarre case where the channel has become a zombie before we 09949 even get started here, abort safely 09950 */ 09951 if (!p) { 09952 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", ast_channel_name(chan)); 09953 ast_hangup(chan); 09954 goto quit; 09955 } 09956 ast_verb(3, "Starting simple switch on '%s'\n", ast_channel_name(chan)); 09957 idx = dahdi_get_index(chan, p, 1); 09958 if (idx < 0) { 09959 ast_log(LOG_WARNING, "Huh?\n"); 09960 ast_hangup(chan); 09961 goto quit; 09962 } 09963 if (p->dsp) 09964 ast_dsp_digitreset(p->dsp); 09965 switch (p->sig) { 09966 case SIG_FEATD: 09967 case SIG_FEATDMF: 09968 case SIG_FEATDMF_TA: 09969 case SIG_E911: 09970 case SIG_FGC_CAMAMF: 09971 case SIG_FEATB: 09972 case SIG_EMWINK: 09973 case SIG_SF_FEATD: 09974 case SIG_SF_FEATDMF: 09975 case SIG_SF_FEATB: 09976 case SIG_SFWINK: 09977 if (dahdi_wink(p, idx)) 09978 goto quit; 09979 /* Fall through */ 09980 case SIG_EM: 09981 case SIG_EM_E1: 09982 case SIG_SF: 09983 case SIG_FGC_CAMA: 09984 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 09985 if (p->dsp) 09986 ast_dsp_digitreset(p->dsp); 09987 /* set digit mode appropriately */ 09988 if (p->dsp) { 09989 if (NEED_MFDETECT(p)) 09990 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 09991 else 09992 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 09993 } 09994 memset(dtmfbuf, 0, sizeof(dtmfbuf)); 09995 /* Wait for the first digit only if immediate=no */ 09996 if (!p->immediate) 09997 /* Wait for the first digit (up to 5 seconds). */ 09998 res = ast_waitfordigit(chan, 5000); 09999 else 10000 res = 0; 10001 if (res > 0) { 10002 /* save first char */ 10003 dtmfbuf[0] = res; 10004 switch (p->sig) { 10005 case SIG_FEATD: 10006 case SIG_SF_FEATD: 10007 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 10008 if (res > 0) 10009 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 10010 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10011 break; 10012 case SIG_FEATDMF_TA: 10013 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10014 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10015 if (dahdi_wink(p, idx)) goto quit; 10016 dtmfbuf[0] = 0; 10017 /* Wait for the first digit (up to 5 seconds). */ 10018 res = ast_waitfordigit(chan, 5000); 10019 if (res <= 0) break; 10020 dtmfbuf[0] = res; 10021 /* fall through intentionally */ 10022 case SIG_FEATDMF: 10023 case SIG_E911: 10024 case SIG_FGC_CAMAMF: 10025 case SIG_SF_FEATDMF: 10026 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10027 /* if international caca, do it again to get real ANO */ 10028 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14)) 10029 { 10030 if (dahdi_wink(p, idx)) goto quit; 10031 dtmfbuf[0] = 0; 10032 /* Wait for the first digit (up to 5 seconds). */ 10033 res = ast_waitfordigit(chan, 5000); 10034 if (res <= 0) break; 10035 dtmfbuf[0] = res; 10036 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10037 } 10038 if (res > 0) { 10039 /* if E911, take off hook */ 10040 if (p->sig == SIG_E911) 10041 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 10042 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); 10043 } 10044 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10045 break; 10046 case SIG_FEATB: 10047 case SIG_SF_FEATB: 10048 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000); 10049 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10050 break; 10051 case SIG_EMWINK: 10052 /* if we received a '*', we are actually receiving Feature Group D 10053 dial syntax, so use that mode; otherwise, fall through to normal 10054 mode 10055 */ 10056 if (res == '*') { 10057 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000); 10058 if (res > 0) 10059 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000); 10060 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); 10061 break; 10062 } 10063 default: 10064 /* If we got the first digit, get the rest */ 10065 len = 1; 10066 dtmfbuf[len] = '\0'; 10067 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 10068 if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) { 10069 timeout = matchdigittimeout; 10070 } else { 10071 timeout = gendigittimeout; 10072 } 10073 res = ast_waitfordigit(chan, timeout); 10074 if (res < 0) { 10075 ast_debug(1, "waitfordigit returned < 0...\n"); 10076 ast_hangup(chan); 10077 goto quit; 10078 } else if (res) { 10079 dtmfbuf[len++] = res; 10080 dtmfbuf[len] = '\0'; 10081 } else { 10082 break; 10083 } 10084 } 10085 break; 10086 } 10087 } 10088 if (res == -1) { 10089 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno)); 10090 ast_hangup(chan); 10091 goto quit; 10092 } else if (res < 0) { 10093 ast_debug(1, "Got hung up before digits finished\n"); 10094 ast_hangup(chan); 10095 goto quit; 10096 } 10097 10098 if (p->sig == SIG_FGC_CAMA) { 10099 char anibuf[100]; 10100 10101 if (ast_safe_sleep(chan,1000) == -1) { 10102 ast_hangup(chan); 10103 goto quit; 10104 } 10105 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 10106 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 10107 res = my_getsigstr(chan, anibuf, "#", 10000); 10108 if ((res > 0) && (strlen(anibuf) > 2)) { 10109 if (anibuf[strlen(anibuf) - 1] == '#') 10110 anibuf[strlen(anibuf) - 1] = 0; 10111 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2); 10112 } 10113 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 10114 } 10115 10116 ast_copy_string(exten, dtmfbuf, sizeof(exten)); 10117 if (ast_strlen_zero(exten)) 10118 ast_copy_string(exten, "s", sizeof(exten)); 10119 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) { 10120 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 10121 if (exten[0] == '*') { 10122 char *stringp=NULL; 10123 ast_copy_string(exten2, exten, sizeof(exten2)); 10124 /* Parse out extension and callerid */ 10125 stringp=exten2 +1; 10126 s1 = strsep(&stringp, "*"); 10127 s2 = strsep(&stringp, "*"); 10128 if (s2) { 10129 if (!ast_strlen_zero(p->cid_num)) 10130 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 10131 else 10132 ast_set_callerid(chan, s1, NULL, s1); 10133 ast_copy_string(exten, s2, sizeof(exten)); 10134 } else 10135 ast_copy_string(exten, s1, sizeof(exten)); 10136 } else if (p->sig == SIG_FEATD) 10137 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 10138 } 10139 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 10140 if (exten[0] == '*') { 10141 char *stringp=NULL; 10142 ast_copy_string(exten2, exten, sizeof(exten2)); 10143 /* Parse out extension and callerid */ 10144 stringp=exten2 +1; 10145 s1 = strsep(&stringp, "#"); 10146 s2 = strsep(&stringp, "#"); 10147 if (s2) { 10148 if (!ast_strlen_zero(p->cid_num)) 10149 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 10150 else 10151 if (*(s1 + 2)) 10152 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2); 10153 ast_copy_string(exten, s2 + 1, sizeof(exten)); 10154 } else 10155 ast_copy_string(exten, s1 + 2, sizeof(exten)); 10156 } else 10157 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel); 10158 } 10159 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) { 10160 if (exten[0] == '*') { 10161 char *stringp=NULL; 10162 ast_copy_string(exten2, exten, sizeof(exten2)); 10163 /* Parse out extension and callerid */ 10164 stringp=exten2 +1; 10165 s1 = strsep(&stringp, "#"); 10166 s2 = strsep(&stringp, "#"); 10167 if (s2 && (*(s2 + 1) == '0')) { 10168 if (*(s2 + 2)) 10169 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2); 10170 } 10171 if (s1) ast_copy_string(exten, s1, sizeof(exten)); 10172 else ast_copy_string(exten, "911", sizeof(exten)); 10173 } else 10174 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel); 10175 } 10176 if (p->sig == SIG_FEATB) { 10177 if (exten[0] == '*') { 10178 char *stringp=NULL; 10179 ast_copy_string(exten2, exten, sizeof(exten2)); 10180 /* Parse out extension and callerid */ 10181 stringp=exten2 +1; 10182 s1 = strsep(&stringp, "#"); 10183 ast_copy_string(exten, exten2 + 1, sizeof(exten)); 10184 } else 10185 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel); 10186 } 10187 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) { 10188 dahdi_wink(p, idx); 10189 /* some switches require a minimum guard time between 10190 the last FGD wink and something that answers 10191 immediately. This ensures it */ 10192 if (ast_safe_sleep(chan, 100)) { 10193 ast_hangup(chan); 10194 goto quit; 10195 } 10196 } 10197 dahdi_enable_ec(p); 10198 if (NEED_MFDETECT(p)) { 10199 if (p->dsp) { 10200 if (!p->hardwaredtmf) 10201 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 10202 else { 10203 ast_dsp_free(p->dsp); 10204 p->dsp = NULL; 10205 } 10206 } 10207 } 10208 10209 if (ast_exists_extension(chan, chan->context, exten, 1, 10210 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 10211 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 10212 if (p->dsp) ast_dsp_digitreset(p->dsp); 10213 res = ast_pbx_run(chan); 10214 if (res) { 10215 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 10216 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10217 } 10218 goto quit; 10219 } else { 10220 ast_verb(2, "Unknown extension '%s' in context '%s' requested\n", exten, chan->context); 10221 sleep(2); 10222 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_INFO); 10223 if (res < 0) 10224 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel); 10225 else 10226 sleep(1); 10227 res = ast_streamfile(chan, "ss-noservice", ast_channel_language(chan)); 10228 if (res >= 0) 10229 ast_waitstream(chan, ""); 10230 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10231 ast_hangup(chan); 10232 goto quit; 10233 } 10234 break; 10235 case SIG_FXOLS: 10236 case SIG_FXOGS: 10237 case SIG_FXOKS: 10238 /* Read the first digit */ 10239 timeout = firstdigittimeout; 10240 /* If starting a threeway call, never timeout on the first digit so someone 10241 can use flash-hook as a "hold" feature */ 10242 if (p->subs[SUB_THREEWAY].owner) 10243 timeout = 999999; 10244 while (len < AST_MAX_EXTENSION-1) { 10245 /* Read digit unless it's supposed to be immediate, in which case the 10246 only answer is 's' */ 10247 if (p->immediate) 10248 res = 's'; 10249 else 10250 res = ast_waitfordigit(chan, timeout); 10251 timeout = 0; 10252 if (res < 0) { 10253 ast_debug(1, "waitfordigit returned < 0...\n"); 10254 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 10255 ast_hangup(chan); 10256 goto quit; 10257 } else if (res) { 10258 ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout); 10259 exten[len++]=res; 10260 exten[len] = '\0'; 10261 } 10262 if (!ast_ignore_pattern(chan->context, exten)) 10263 tone_zone_play_tone(p->subs[idx].dfd, -1); 10264 else 10265 tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE); 10266 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && !ast_parking_ext_valid(exten, chan, chan->context)) { 10267 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 10268 if (getforward) { 10269 /* Record this as the forwarding extension */ 10270 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 10271 ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel); 10272 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10273 if (res) 10274 break; 10275 usleep(500000); 10276 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 10277 sleep(1); 10278 memset(exten, 0, sizeof(exten)); 10279 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE); 10280 len = 0; 10281 getforward = 0; 10282 } else { 10283 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 10284 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 10285 if (!ast_strlen_zero(p->cid_num)) { 10286 if (!p->hidecallerid) 10287 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 10288 else 10289 ast_set_callerid(chan, NULL, NULL, p->cid_num); 10290 } 10291 if (!ast_strlen_zero(p->cid_name)) { 10292 if (!p->hidecallerid) 10293 ast_set_callerid(chan, NULL, p->cid_name, NULL); 10294 } 10295 ast_setstate(chan, AST_STATE_RING); 10296 dahdi_enable_ec(p); 10297 res = ast_pbx_run(chan); 10298 if (res) { 10299 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 10300 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10301 } 10302 goto quit; 10303 } 10304 } else { 10305 /* It's a match, but they just typed a digit, and there is an ambiguous match, 10306 so just set the timeout to matchdigittimeout and wait some more */ 10307 timeout = matchdigittimeout; 10308 } 10309 } else if (res == 0) { 10310 ast_debug(1, "not enough digits (and no ambiguous match)...\n"); 10311 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10312 dahdi_wait_event(p->subs[idx].dfd); 10313 ast_hangup(chan); 10314 goto quit; 10315 } else if (p->callwaiting && !strcmp(exten, "*70")) { 10316 ast_verb(3, "Disabling call waiting on %s\n", ast_channel_name(chan)); 10317 /* Disable call waiting if enabled */ 10318 p->callwaiting = 0; 10319 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10320 if (res) { 10321 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 10322 ast_channel_name(chan), strerror(errno)); 10323 } 10324 len = 0; 10325 ioctl(p->subs[idx].dfd,DAHDI_CONFDIAG,&len); 10326 memset(exten, 0, sizeof(exten)); 10327 timeout = firstdigittimeout; 10328 10329 } else if (!strcmp(exten,ast_pickup_ext())) { 10330 /* Scan all channels and see if there are any 10331 * ringing channels that have call groups 10332 * that equal this channels pickup group 10333 */ 10334 if (idx == SUB_REAL) { 10335 /* Switch us from Third call to Call Wait */ 10336 if (p->subs[SUB_THREEWAY].owner) { 10337 /* If you make a threeway call and the *8# a call, it should actually 10338 look like a callwait */ 10339 alloc_sub(p, SUB_CALLWAIT); 10340 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 10341 unalloc_sub(p, SUB_THREEWAY); 10342 } 10343 dahdi_enable_ec(p); 10344 if (ast_pickup_call(chan)) { 10345 ast_debug(1, "No call pickup possible...\n"); 10346 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10347 dahdi_wait_event(p->subs[idx].dfd); 10348 } 10349 ast_hangup(chan); 10350 goto quit; 10351 } else { 10352 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n"); 10353 ast_hangup(chan); 10354 goto quit; 10355 } 10356 10357 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 10358 ast_verb(3, "Disabling Caller*ID on %s\n", ast_channel_name(chan)); 10359 /* Disable Caller*ID if enabled */ 10360 p->hidecallerid = 1; 10361 ast_party_number_free(&chan->caller.id.number); 10362 ast_party_number_init(&chan->caller.id.number); 10363 ast_party_name_free(&chan->caller.id.name); 10364 ast_party_name_init(&chan->caller.id.name); 10365 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10366 if (res) { 10367 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 10368 ast_channel_name(chan), strerror(errno)); 10369 } 10370 len = 0; 10371 memset(exten, 0, sizeof(exten)); 10372 timeout = firstdigittimeout; 10373 } else if (p->callreturn && !strcmp(exten, "*69")) { 10374 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10375 break; 10376 } else if (!strcmp(exten, "*78")) { 10377 dahdi_dnd(p, 1); 10378 /* Do not disturb */ 10379 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10380 getforward = 0; 10381 memset(exten, 0, sizeof(exten)); 10382 len = 0; 10383 } else if (!strcmp(exten, "*79")) { 10384 dahdi_dnd(p, 0); 10385 /* Do not disturb */ 10386 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10387 getforward = 0; 10388 memset(exten, 0, sizeof(exten)); 10389 len = 0; 10390 } else if (p->cancallforward && !strcmp(exten, "*72")) { 10391 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10392 getforward = 1; 10393 memset(exten, 0, sizeof(exten)); 10394 len = 0; 10395 } else if (p->cancallforward && !strcmp(exten, "*73")) { 10396 ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel); 10397 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10398 memset(p->call_forward, 0, sizeof(p->call_forward)); 10399 getforward = 0; 10400 memset(exten, 0, sizeof(exten)); 10401 len = 0; 10402 } else if ((p->transfer || p->canpark) && ast_parking_ext_valid(exten, chan, chan->context) && 10403 p->subs[SUB_THREEWAY].owner && 10404 ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 10405 /* This is a three way call, the main call being a real channel, 10406 and we're parking the first call. */ 10407 ast_masq_park_call_exten(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), 10408 chan, exten, chan->context, 0, NULL); 10409 ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan)); 10410 break; 10411 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 10412 ast_verb(3, "Enabling Caller*ID on %s\n", ast_channel_name(chan)); 10413 /* Enable Caller*ID if enabled */ 10414 p->hidecallerid = 0; 10415 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 10416 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL); 10417 if (res) { 10418 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 10419 ast_channel_name(chan), strerror(errno)); 10420 } 10421 len = 0; 10422 memset(exten, 0, sizeof(exten)); 10423 timeout = firstdigittimeout; 10424 } else if (!strcmp(exten, "*0")) { 10425 struct ast_channel *nbridge = 10426 p->subs[SUB_THREEWAY].owner; 10427 struct dahdi_pvt *pbridge = NULL; 10428 /* set up the private struct of the bridged one, if any */ 10429 if (nbridge && ast_bridged_channel(nbridge)) 10430 pbridge = ast_bridged_channel(nbridge)->tech_pvt; 10431 if (nbridge && pbridge && 10432 (nbridge->tech == &dahdi_tech) && 10433 (ast_bridged_channel(nbridge)->tech == &dahdi_tech) && 10434 ISTRUNK(pbridge)) { 10435 int func = DAHDI_FLASH; 10436 /* Clear out the dial buffer */ 10437 p->dop.dialstr[0] = '\0'; 10438 /* flash hookswitch */ 10439 if ((ioctl(pbridge->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 10440 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 10441 ast_channel_name(nbridge), strerror(errno)); 10442 } 10443 swap_subs(p, SUB_REAL, SUB_THREEWAY); 10444 unalloc_sub(p, SUB_THREEWAY); 10445 p->owner = p->subs[SUB_REAL].owner; 10446 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 10447 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 10448 ast_hangup(chan); 10449 goto quit; 10450 } else { 10451 tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 10452 dahdi_wait_event(p->subs[idx].dfd); 10453 tone_zone_play_tone(p->subs[idx].dfd, -1); 10454 swap_subs(p, SUB_REAL, SUB_THREEWAY); 10455 unalloc_sub(p, SUB_THREEWAY); 10456 p->owner = p->subs[SUB_REAL].owner; 10457 ast_hangup(chan); 10458 goto quit; 10459 } 10460 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, 10461 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)) 10462 && !canmatch_featurecode(exten)) { 10463 ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, 10464 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<Unknown Caller>"), 10465 chan->context); 10466 break; 10467 } 10468 if (!timeout) 10469 timeout = gendigittimeout; 10470 if (len && !ast_ignore_pattern(chan->context, exten)) 10471 tone_zone_play_tone(p->subs[idx].dfd, -1); 10472 } 10473 break; 10474 case SIG_FXSLS: 10475 case SIG_FXSGS: 10476 case SIG_FXSKS: 10477 /* check for SMDI messages */ 10478 if (p->use_smdi && p->smdi_iface) { 10479 smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT); 10480 10481 if (smdi_msg != NULL) { 10482 ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten)); 10483 10484 if (smdi_msg->type == 'B') 10485 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b"); 10486 else if (smdi_msg->type == 'N') 10487 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u"); 10488 10489 ast_debug(1, "Received SMDI message on %s\n", ast_channel_name(chan)); 10490 } else { 10491 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n"); 10492 } 10493 } 10494 10495 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) { 10496 number = smdi_msg->calling_st; 10497 10498 /* If we want caller id, we're in a prering state due to a polarity reversal 10499 * and we're set to use a polarity reversal to trigger the start of caller id, 10500 * grab the caller id and wait for ringing to start... */ 10501 } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && 10502 (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_POLARITY_IN || p->cid_start == CID_START_DTMF_NOALERT))) { 10503 /* If set to use DTMF CID signalling, listen for DTMF */ 10504 if (p->cid_signalling == CID_SIG_DTMF) { 10505 int k = 0; 10506 cs = NULL; 10507 ast_debug(1, "Receiving DTMF cid on channel %s\n", ast_channel_name(chan)); 10508 dahdi_setlinear(p->subs[idx].dfd, 0); 10509 /* 10510 * We are the only party interested in the Rx stream since 10511 * we have not answered yet. We don't need or even want DTMF 10512 * emulation. The DTMF digits can come so fast that emulation 10513 * can drop some of them. 10514 */ 10515 ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); 10516 res = 4000;/* This is a typical OFF time between rings. */ 10517 for (;;) { 10518 struct ast_frame *f; 10519 res = ast_waitfor(chan, res); 10520 if (res <= 0) { 10521 /* 10522 * We do not need to restore the dahdi_setlinear() 10523 * or AST_FLAG_END_DTMF_ONLY flag settings since we 10524 * are hanging up the channel. 10525 */ 10526 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 10527 "Exiting simple switch\n"); 10528 ast_hangup(chan); 10529 goto quit; 10530 } 10531 f = ast_read(chan); 10532 if (!f) 10533 break; 10534 if (f->frametype == AST_FRAME_DTMF) { 10535 if (k < ARRAY_LEN(dtmfbuf) - 1) { 10536 dtmfbuf[k++] = f->subclass.integer; 10537 } 10538 ast_debug(1, "CID got digit '%c'\n", f->subclass.integer); 10539 res = 4000;/* This is a typical OFF time between rings. */ 10540 } 10541 ast_frfree(f); 10542 if (chan->_state == AST_STATE_RING || 10543 chan->_state == AST_STATE_RINGING) 10544 break; /* Got ring */ 10545 } 10546 ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); 10547 dtmfbuf[k] = '\0'; 10548 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10549 /* Got cid and ring. */ 10550 ast_debug(1, "CID got string '%s'\n", dtmfbuf); 10551 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 10552 ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags); 10553 /* If first byte is NULL, we have no cid */ 10554 if (!ast_strlen_zero(dtmfcid)) 10555 number = dtmfcid; 10556 else 10557 number = NULL; 10558 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 10559 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) { 10560 cs = callerid_new(p->cid_signalling); 10561 if (cs) { 10562 samples = 0; 10563 #if 1 10564 bump_gains(p); 10565 #endif 10566 /* Take out of linear mode for Caller*ID processing */ 10567 dahdi_setlinear(p->subs[idx].dfd, 0); 10568 10569 /* First we wait and listen for the Caller*ID */ 10570 for (;;) { 10571 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10572 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10573 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10574 callerid_free(cs); 10575 ast_hangup(chan); 10576 goto quit; 10577 } 10578 if (i & DAHDI_IOMUX_SIGEVENT) { 10579 res = dahdi_get_event(p->subs[idx].dfd); 10580 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10581 if (res == DAHDI_EVENT_NOALARM) { 10582 p->inalarm = 0; 10583 } 10584 10585 if (p->cid_signalling == CID_SIG_V23_JP) { 10586 if (res == DAHDI_EVENT_RINGBEGIN) { 10587 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 10588 usleep(1); 10589 } 10590 } else { 10591 res = 0; 10592 break; 10593 } 10594 } else if (i & DAHDI_IOMUX_READ) { 10595 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10596 if (res < 0) { 10597 if (errno != ELAST) { 10598 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10599 callerid_free(cs); 10600 ast_hangup(chan); 10601 goto quit; 10602 } 10603 break; 10604 } 10605 samples += res; 10606 10607 if (p->cid_signalling == CID_SIG_V23_JP) { 10608 res = callerid_feed_jp(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0)); 10609 } else { 10610 res = callerid_feed(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0)); 10611 } 10612 if (res < 0) { 10613 /* 10614 * The previous diagnostic message output likely 10615 * explains why it failed. 10616 */ 10617 ast_log(LOG_WARNING, 10618 "Failed to decode CallerID on channel '%s'\n", 10619 ast_channel_name(chan)); 10620 break; 10621 } else if (res) 10622 break; 10623 else if (samples > (8000 * 10)) 10624 break; 10625 } 10626 } 10627 if (res == 1) { 10628 callerid_get(cs, &name, &number, &flags); 10629 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 10630 } 10631 10632 if (p->cid_signalling == CID_SIG_V23_JP) { 10633 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 10634 usleep(1); 10635 } 10636 10637 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 10638 res = 4000;/* This is a typical OFF time between rings. */ 10639 for (;;) { 10640 struct ast_frame *f; 10641 res = ast_waitfor(chan, res); 10642 if (res <= 0) { 10643 ast_log(LOG_WARNING, "CID timed out waiting for ring. " 10644 "Exiting simple switch\n"); 10645 ast_hangup(chan); 10646 goto quit; 10647 } 10648 if (!(f = ast_read(chan))) { 10649 ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n"); 10650 ast_hangup(chan); 10651 goto quit; 10652 } 10653 ast_frfree(f); 10654 if (chan->_state == AST_STATE_RING || 10655 chan->_state == AST_STATE_RINGING) 10656 break; /* Got ring */ 10657 } 10658 10659 /* We must have a ring by now, so, if configured, lets try to listen for 10660 * distinctive ringing */ 10661 if (p->usedistinctiveringdetection) { 10662 len = 0; 10663 distMatches = 0; 10664 /* Clear the current ring data array so we don't have old data in it. */ 10665 for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++) 10666 curRingData[receivedRingT] = 0; 10667 receivedRingT = 0; 10668 counter = 0; 10669 counter1 = 0; 10670 /* Check to see if context is what it should be, if not set to be. */ 10671 if (strcmp(p->context,p->defcontext) != 0) { 10672 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 10673 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 10674 } 10675 10676 for (;;) { 10677 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10678 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10679 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10680 callerid_free(cs); 10681 ast_hangup(chan); 10682 goto quit; 10683 } 10684 if (i & DAHDI_IOMUX_SIGEVENT) { 10685 res = dahdi_get_event(p->subs[idx].dfd); 10686 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10687 if (res == DAHDI_EVENT_NOALARM) { 10688 p->inalarm = 0; 10689 } 10690 res = 0; 10691 /* Let us detect distinctive ring */ 10692 10693 curRingData[receivedRingT] = p->ringt; 10694 10695 if (p->ringt < p->ringt_base/2) 10696 break; 10697 /* Increment the ringT counter so we can match it against 10698 values in chan_dahdi.conf for distinctive ring */ 10699 if (++receivedRingT == ARRAY_LEN(curRingData)) 10700 break; 10701 } else if (i & DAHDI_IOMUX_READ) { 10702 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10703 if (res < 0) { 10704 if (errno != ELAST) { 10705 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10706 callerid_free(cs); 10707 ast_hangup(chan); 10708 goto quit; 10709 } 10710 break; 10711 } 10712 if (p->ringt > 0) { 10713 if (!(--p->ringt)) { 10714 res = -1; 10715 break; 10716 } 10717 } 10718 } 10719 } 10720 /* this only shows up if you have n of the dring patterns filled in */ 10721 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 10722 for (counter = 0; counter < 3; counter++) { 10723 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this 10724 channel */ 10725 distMatches = 0; 10726 for (counter1 = 0; counter1 < 3; counter1++) { 10727 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 10728 if (p->drings.ringnum[counter].ring[counter1] == -1) { 10729 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 10730 curRingData[counter1]); 10731 distMatches++; 10732 } else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 10733 curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 10734 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 10735 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 10736 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 10737 distMatches++; 10738 } 10739 } 10740 10741 if (distMatches == 3) { 10742 /* The ring matches, set the context to whatever is for distinctive ring.. */ 10743 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 10744 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 10745 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 10746 break; 10747 } 10748 } 10749 } 10750 /* Restore linear mode (if appropriate) for Caller*ID processing */ 10751 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10752 #if 1 10753 restore_gains(p); 10754 #endif 10755 } else 10756 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 10757 } else { 10758 ast_log(LOG_WARNING, "Channel %s in prering " 10759 "state, but I have nothing to do. " 10760 "Terminating simple switch, should be " 10761 "restarted by the actual ring.\n", 10762 ast_channel_name(chan)); 10763 ast_hangup(chan); 10764 goto quit; 10765 } 10766 } else if (p->use_callerid && p->cid_start == CID_START_RING) { 10767 if (p->cid_signalling == CID_SIG_DTMF) { 10768 int k = 0; 10769 cs = NULL; 10770 dahdi_setlinear(p->subs[idx].dfd, 0); 10771 res = 2000; 10772 for (;;) { 10773 struct ast_frame *f; 10774 res = ast_waitfor(chan, res); 10775 if (res <= 0) { 10776 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. " 10777 "Exiting simple switch\n"); 10778 ast_hangup(chan); 10779 goto quit; 10780 } 10781 f = ast_read(chan); 10782 if (!f) { 10783 /* Hangup received waiting for DTMFCID. Exiting simple switch. */ 10784 ast_hangup(chan); 10785 goto quit; 10786 } 10787 if (f->frametype == AST_FRAME_DTMF) { 10788 dtmfbuf[k++] = f->subclass.integer; 10789 ast_debug(1, "CID got digit '%c'\n", f->subclass.integer); 10790 res = 2000; 10791 } 10792 ast_frfree(f); 10793 10794 if (p->ringt_base == p->ringt) 10795 break; 10796 } 10797 dtmfbuf[k] = '\0'; 10798 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10799 /* Got cid and ring. */ 10800 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags); 10801 ast_debug(1, "CID is '%s', flags %d\n", 10802 dtmfcid, flags); 10803 /* If first byte is NULL, we have no cid */ 10804 if (!ast_strlen_zero(dtmfcid)) 10805 number = dtmfcid; 10806 else 10807 number = NULL; 10808 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 10809 } else { 10810 /* FSK Bell202 callerID */ 10811 cs = callerid_new(p->cid_signalling); 10812 if (cs) { 10813 #if 1 10814 bump_gains(p); 10815 #endif 10816 samples = 0; 10817 len = 0; 10818 distMatches = 0; 10819 /* Clear the current ring data array so we don't have old data in it. */ 10820 for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++) 10821 curRingData[receivedRingT] = 0; 10822 receivedRingT = 0; 10823 counter = 0; 10824 counter1 = 0; 10825 /* Check to see if context is what it should be, if not set to be. */ 10826 if (strcmp(p->context,p->defcontext) != 0) { 10827 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 10828 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 10829 } 10830 10831 /* Take out of linear mode for Caller*ID processing */ 10832 dahdi_setlinear(p->subs[idx].dfd, 0); 10833 for (;;) { 10834 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10835 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10836 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10837 callerid_free(cs); 10838 ast_hangup(chan); 10839 goto quit; 10840 } 10841 if (i & DAHDI_IOMUX_SIGEVENT) { 10842 res = dahdi_get_event(p->subs[idx].dfd); 10843 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10844 if (res == DAHDI_EVENT_NOALARM) { 10845 p->inalarm = 0; 10846 } 10847 /* If we get a PR event, they hung up while processing calerid */ 10848 if ( res == DAHDI_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) { 10849 ast_debug(1, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel); 10850 p->polarity = POLARITY_IDLE; 10851 callerid_free(cs); 10852 ast_hangup(chan); 10853 goto quit; 10854 } 10855 res = 0; 10856 /* Let us detect callerid when the telco uses distinctive ring */ 10857 10858 curRingData[receivedRingT] = p->ringt; 10859 10860 if (p->ringt < p->ringt_base/2) 10861 break; 10862 /* Increment the ringT counter so we can match it against 10863 values in chan_dahdi.conf for distinctive ring */ 10864 if (++receivedRingT == ARRAY_LEN(curRingData)) 10865 break; 10866 } else if (i & DAHDI_IOMUX_READ) { 10867 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10868 if (res < 0) { 10869 if (errno != ELAST) { 10870 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10871 callerid_free(cs); 10872 ast_hangup(chan); 10873 goto quit; 10874 } 10875 break; 10876 } 10877 if (p->ringt > 0) { 10878 if (!(--p->ringt)) { 10879 res = -1; 10880 break; 10881 } 10882 } 10883 samples += res; 10884 res = callerid_feed(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0)); 10885 if (res < 0) { 10886 /* 10887 * The previous diagnostic message output likely 10888 * explains why it failed. 10889 */ 10890 ast_log(LOG_WARNING, 10891 "Failed to decode CallerID on channel '%s'\n", 10892 ast_channel_name(chan)); 10893 break; 10894 } else if (res) 10895 break; 10896 else if (samples > (8000 * 10)) 10897 break; 10898 } 10899 } 10900 if (res == 1) { 10901 callerid_get(cs, &name, &number, &flags); 10902 ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags); 10903 } 10904 if (distinctiveringaftercid == 1) { 10905 /* Clear the current ring data array so we don't have old data in it. */ 10906 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) { 10907 curRingData[receivedRingT] = 0; 10908 } 10909 receivedRingT = 0; 10910 ast_verb(3, "Detecting post-CID distinctive ring\n"); 10911 for (;;) { 10912 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 10913 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 10914 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 10915 callerid_free(cs); 10916 ast_hangup(chan); 10917 goto quit; 10918 } 10919 if (i & DAHDI_IOMUX_SIGEVENT) { 10920 res = dahdi_get_event(p->subs[idx].dfd); 10921 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 10922 if (res == DAHDI_EVENT_NOALARM) { 10923 p->inalarm = 0; 10924 } 10925 res = 0; 10926 /* Let us detect callerid when the telco uses distinctive ring */ 10927 10928 curRingData[receivedRingT] = p->ringt; 10929 10930 if (p->ringt < p->ringt_base/2) 10931 break; 10932 /* Increment the ringT counter so we can match it against 10933 values in chan_dahdi.conf for distinctive ring */ 10934 if (++receivedRingT == ARRAY_LEN(curRingData)) 10935 break; 10936 } else if (i & DAHDI_IOMUX_READ) { 10937 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 10938 if (res < 0) { 10939 if (errno != ELAST) { 10940 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 10941 callerid_free(cs); 10942 ast_hangup(chan); 10943 goto quit; 10944 } 10945 break; 10946 } 10947 if (p->ringt > 0) { 10948 if (!(--p->ringt)) { 10949 res = -1; 10950 break; 10951 } 10952 } 10953 } 10954 } 10955 } 10956 if (p->usedistinctiveringdetection) { 10957 /* this only shows up if you have n of the dring patterns filled in */ 10958 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]); 10959 10960 for (counter = 0; counter < 3; counter++) { 10961 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this 10962 channel */ 10963 /* this only shows up if you have n of the dring patterns filled in */ 10964 ast_verb(3, "Checking %d,%d,%d\n", 10965 p->drings.ringnum[counter].ring[0], 10966 p->drings.ringnum[counter].ring[1], 10967 p->drings.ringnum[counter].ring[2]); 10968 distMatches = 0; 10969 for (counter1 = 0; counter1 < 3; counter1++) { 10970 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 10971 if (p->drings.ringnum[counter].ring[counter1] == -1) { 10972 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 10973 curRingData[counter1]); 10974 distMatches++; 10975 } 10976 else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 10977 curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 10978 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 10979 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 10980 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 10981 distMatches++; 10982 } 10983 } 10984 if (distMatches == 3) { 10985 /* The ring matches, set the context to whatever is for distinctive ring.. */ 10986 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 10987 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 10988 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 10989 break; 10990 } 10991 } 10992 } 10993 /* Restore linear mode (if appropriate) for Caller*ID processing */ 10994 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 10995 #if 1 10996 restore_gains(p); 10997 #endif 10998 if (res < 0) { 10999 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", ast_channel_name(chan)); 11000 } 11001 } else 11002 ast_log(LOG_WARNING, "Unable to get caller ID space\n"); 11003 } 11004 } else 11005 cs = NULL; 11006 11007 if (number) 11008 ast_shrink_phone_number(number); 11009 ast_set_callerid(chan, number, name, number); 11010 11011 if (smdi_msg) 11012 ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy); 11013 11014 if (cs) 11015 callerid_free(cs); 11016 11017 my_handle_notify_message(chan, p, flags, -1); 11018 11019 ast_setstate(chan, AST_STATE_RING); 11020 chan->rings = 1; 11021 p->ringt = p->ringt_base; 11022 res = ast_pbx_run(chan); 11023 if (res) { 11024 ast_hangup(chan); 11025 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 11026 } 11027 goto quit; 11028 default: 11029 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel); 11030 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 11031 if (res < 0) 11032 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 11033 } 11034 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION); 11035 if (res < 0) 11036 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel); 11037 ast_hangup(chan); 11038 quit: 11039 ast_mutex_lock(&ss_thread_lock); 11040 ss_thread_count--; 11041 ast_cond_signal(&ss_thread_complete); 11042 ast_mutex_unlock(&ss_thread_lock); 11043 return NULL; 11044 }
| static int analog_tone_to_dahditone | ( | enum analog_tone | tone | ) | [static] |
Definition at line 1634 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().
01635 { 01636 switch (tone) { 01637 case ANALOG_TONE_RINGTONE: 01638 return DAHDI_TONE_RINGTONE; 01639 case ANALOG_TONE_STUTTER: 01640 return DAHDI_TONE_STUTTER; 01641 case ANALOG_TONE_CONGESTION: 01642 return DAHDI_TONE_CONGESTION; 01643 case ANALOG_TONE_DIALTONE: 01644 return DAHDI_TONE_DIALTONE; 01645 case ANALOG_TONE_DIALRECALL: 01646 return DAHDI_TONE_DIALRECALL; 01647 case ANALOG_TONE_INFO: 01648 return DAHDI_TONE_INFO; 01649 default: 01650 return -1; 01651 } 01652 }
| static int analogsub_to_dahdisub | ( | enum analog_sub | analogsub | ) | [static] |
Definition at line 1654 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().
01655 { 01656 int index; 01657 01658 switch (analogsub) { 01659 case ANALOG_SUB_REAL: 01660 index = SUB_REAL; 01661 break; 01662 case ANALOG_SUB_CALLWAIT: 01663 index = SUB_CALLWAIT; 01664 break; 01665 case ANALOG_SUB_THREEWAY: 01666 index = SUB_THREEWAY; 01667 break; 01668 default: 01669 ast_log(LOG_ERROR, "Unidentified sub!\n"); 01670 index = SUB_REAL; 01671 } 01672 01673 return index; 01674 }
| AST_DATA_STRUCTURE | ( | dahdi_pvt | , | |
| DATA_EXPORT_DAHDI_PVT | ||||
| ) |
| static int attempt_transfer | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7677 of file chan_dahdi.c.
References ast_channel::_softhangup, ast_channel::_state, ast_bridged_channel(), ast_channel_masquerade(), ast_channel_name(), 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 close_call(), dahdi_handle_event(), handle_request(), and local_attended_transfer().
07678 { 07679 /* In order to transfer, we need at least one of the channels to 07680 actually be in a call bridge. We can't conference two applications 07681 together (but then, why would we want to?) */ 07682 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 07683 /* The three-way person we're about to transfer to could still be in MOH, so 07684 stop if now if appropriate */ 07685 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) 07686 ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD); 07687 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) { 07688 ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING); 07689 } 07690 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) { 07691 tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, DAHDI_TONE_RINGTONE); 07692 } 07693 if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) { 07694 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 07695 ast_channel_name(ast_bridged_channel(p->subs[SUB_REAL].owner)), ast_channel_name(p->subs[SUB_THREEWAY].owner)); 07696 return -1; 07697 } 07698 /* Orphan the channel after releasing the lock */ 07699 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 07700 unalloc_sub(p, SUB_THREEWAY); 07701 } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 07702 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 07703 if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) { 07704 ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING); 07705 } 07706 if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) { 07707 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 07708 } 07709 if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) { 07710 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 07711 ast_channel_name(ast_bridged_channel(p->subs[SUB_THREEWAY].owner)), ast_channel_name(p->subs[SUB_REAL].owner)); 07712 return -1; 07713 } 07714 /* Three-way is now the REAL */ 07715 swap_subs(p, SUB_THREEWAY, SUB_REAL); 07716 ast_channel_unlock(p->subs[SUB_REAL].owner); 07717 unalloc_sub(p, SUB_THREEWAY); 07718 /* Tell the caller not to hangup */ 07719 return 1; 07720 } else { 07721 ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n", 07722 ast_channel_name(p->subs[SUB_REAL].owner), ast_channel_name(p->subs[SUB_THREEWAY].owner)); 07723 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 07724 return -1; 07725 } 07726 return 0; 07727 }
| static int available | ( | struct dahdi_pvt ** | pvt, | |
| int | is_specific_channel | |||
| ) | [static] |
Definition at line 13222 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().
13223 { 13224 struct dahdi_pvt *p = *pvt; 13225 13226 if (p->inalarm) 13227 return 0; 13228 13229 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) 13230 return analog_available(p->sig_pvt); 13231 13232 switch (p->sig) { 13233 #if defined(HAVE_PRI) 13234 case SIG_PRI_LIB_HANDLE_CASES: 13235 { 13236 struct sig_pri_chan *pvt_chan; 13237 int res; 13238 13239 pvt_chan = p->sig_pvt; 13240 res = sig_pri_available(&pvt_chan, is_specific_channel); 13241 *pvt = pvt_chan->chan_pvt; 13242 return res; 13243 } 13244 #endif /* defined(HAVE_PRI) */ 13245 #if defined(HAVE_SS7) 13246 case SIG_SS7: 13247 return sig_ss7_available(p->sig_pvt); 13248 #endif /* defined(HAVE_SS7) */ 13249 default: 13250 break; 13251 } 13252 13253 if (p->locallyblocked || p->remotelyblocked) { 13254 return 0; 13255 } 13256 13257 /* If no owner definitely available */ 13258 if (!p->owner) { 13259 #ifdef HAVE_OPENR2 13260 /* Trust MFC/R2 */ 13261 if (p->mfcr2) { 13262 if (p->mfcr2call) { 13263 return 0; 13264 } else { 13265 return 1; 13266 } 13267 } 13268 #endif 13269 return 1; 13270 } 13271 13272 return 0; 13273 }
| static int build_channels | ( | struct dahdi_chan_conf * | conf, | |
| const char * | value, | |||
| int | reload, | |||
| int | lineno, | |||
| int * | found_pseudo | |||
| ) | [static] |
Definition at line 16895 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, sig2str, and strsep().
Referenced by process_dahdi().
16896 { 16897 char *c, *chan; 16898 char *subdir; 16899 int x, start, finish; 16900 struct dahdi_pvt *tmp; 16901 16902 if ((reload == 0) && (conf->chan.sig < 0) && !conf->is_sig_auto) { 16903 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n"); 16904 return -1; 16905 } 16906 16907 c = ast_strdupa(value); 16908 c = parse_spanchan(c, &subdir); 16909 16910 while ((chan = strsep(&c, ","))) { 16911 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) { 16912 /* Range */ 16913 } else if (sscanf(chan, "%30d", &start)) { 16914 /* Just one */ 16915 finish = start; 16916 } else if (!strcasecmp(chan, "pseudo")) { 16917 finish = start = CHAN_PSEUDO; 16918 if (found_pseudo) 16919 *found_pseudo = 1; 16920 } else { 16921 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan); 16922 return -1; 16923 } 16924 if (finish < start) { 16925 ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish); 16926 x = finish; 16927 finish = start; 16928 start = x; 16929 } 16930 16931 for (x = start; x <= finish; x++) { 16932 char fn[PATH_MAX]; 16933 int real_channel = x; 16934 16935 if (!ast_strlen_zero(subdir)) { 16936 real_channel = device2chan(subdir, x, fn, sizeof(fn)); 16937 if (real_channel < 0) { 16938 if (conf->ignore_failed_channels) { 16939 ast_log(LOG_WARNING, "Failed configuring %s!%d, (got %d). But moving on to others.\n", 16940 subdir, x, real_channel); 16941 continue; 16942 } else { 16943 ast_log(LOG_ERROR, "Failed configuring %s!%d, (got %d).\n", 16944 subdir, x, real_channel); 16945 return -1; 16946 } 16947 } 16948 } 16949 tmp = mkintf(real_channel, conf, reload); 16950 16951 if (tmp) { 16952 ast_verb(3, "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", real_channel, sig2str(tmp->sig)); 16953 } else { 16954 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n", 16955 (reload == 1) ? "reconfigure" : "register", value); 16956 return -1; 16957 } 16958 } 16959 } 16960 16961 return 0; 16962 }
| static int bump_gains | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5122 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().
05123 { 05124 int res; 05125 05126 /* Bump receive gain by value stored in cid_rxgain */ 05127 res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain + p->cid_rxgain, p->txgain, p->rxdrc, p->txdrc, p->law); 05128 if (res) { 05129 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno)); 05130 return -1; 05131 } 05132 05133 return 0; 05134 }
| static int calc_energy | ( | const unsigned char * | buf, | |
| int | len, | |||
| enum ast_format_id | law | |||
| ) | [static] |
Definition at line 11052 of file chan_dahdi.c.
References AST_ALAW, AST_FORMAT_ULAW, and AST_MULAW.
Referenced by do_monitor(), and mwi_thread().
11053 { 11054 int x; 11055 int sum = 0; 11056 11057 if (!len) 11058 return 0; 11059 11060 for (x = 0; x < len; x++) 11061 sum += abs(law == AST_FORMAT_ULAW ? AST_MULAW(buf[x]) : AST_ALAW(buf[x])); 11062 11063 return sum / len; 11064 }
| static int canmatch_featurecode | ( | const char * | exten | ) | [static] |
Definition at line 9890 of file chan_dahdi.c.
References ast_pickup_ext(), and pickup_ext.
Referenced by analog_ss_thread().
09891 { 09892 int extlen = strlen(exten); 09893 const char *pickup_ext; 09894 if (!extlen) { 09895 return 1; 09896 } 09897 pickup_ext = ast_pickup_ext(); 09898 if (extlen < strlen(pickup_ext) && !strncmp(pickup_ext, exten, extlen)) { 09899 return 1; 09900 } 09901 /* hardcoded features are *60, *67, *69, *70, *72, *73, *78, *79, *82, *0 */ 09902 if (exten[0] == '*' && extlen < 3) { 09903 if (extlen == 1) { 09904 return 1; 09905 } 09906 /* "*0" should be processed before it gets here */ 09907 switch (exten[1]) { 09908 case '6': 09909 case '7': 09910 case '8': 09911 return 1; 09912 } 09913 } 09914 return 0; 09915 }
| static int check_for_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7729 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().
07730 { 07731 struct dahdi_confinfo ci; 07732 /* Fine if we already have a master, etc */ 07733 if (p->master || (p->confno > -1)) 07734 return 0; 07735 memset(&ci, 0, sizeof(ci)); 07736 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) { 07737 ast_log(LOG_WARNING, "Failed to get conference info on channel %d: %s\n", p->channel, strerror(errno)); 07738 return 0; 07739 } 07740 /* If we have no master and don't have a confno, then 07741 if we're in a conference, it's probably a MeetMe room or 07742 some such, so don't let us 3-way out! */ 07743 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) { 07744 ast_verb(3, "Avoiding 3-way call when in an external conference\n"); 07745 return 1; 07746 } 07747 return 0; 07748 }
| static int conf_add | ( | struct dahdi_pvt * | p, | |
| struct dahdi_subchannel * | c, | |||
| int | index, | |||
| int | slavechannel | |||
| ) | [static] |
Definition at line 4704 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().
04705 { 04706 /* If the conference already exists, and we're already in it 04707 don't bother doing anything */ 04708 struct dahdi_confinfo zi; 04709 04710 memset(&zi, 0, sizeof(zi)); 04711 zi.chan = 0; 04712 04713 if (slavechannel > 0) { 04714 /* If we have only one slave, do a digital mon */ 04715 zi.confmode = DAHDI_CONF_DIGITALMON; 04716 zi.confno = slavechannel; 04717 } else { 04718 if (!idx) { 04719 /* Real-side and pseudo-side both participate in conference */ 04720 zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER | 04721 DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER; 04722 } else 04723 zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER; 04724 zi.confno = p->confno; 04725 } 04726 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode)) 04727 return 0; 04728 if (c->dfd < 0) 04729 return 0; 04730 if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) { 04731 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno)); 04732 return -1; 04733 } 04734 if (slavechannel < 1) { 04735 p->confno = zi.confno; 04736 } 04737 c->curconf = zi; 04738 ast_debug(1, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno); 04739 return 0; 04740 }
| static int conf_del | ( | struct dahdi_pvt * | p, | |
| struct dahdi_subchannel * | c, | |||
| int | index | |||
| ) | [static] |
Definition at line 4753 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().
04754 { 04755 struct dahdi_confinfo zi; 04756 if (/* Can't delete if there's no dfd */ 04757 (c->dfd < 0) || 04758 /* Don't delete from the conference if it's not our conference */ 04759 !isourconf(p, c) 04760 /* Don't delete if we don't think it's conferenced at all (implied) */ 04761 ) return 0; 04762 memset(&zi, 0, sizeof(zi)); 04763 if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) { 04764 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno)); 04765 return -1; 04766 } 04767 ast_debug(1, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno); 04768 memcpy(&c->curconf, &zi, sizeof(c->curconf)); 04769 return 0; 04770 }
Definition at line 9555 of file chan_dahdi.c.
References ast_channel_name(), 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().
09557 { 09558 struct ast_str *chan_name; 09559 int x, y; 09560 09561 /* Create the new channel name tail. */ 09562 if (!(chan_name = ast_str_create(32))) { 09563 return NULL; 09564 } 09565 if (i->channel == CHAN_PSEUDO) { 09566 ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random()); 09567 #if defined(HAVE_PRI) 09568 } else if (i->pri) { 09569 ast_mutex_lock(&i->pri->lock); 09570 y = ++i->pri->new_chan_seq; 09571 if (is_outgoing) { 09572 ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, address, y); 09573 address[0] = '\0'; 09574 } else if (ast_strlen_zero(i->cid_subaddr)) { 09575 /* Put in caller-id number only since there is no subaddress. */ 09576 ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, i->cid_num, y); 09577 } else { 09578 /* Put in caller-id number and subaddress. */ 09579 ast_str_set(&chan_name, 0, "i%d/%s:%s-%x", i->pri->span, i->cid_num, 09580 i->cid_subaddr, y); 09581 } 09582 ast_mutex_unlock(&i->pri->lock); 09583 #endif /* defined(HAVE_PRI) */ 09584 } else { 09585 y = 1; 09586 do { 09587 ast_str_set(&chan_name, 0, "%d-%d", i->channel, y); 09588 for (x = 0; x < 3; ++x) { 09589 if (i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name), 09590 ast_channel_name(i->subs[x].owner) + 6)) { 09591 break; 09592 } 09593 } 09594 ++y; 09595 } while (x < 3); 09596 } 09597 return chan_name; 09598 }
| static void dahdi_ami_channel_event | ( | struct dahdi_pvt * | p, | |
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 2156 of file chan_dahdi.c.
References ast_channel_name(), ast_channel_uniqueid(), ast_manager_event, CHAN_PSEUDO, dahdi_pvt::channel, EVENT_FLAG_CALL, and dahdi_pvt::span.
Referenced by dahdi_new().
02157 { 02158 char ch_name[20]; 02159 02160 if (p->channel < CHAN_PSEUDO) { 02161 /* No B channel */ 02162 snprintf(ch_name, sizeof(ch_name), "no-media (%d)", p->channel); 02163 } else if (p->channel == CHAN_PSEUDO) { 02164 /* Pseudo channel */ 02165 strcpy(ch_name, "pseudo"); 02166 } else { 02167 /* Real channel */ 02168 snprintf(ch_name, sizeof(ch_name), "%d", p->channel); 02169 } 02170 ast_manager_event(chan, EVENT_FLAG_CALL, "DAHDIChannel", 02171 "Channel: %s\r\n" 02172 "Uniqueid: %s\r\n" 02173 "DAHDISpan: %d\r\n" 02174 "DAHDIChannel: %s\r\n", 02175 ast_channel_name(chan), 02176 ast_channel_uniqueid(chan), 02177 p->span, 02178 ch_name); 02179 }
| static int dahdi_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 6591 of file chan_dahdi.c.
References analog_answer(), analog_lib_handles(), ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_UP, dahdi_pvt::channel, dahdi_get_index, dahdi_pvt::lock, 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.
06592 { 06593 struct dahdi_pvt *p = ast->tech_pvt; 06594 int res = 0; 06595 int idx; 06596 ast_setstate(ast, AST_STATE_UP);/*! \todo XXX this is redundantly set by the analog and PRI submodules! */ 06597 ast_mutex_lock(&p->lock); 06598 idx = dahdi_get_index(ast, p, 0); 06599 if (idx < 0) 06600 idx = SUB_REAL; 06601 /* nothing to do if a radio channel */ 06602 if ((p->radio || (p->oprmode < 0))) { 06603 ast_mutex_unlock(&p->lock); 06604 return 0; 06605 } 06606 06607 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 06608 res = analog_answer(p->sig_pvt, ast); 06609 ast_mutex_unlock(&p->lock); 06610 return res; 06611 } 06612 06613 switch (p->sig) { 06614 #if defined(HAVE_PRI) 06615 case SIG_PRI_LIB_HANDLE_CASES: 06616 res = sig_pri_answer(p->sig_pvt, ast); 06617 break; 06618 #endif /* defined(HAVE_PRI) */ 06619 #if defined(HAVE_SS7) 06620 case SIG_SS7: 06621 res = sig_ss7_answer(p->sig_pvt, ast); 06622 break; 06623 #endif /* defined(HAVE_SS7) */ 06624 #ifdef HAVE_OPENR2 06625 case SIG_MFCR2: 06626 if (!p->mfcr2_call_accepted) { 06627 /* The call was not accepted on offer nor the user, so it must be accepted now before answering, 06628 openr2_chan_answer_call will be called when the callback on_call_accepted is executed */ 06629 p->mfcr2_answer_pending = 1; 06630 if (p->mfcr2_charge_calls) { 06631 ast_debug(1, "Accepting MFC/R2 call with charge before answering on chan %d\n", p->channel); 06632 openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE); 06633 } else { 06634 ast_debug(1, "Accepting MFC/R2 call with no charge before answering on chan %d\n", p->channel); 06635 openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE); 06636 } 06637 } else { 06638 ast_debug(1, "Answering MFC/R2 call on chan %d\n", p->channel); 06639 dahdi_r2_answer(p); 06640 } 06641 break; 06642 #endif 06643 case 0: 06644 ast_mutex_unlock(&p->lock); 06645 return 0; 06646 default: 06647 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel); 06648 res = -1; 06649 break; 06650 } 06651 ast_mutex_unlock(&p->lock); 06652 return res; 06653 }
| 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 7238 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_name(), ast_channel_trylock, ast_channel_unlock, ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_read(), AST_STATE_RINGING, ast_verb, ast_waitfor_n(), ast_write(), sig_pri_chan::call, dahdi_pvt::callwaiting, dahdi_pvt::callwaitingcallerid, dahdi_pvt::channel, CHANNEL_DEADLOCK_AVOIDANCE, dahdi_disable_ec(), dahdi_enable_ec(), dahdi_get_index, dahdi_link(), dahdi_sig_pri_lib_handles(), dahdi_unlink(), dahdi_subchannel::dfd, disable_dtmf_detect(), dahdi_pvt::echocanbridged, enable_dtmf_detect(), 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().
07239 { 07240 struct ast_channel *who; 07241 struct dahdi_pvt *p0, *p1, *op0, *op1; 07242 struct dahdi_pvt *master = NULL, *slave = NULL; 07243 struct ast_frame *f; 07244 int inconf = 0; 07245 int nothingok = 1; 07246 int ofd0, ofd1; 07247 int oi0, oi1, i0 = -1, i1 = -1, t0, t1; 07248 int os0 = -1, os1 = -1; 07249 int priority = 0; 07250 struct ast_channel *oc0, *oc1; 07251 enum ast_bridge_result res; 07252 #ifdef PRI_2BCT 07253 int triedtopribridge = 0; 07254 q931_call *q931c0; 07255 q931_call *q931c1; 07256 #endif 07257 07258 /* For now, don't attempt to native bridge if either channel needs DTMF detection. 07259 There is code below to handle it properly until DTMF is actually seen, 07260 but due to currently unresolved issues it's ignored... 07261 */ 07262 07263 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 07264 return AST_BRIDGE_FAILED_NOWARN; 07265 07266 ast_channel_lock(c0); 07267 while (ast_channel_trylock(c1)) { 07268 CHANNEL_DEADLOCK_AVOIDANCE(c0); 07269 } 07270 07271 p0 = c0->tech_pvt; 07272 p1 = c1->tech_pvt; 07273 /* cant do pseudo-channels here */ 07274 if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) { 07275 ast_channel_unlock(c0); 07276 ast_channel_unlock(c1); 07277 return AST_BRIDGE_FAILED_NOWARN; 07278 } 07279 07280 oi0 = dahdi_get_index(c0, p0, 0); 07281 oi1 = dahdi_get_index(c1, p1, 0); 07282 if ((oi0 < 0) || (oi1 < 0)) { 07283 ast_channel_unlock(c0); 07284 ast_channel_unlock(c1); 07285 return AST_BRIDGE_FAILED; 07286 } 07287 07288 op0 = p0 = c0->tech_pvt; 07289 op1 = p1 = c1->tech_pvt; 07290 ofd0 = c0->fds[0]; 07291 ofd1 = c1->fds[0]; 07292 oc0 = p0->owner; 07293 oc1 = p1->owner; 07294 07295 if (ast_mutex_trylock(&p0->lock)) { 07296 /* Don't block, due to potential for deadlock */ 07297 ast_channel_unlock(c0); 07298 ast_channel_unlock(c1); 07299 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 07300 return AST_BRIDGE_RETRY; 07301 } 07302 if (ast_mutex_trylock(&p1->lock)) { 07303 /* Don't block, due to potential for deadlock */ 07304 ast_mutex_unlock(&p0->lock); 07305 ast_channel_unlock(c0); 07306 ast_channel_unlock(c1); 07307 ast_log(LOG_NOTICE, "Avoiding deadlock...\n"); 07308 return AST_BRIDGE_RETRY; 07309 } 07310 07311 if ((p0->callwaiting && p0->callwaitingcallerid) 07312 || (p1->callwaiting && p1->callwaitingcallerid)) { 07313 /* 07314 * Call Waiting Caller ID requires DTMF detection to know if it 07315 * can send the CID spill. 07316 * 07317 * For now, don't attempt to native bridge if either channel 07318 * needs DTMF detection. There is code below to handle it 07319 * properly until DTMF is actually seen, but due to currently 07320 * unresolved issues it's ignored... 07321 */ 07322 ast_mutex_unlock(&p0->lock); 07323 ast_mutex_unlock(&p1->lock); 07324 ast_channel_unlock(c0); 07325 ast_channel_unlock(c1); 07326 return AST_BRIDGE_FAILED_NOWARN; 07327 } 07328 07329 #if defined(HAVE_PRI) 07330 if ((dahdi_sig_pri_lib_handles(p0->sig) 07331 && ((struct sig_pri_chan *) p0->sig_pvt)->no_b_channel) 07332 || (dahdi_sig_pri_lib_handles(p1->sig) 07333 && ((struct sig_pri_chan *) p1->sig_pvt)->no_b_channel)) { 07334 /* 07335 * PRI nobch channels (hold and call waiting) are equivalent to 07336 * pseudo channels and cannot be done here. 07337 */ 07338 ast_mutex_unlock(&p0->lock); 07339 ast_mutex_unlock(&p1->lock); 07340 ast_channel_unlock(c0); 07341 ast_channel_unlock(c1); 07342 return AST_BRIDGE_FAILED_NOWARN; 07343 } 07344 #endif /* defined(HAVE_PRI) */ 07345 07346 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 07347 if (p0->owner && p1->owner) { 07348 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */ 07349 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) { 07350 master = p0; 07351 slave = p1; 07352 inconf = 1; 07353 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) { 07354 master = p1; 07355 slave = p0; 07356 inconf = 1; 07357 } else { 07358 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n"); 07359 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n", 07360 p0->channel, 07361 oi0, (p0->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0, 07362 p0->subs[SUB_REAL].inthreeway, p0->channel, 07363 oi0, (p1->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0, 07364 p1->subs[SUB_REAL].inthreeway); 07365 } 07366 nothingok = 0; 07367 } 07368 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) { 07369 if (p1->subs[SUB_THREEWAY].inthreeway) { 07370 master = p1; 07371 slave = p0; 07372 nothingok = 0; 07373 } 07374 } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) { 07375 if (p0->subs[SUB_THREEWAY].inthreeway) { 07376 master = p0; 07377 slave = p1; 07378 nothingok = 0; 07379 } 07380 } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) { 07381 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise, 07382 don't put us in anything */ 07383 if (p1->subs[SUB_CALLWAIT].inthreeway) { 07384 master = p1; 07385 slave = p0; 07386 nothingok = 0; 07387 } 07388 } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) { 07389 /* Same as previous */ 07390 if (p0->subs[SUB_CALLWAIT].inthreeway) { 07391 master = p0; 07392 slave = p1; 07393 nothingok = 0; 07394 } 07395 } 07396 ast_debug(1, "master: %d, slave: %d, nothingok: %d\n", 07397 master ? master->channel : 0, slave ? slave->channel : 0, nothingok); 07398 if (master && slave) { 07399 /* Stop any tones, or play ringtone as appropriate. If they're bridged 07400 in an active threeway call with a channel that is ringing, we should 07401 indicate ringing. */ 07402 if ((oi1 == SUB_THREEWAY) && 07403 p1->subs[SUB_THREEWAY].inthreeway && 07404 p1->subs[SUB_REAL].owner && 07405 p1->subs[SUB_REAL].inthreeway && 07406 (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 07407 ast_debug(1, 07408 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n", 07409 p0->channel, oi0, ast_channel_name(c0), p1->channel, oi1, ast_channel_name(c1)); 07410 tone_zone_play_tone(p0->subs[oi0].dfd, DAHDI_TONE_RINGTONE); 07411 os1 = p1->subs[SUB_REAL].owner->_state; 07412 } else { 07413 ast_debug(1, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n", 07414 p0->channel, oi0, ast_channel_name(c0), p1->channel, oi1, ast_channel_name(c1)); 07415 tone_zone_play_tone(p0->subs[oi0].dfd, -1); 07416 } 07417 if ((oi0 == SUB_THREEWAY) && 07418 p0->subs[SUB_THREEWAY].inthreeway && 07419 p0->subs[SUB_REAL].owner && 07420 p0->subs[SUB_REAL].inthreeway && 07421 (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) { 07422 ast_debug(1, 07423 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n", 07424 p1->channel, oi1, ast_channel_name(c1), p0->channel, oi0, ast_channel_name(c0)); 07425 tone_zone_play_tone(p1->subs[oi1].dfd, DAHDI_TONE_RINGTONE); 07426 os0 = p0->subs[SUB_REAL].owner->_state; 07427 } else { 07428 ast_debug(1, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n", 07429 p1->channel, oi1, ast_channel_name(c1), p0->channel, oi0, ast_channel_name(c0)); 07430 tone_zone_play_tone(p1->subs[oi1].dfd, -1); 07431 } 07432 if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) { 07433 if (!p0->echocanbridged || !p1->echocanbridged) { 07434 /* Disable echo cancellation if appropriate */ 07435 dahdi_disable_ec(p0); 07436 dahdi_disable_ec(p1); 07437 } 07438 } 07439 dahdi_link(slave, master); 07440 master->inconference = inconf; 07441 } else if (!nothingok) 07442 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]); 07443 07444 update_conf(p0); 07445 update_conf(p1); 07446 t0 = p0->subs[SUB_REAL].inthreeway; 07447 t1 = p1->subs[SUB_REAL].inthreeway; 07448 07449 ast_mutex_unlock(&p0->lock); 07450 ast_mutex_unlock(&p1->lock); 07451 07452 ast_channel_unlock(c0); 07453 ast_channel_unlock(c1); 07454 07455 /* Native bridge failed */ 07456 if ((!master || !slave) && !nothingok) { 07457 dahdi_enable_ec(p0); 07458 dahdi_enable_ec(p1); 07459 return AST_BRIDGE_FAILED; 07460 } 07461 07462 ast_verb(3, "Native bridging %s and %s\n", ast_channel_name(c0), ast_channel_name(c1)); 07463 07464 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 07465 disable_dtmf_detect(op0); 07466 07467 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 07468 disable_dtmf_detect(op1); 07469 07470 for (;;) { 07471 struct ast_channel *c0_priority[2] = {c0, c1}; 07472 struct ast_channel *c1_priority[2] = {c1, c0}; 07473 07474 /* Here's our main loop... Start by locking things, looking for private parts, 07475 and then balking if anything is wrong */ 07476 07477 ast_channel_lock(c0); 07478 while (ast_channel_trylock(c1)) { 07479 CHANNEL_DEADLOCK_AVOIDANCE(c0); 07480 } 07481 07482 p0 = c0->tech_pvt; 07483 p1 = c1->tech_pvt; 07484 07485 if (op0 == p0) 07486 i0 = dahdi_get_index(c0, p0, 1); 07487 if (op1 == p1) 07488 i1 = dahdi_get_index(c1, p1, 1); 07489 07490 ast_channel_unlock(c0); 07491 ast_channel_unlock(c1); 07492 07493 if (!timeoutms || 07494 (op0 != p0) || 07495 (op1 != p1) || 07496 (ofd0 != c0->fds[0]) || 07497 (ofd1 != c1->fds[0]) || 07498 (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 07499 (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 07500 (oc0 != p0->owner) || 07501 (oc1 != p1->owner) || 07502 (t0 != p0->subs[SUB_REAL].inthreeway) || 07503 (t1 != p1->subs[SUB_REAL].inthreeway) || 07504 (oi0 != i0) || 07505 (oi1 != i1)) { 07506 ast_debug(1, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n", 07507 op0->channel, oi0, op1->channel, oi1); 07508 res = AST_BRIDGE_RETRY; 07509 goto return_from_bridge; 07510 } 07511 07512 #ifdef PRI_2BCT 07513 if (!triedtopribridge) { 07514 triedtopribridge = 1; 07515 if (p0->pri && p0->pri == p1->pri && p0->pri->transfer) { 07516 ast_mutex_lock(&p0->pri->lock); 07517 switch (p0->sig) { 07518 case SIG_PRI_LIB_HANDLE_CASES: 07519 q931c0 = ((struct sig_pri_chan *) (p0->sig_pvt))->call; 07520 break; 07521 default: 07522 q931c0 = NULL; 07523 break; 07524 } 07525 switch (p1->sig) { 07526 case SIG_PRI_LIB_HANDLE_CASES: 07527 q931c1 = ((struct sig_pri_chan *) (p1->sig_pvt))->call; 07528 break; 07529 default: 07530 q931c1 = NULL; 07531 break; 07532 } 07533 if (q931c0 && q931c1) { 07534 pri_channel_bridge(q931c0, q931c1); 07535 } 07536 ast_mutex_unlock(&p0->pri->lock); 07537 } 07538 } 07539 #endif 07540 07541 who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms); 07542 if (!who) { 07543 ast_debug(1, "Ooh, empty read...\n"); 07544 continue; 07545 } 07546 f = ast_read(who); 07547 switch (f ? f->frametype : AST_FRAME_CONTROL) { 07548 case AST_FRAME_CONTROL: 07549 *fo = f; 07550 *rc = who; 07551 res = AST_BRIDGE_COMPLETE; 07552 goto return_from_bridge; 07553 case AST_FRAME_DTMF_END: 07554 if ((who == c0) && p0->pulsedial) { 07555 ast_write(c1, f); 07556 } else if ((who == c1) && p1->pulsedial) { 07557 ast_write(c0, f); 07558 } else { 07559 *fo = f; 07560 *rc = who; 07561 res = AST_BRIDGE_COMPLETE; 07562 goto return_from_bridge; 07563 } 07564 break; 07565 case AST_FRAME_TEXT: 07566 if (who == c0) { 07567 ast_write(c1, f); 07568 } else { 07569 ast_write(c0, f); 07570 } 07571 break; 07572 case AST_FRAME_VOICE: 07573 /* Native bridge handles voice frames in hardware. */ 07574 case AST_FRAME_NULL: 07575 break; 07576 default: 07577 ast_debug(1, "Chan '%s' is discarding frame of frametype:%d\n", 07578 ast_channel_name(who), f->frametype); 07579 break; 07580 } 07581 ast_frfree(f); 07582 07583 /* Swap who gets priority */ 07584 priority = !priority; 07585 } 07586 07587 return_from_bridge: 07588 if (op0 == p0) 07589 dahdi_enable_ec(p0); 07590 07591 if (op1 == p1) 07592 dahdi_enable_ec(p1); 07593 07594 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL)) 07595 enable_dtmf_detect(op0); 07596 07597 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL)) 07598 enable_dtmf_detect(op1); 07599 07600 dahdi_unlink(slave, master, 1); 07601 07602 return res; 07603 }
| static int dahdi_call | ( | struct ast_channel * | ast, | |
| const char * | rdest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 5359 of file chan_dahdi.c.
References ast_channel::_state, analog_call(), analog_lib_handles(), args, AST_APP_ARG, ast_channel_name(), ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_NONSTANDARD_APP_ARGS, ast_setstate(), AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_UP, ast_strdupa, 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, ext, dahdi_pvt::exten, 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(), sig_pri_extract_called_num_subaddr(), 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.
05360 { 05361 struct dahdi_pvt *p = ast->tech_pvt; 05362 int x, res, mysig; 05363 char *dest; 05364 AST_DECLARE_APP_ARGS(args, 05365 AST_APP_ARG(group); /* channel/group token */ 05366 AST_APP_ARG(ext); /* extension token */ 05367 //AST_APP_ARG(opts); /* options token */ 05368 AST_APP_ARG(other); /* Any remining unused arguments */ 05369 ); 05370 05371 ast_mutex_lock(&p->lock); 05372 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest)); 05373 05374 /* Split the dialstring */ 05375 dest = ast_strdupa(rdest); 05376 AST_NONSTANDARD_APP_ARGS(args, dest, '/'); 05377 if (!args.ext) { 05378 args.ext = ""; 05379 } 05380 05381 #if defined(HAVE_PRI) 05382 if (dahdi_sig_pri_lib_handles(p->sig)) { 05383 char *subaddr; 05384 05385 sig_pri_extract_called_num_subaddr(p->sig_pvt, rdest, p->exten, sizeof(p->exten)); 05386 05387 /* Remove any subaddress for uniformity with incoming calls. */ 05388 subaddr = strchr(p->exten, ':'); 05389 if (subaddr) { 05390 *subaddr = '\0'; 05391 } 05392 } else 05393 #endif /* defined(HAVE_PRI) */ 05394 { 05395 ast_copy_string(p->exten, args.ext, sizeof(p->exten)); 05396 } 05397 05398 if ((ast->_state == AST_STATE_BUSY)) { 05399 p->subs[SUB_REAL].needbusy = 1; 05400 ast_mutex_unlock(&p->lock); 05401 return 0; 05402 } 05403 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 05404 ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast_channel_name(ast)); 05405 ast_mutex_unlock(&p->lock); 05406 return -1; 05407 } 05408 p->waitingfordt.tv_sec = 0; 05409 p->dialednone = 0; 05410 if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */ 05411 { 05412 /* Special pseudo -- automatically up */ 05413 ast_setstate(ast, AST_STATE_UP); 05414 ast_mutex_unlock(&p->lock); 05415 return 0; 05416 } 05417 x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE; 05418 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x); 05419 if (res) 05420 ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno)); 05421 p->outgoing = 1; 05422 05423 if (IS_DIGITAL(ast->transfercapability)){ 05424 set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, p->rxdrc, p->txdrc, p->law); 05425 } else { 05426 set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law); 05427 } 05428 05429 #ifdef HAVE_PRI 05430 if (dahdi_sig_pri_lib_handles(p->sig)) { 05431 res = sig_pri_call(p->sig_pvt, ast, rdest, timeout, 05432 (p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW); 05433 ast_mutex_unlock(&p->lock); 05434 return res; 05435 } 05436 #endif 05437 05438 #if defined(HAVE_SS7) 05439 if (p->sig == SIG_SS7) { 05440 res = sig_ss7_call(p->sig_pvt, ast, rdest); 05441 ast_mutex_unlock(&p->lock); 05442 return res; 05443 } 05444 #endif /* defined(HAVE_SS7) */ 05445 05446 /* If this is analog signalling we can exit here */ 05447 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 05448 p->callwaitrings = 0; 05449 res = analog_call(p->sig_pvt, ast, rdest, timeout); 05450 ast_mutex_unlock(&p->lock); 05451 return res; 05452 } 05453 05454 mysig = p->outsigmod > -1 ? p->outsigmod : p->sig; 05455 switch (mysig) { 05456 case 0: 05457 /* Special pseudo -- automatically up*/ 05458 ast_setstate(ast, AST_STATE_UP); 05459 break; 05460 case SIG_MFCR2: 05461 break; 05462 default: 05463 ast_debug(1, "not yet implemented\n"); 05464 ast_mutex_unlock(&p->lock); 05465 return -1; 05466 } 05467 05468 #ifdef HAVE_OPENR2 05469 if (p->mfcr2) { 05470 openr2_calling_party_category_t chancat; 05471 int callres = 0; 05472 char *c, *l; 05473 05474 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */ 05475 p->dialdest[0] = '\0'; 05476 05477 c = args.ext; 05478 if (!p->hidecallerid) { 05479 l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL; 05480 } else { 05481 l = NULL; 05482 } 05483 if (strlen(c) < p->stripmsd) { 05484 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 05485 ast_mutex_unlock(&p->lock); 05486 return -1; 05487 } 05488 p->dialing = 1; 05489 chancat = dahdi_r2_get_channel_category(ast); 05490 callres = openr2_chan_make_call(p->r2chan, l, (c + p->stripmsd), chancat); 05491 if (-1 == callres) { 05492 ast_mutex_unlock(&p->lock); 05493 ast_log(LOG_ERROR, "unable to make new MFC/R2 call!\n"); 05494 return -1; 05495 } 05496 p->mfcr2_call_accepted = 0; 05497 p->mfcr2_progress_sent = 0; 05498 ast_setstate(ast, AST_STATE_DIALING); 05499 } 05500 #endif /* HAVE_OPENR2 */ 05501 ast_mutex_unlock(&p->lock); 05502 return 0; 05503 }
| static int dahdi_callwait | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 5325 of file chan_dahdi.c.
References ast_format_set(), 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().
05326 { 05327 struct dahdi_pvt *p = ast->tech_pvt; 05328 struct ast_format tmpfmt; 05329 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 05330 if (p->cidspill) { 05331 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 05332 ast_free(p->cidspill); 05333 } 05334 05335 /* 05336 * SAS: Subscriber Alert Signal, 440Hz for 300ms 05337 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves 05338 */ 05339 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 05340 return -1; 05341 save_conference(p); 05342 /* Silence */ 05343 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 05344 if (!p->callwaitrings && p->callwaitingcallerid) { 05345 ast_gen_cas(p->cidspill, 1, 2400 + 680, ast_format_set(&tmpfmt, AST_LAW(p), 0)); 05346 p->callwaitcas = 1; 05347 p->cidlen = 2400 + 680 + READ_SIZE * 4; 05348 } else { 05349 ast_gen_cas(p->cidspill, 1, 2400, ast_format_set(&tmpfmt, AST_LAW(p), 0)); 05350 p->callwaitcas = 0; 05351 p->cidlen = 2400 + READ_SIZE * 4; 05352 } 05353 p->cidpos = 0; 05354 send_callerid(p); 05355 05356 return 0; 05357 }
| static int dahdi_cc_callback | ( | struct ast_channel * | inbound, | |
| const char * | dest, | |||
| ast_cc_callback_fn | callback | |||
| ) | [static] |
Callback made when dial failed to get a channel out of dahdi_request().
| inbound | Incoming asterisk channel. | |
| dest | Same dial string passed to dahdi_request(). | |
| callback | Callback into CC core to announce a busy channel available for CC. |
| 0 | on success. | |
| -1 | on error. |
Definition at line 13887 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, iflock, is_group_or_channel_match(), dahdi_pvt::next, dahdi_pvt::prev, dahdi_pvt::sig, dahdi_pvt::span, and dahdi_starting_point::span.
13888 { 13889 struct dahdi_pvt *p; 13890 struct dahdi_pvt *exitpvt; 13891 struct dahdi_starting_point start; 13892 int groupmatched = 0; 13893 int channelmatched = 0; 13894 13895 ast_mutex_lock(&iflock); 13896 p = determine_starting_point(dest, &start); 13897 if (!p) { 13898 ast_mutex_unlock(&iflock); 13899 return -1; 13900 } 13901 exitpvt = p; 13902 for (;;) { 13903 if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)) { 13904 /* We found a potential match. call the callback */ 13905 struct ast_str *device_name; 13906 char *dash; 13907 const char *monitor_type; 13908 char dialstring[AST_CHANNEL_NAME]; 13909 char full_device_name[AST_CHANNEL_NAME]; 13910 13911 switch (ast_get_cc_monitor_policy(p->cc_params)) { 13912 case AST_CC_MONITOR_NEVER: 13913 break; 13914 case AST_CC_MONITOR_NATIVE: 13915 case AST_CC_MONITOR_ALWAYS: 13916 case AST_CC_MONITOR_GENERIC: 13917 #if defined(HAVE_PRI) 13918 if (dahdi_sig_pri_lib_handles(p->sig)) { 13919 /* 13920 * ISDN is in a trunk busy condition so we need to monitor 13921 * the span congestion device state. 13922 */ 13923 snprintf(full_device_name, sizeof(full_device_name), 13924 "DAHDI/I%d/congestion", p->pri->span); 13925 } else 13926 #endif /* defined(HAVE_PRI) */ 13927 { 13928 #if defined(HAVE_PRI) 13929 device_name = create_channel_name(p, 1, ""); 13930 #else 13931 device_name = create_channel_name(p); 13932 #endif /* defined(HAVE_PRI) */ 13933 snprintf(full_device_name, sizeof(full_device_name), "DAHDI/%s", 13934 device_name ? ast_str_buffer(device_name) : ""); 13935 ast_free(device_name); 13936 /* 13937 * The portion after the '-' in the channel name is either a random 13938 * number, a sequence number, or a subchannel number. None are 13939 * necessary so strip them off. 13940 */ 13941 dash = strrchr(full_device_name, '-'); 13942 if (dash) { 13943 *dash = '\0'; 13944 } 13945 } 13946 snprintf(dialstring, sizeof(dialstring), "DAHDI/%s", dest); 13947 13948 /* 13949 * Analog can only do generic monitoring. 13950 * ISDN is in a trunk busy condition and any "device" is going 13951 * to be busy until a B channel becomes available. The generic 13952 * monitor can do this task. 13953 */ 13954 monitor_type = AST_CC_GENERIC_MONITOR_TYPE; 13955 callback(inbound, 13956 #if defined(HAVE_PRI) 13957 p->pri ? p->pri->cc_params : p->cc_params, 13958 #else 13959 p->cc_params, 13960 #endif /* defined(HAVE_PRI) */ 13961 monitor_type, full_device_name, dialstring, NULL); 13962 break; 13963 } 13964 } 13965 p = start.backwards ? p->prev : p->next; 13966 if (!p) { 13967 p = start.backwards ? ifend : iflist; 13968 } 13969 if (p == exitpvt) { 13970 break; 13971 } 13972 } 13973 ast_mutex_unlock(&iflock); 13974 return 0; 13975 }
| 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 1374 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().
01375 { 01376 /* recall that if a field is not included here it is initialized 01377 * to 0 or equivalent 01378 */ 01379 struct dahdi_chan_conf conf = { 01380 #ifdef HAVE_PRI 01381 .pri.pri = { 01382 .nsf = PRI_NSF_NONE, 01383 .switchtype = PRI_SWITCH_NI2, 01384 .dialplan = PRI_UNKNOWN + 1, 01385 .localdialplan = PRI_NATIONAL_ISDN + 1, 01386 .nodetype = PRI_CPE, 01387 .qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL, 01388 01389 #if defined(HAVE_PRI_CCSS) 01390 .cc_ptmp_recall_mode = 1,/* specificRecall */ 01391 .cc_qsig_signaling_link_req = 1,/* retain */ 01392 .cc_qsig_signaling_link_rsp = 1,/* retain */ 01393 #endif /* defined(HAVE_PRI_CCSS) */ 01394 01395 .minunused = 2, 01396 .idleext = "", 01397 .idledial = "", 01398 .internationalprefix = "", 01399 .nationalprefix = "", 01400 .localprefix = "", 01401 .privateprefix = "", 01402 .unknownprefix = "", 01403 .resetinterval = -1, 01404 }, 01405 #endif 01406 #if defined(HAVE_SS7) 01407 .ss7.ss7 = { 01408 .called_nai = SS7_NAI_NATIONAL, 01409 .calling_nai = SS7_NAI_NATIONAL, 01410 .internationalprefix = "", 01411 .nationalprefix = "", 01412 .subscriberprefix = "", 01413 .unknownprefix = "" 01414 }, 01415 #endif /* defined(HAVE_SS7) */ 01416 #ifdef HAVE_OPENR2 01417 .mfcr2 = { 01418 .variant = OR2_VAR_ITU, 01419 .mfback_timeout = -1, 01420 .metering_pulse_timeout = -1, 01421 .max_ani = 10, 01422 .max_dnis = 4, 01423 .get_ani_first = -1, 01424 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 01425 .skip_category_request = -1, 01426 #endif 01427 .call_files = 0, 01428 .allow_collect_calls = 0, 01429 .charge_calls = 1, 01430 .accept_on_offer = 1, 01431 .forced_release = 0, 01432 .double_answer = 0, 01433 .immediate_accept = -1, 01434 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2 01435 .dtmf_dialing = -1, 01436 .dtmf_detection = -1, 01437 .dtmf_time_on = OR2_DEFAULT_DTMF_ON, 01438 .dtmf_time_off = OR2_DEFAULT_DTMF_OFF, 01439 #endif 01440 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3 01441 .dtmf_end_timeout = -1, 01442 #endif 01443 .logdir = "", 01444 .r2proto_file = "", 01445 .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING, 01446 .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER 01447 }, 01448 #endif 01449 .chan = { 01450 .context = "default", 01451 .cid_num = "", 01452 .cid_name = "", 01453 .cid_tag = "", 01454 .mohinterpret = "default", 01455 .mohsuggest = "", 01456 .parkinglot = "", 01457 .transfertobusy = 1, 01458 01459 .cid_signalling = CID_SIG_BELL, 01460 .cid_start = CID_START_RING, 01461 .dahditrcallerid = 0, 01462 .use_callerid = 1, 01463 .sig = -1, 01464 .outsigmod = -1, 01465 01466 .cid_rxgain = +5.0, 01467 01468 .tonezone = -1, 01469 01470 .echocancel.head.tap_length = 1, 01471 01472 .busycount = 3, 01473 01474 .accountcode = "", 01475 01476 .mailbox = "", 01477 01478 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 01479 .mwisend_fsk = 1, 01480 #endif 01481 .polarityonanswerdelay = 600, 01482 01483 .sendcalleridafter = DEFAULT_CIDRINGS, 01484 01485 .buf_policy = DAHDI_POLICY_IMMEDIATE, 01486 .buf_no = numbufs, 01487 .usefaxbuffers = 0, 01488 .cc_params = ast_cc_config_params_init(), 01489 }, 01490 .timing = { 01491 .prewinktime = -1, 01492 .preflashtime = -1, 01493 .winktime = -1, 01494 .flashtime = -1, 01495 .starttime = -1, 01496 .rxwinktime = -1, 01497 .rxflashtime = -1, 01498 .debouncetime = -1 01499 }, 01500 .is_sig_auto = 1, 01501 .smdi_port = "/dev/ttyS0", 01502 }; 01503 01504 return conf; 01505 }
| static int dahdi_channels_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 18717 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, iflock, and dahdi_pvt::next.
18719 { 18720 struct dahdi_pvt *tmp; 18721 struct ast_data *data_channel; 18722 18723 ast_mutex_lock(&iflock); 18724 for (tmp = iflist; tmp; tmp = tmp->next) { 18725 data_channel = ast_data_add_node(data_root, "channel"); 18726 if (!data_channel) { 18727 continue; 18728 } 18729 18730 ast_data_add_structure(dahdi_pvt, data_channel, tmp); 18731 18732 /* if this channel doesn't match remove it. */ 18733 if (!ast_data_search_match(search, data_channel)) { 18734 ast_data_remove_node(data_root, data_channel); 18735 } 18736 } 18737 ast_mutex_unlock(&iflock); 18738 18739 return 0; 18740 }
| static void dahdi_close | ( | int | fd | ) | [static] |
| static void dahdi_close_sub | ( | struct dahdi_pvt * | chan_pvt, | |
| int | sub_num | |||
| ) | [static] |
Definition at line 4356 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().
04357 { 04358 dahdi_close(chan_pvt->subs[sub_num].dfd); 04359 chan_pvt->subs[sub_num].dfd = -1; 04360 }
| static int dahdi_confmute | ( | struct dahdi_pvt * | p, | |
| int | muted | |||
| ) | [inline, static] |
Definition at line 5166 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().
05167 { 05168 int x, res; 05169 05170 x = muted; 05171 #if defined(HAVE_PRI) || defined(HAVE_SS7) 05172 switch (p->sig) { 05173 #if defined(HAVE_PRI) 05174 case SIG_PRI_LIB_HANDLE_CASES: 05175 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 05176 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */ 05177 break; 05178 } 05179 /* Fall through */ 05180 #endif /* defined(HAVE_PRI) */ 05181 #if defined(HAVE_SS7) 05182 case SIG_SS7: 05183 #endif /* defined(HAVE_SS7) */ 05184 { 05185 int y = 1; 05186 05187 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y); 05188 if (res) 05189 ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n", 05190 p->channel, strerror(errno)); 05191 } 05192 break; 05193 default: 05194 break; 05195 } 05196 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 05197 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x); 05198 if (res < 0) 05199 ast_log(LOG_WARNING, "DAHDI confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno)); 05200 return res; 05201 }
| static char* dahdi_destroy_channel | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15047 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.
15048 { 15049 int channel; 15050 int ret; 15051 switch (cmd) { 15052 case CLI_INIT: 15053 e->command = "dahdi destroy channel"; 15054 e->usage = 15055 "Usage: dahdi destroy channel <chan num>\n" 15056 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n"; 15057 return NULL; 15058 case CLI_GENERATE: 15059 return NULL; 15060 } 15061 if (a->argc != 4) 15062 return CLI_SHOWUSAGE; 15063 15064 channel = atoi(a->argv[3]); 15065 ret = dahdi_destroy_channel_bynum(channel); 15066 return ( RESULT_SUCCESS == ret ) ? CLI_SUCCESS : CLI_FAILURE; 15067 }
| static int dahdi_destroy_channel_bynum | ( | int | channel | ) | [static] |
Definition at line 11408 of file chan_dahdi.c.
References ast_module_unref(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, destroy_channel(), dahdi_subchannel::dfd, iflock, dahdi_pvt::next, RESULT_FAILURE, RESULT_SUCCESS, SUB_REAL, and dahdi_pvt::subs.
Referenced by dahdi_destroy_channel(), and do_monitor().
11409 { 11410 struct dahdi_pvt *cur; 11411 11412 ast_mutex_lock(&iflock); 11413 for (cur = iflist; cur; cur = cur->next) { 11414 if (cur->channel == channel) { 11415 int x = DAHDI_FLASH; 11416 11417 /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */ 11418 ioctl(cur->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 11419 11420 destroy_channel(cur, 1); 11421 ast_mutex_unlock(&iflock); 11422 ast_module_unref(ast_module_info->self); 11423 return RESULT_SUCCESS; 11424 } 11425 } 11426 ast_mutex_unlock(&iflock); 11427 return RESULT_FAILURE; 11428 }
| static int dahdi_devicestate | ( | const char * | data | ) | [static] |
Definition at line 13825 of file chan_dahdi.c.
References AST_DEVICE_UNKNOWN.
13826 { 13827 #if defined(HAVE_PRI) 13828 const char *device; 13829 unsigned span; 13830 int res; 13831 13832 device = data; 13833 13834 if (*device != 'I') { 13835 /* The request is not for an ISDN span device. */ 13836 return AST_DEVICE_UNKNOWN; 13837 } 13838 res = sscanf(device, "I%30u", &span); 13839 if (res != 1 || !span || NUM_SPANS < span) { 13840 /* Bad format for ISDN span device name. */ 13841 return AST_DEVICE_UNKNOWN; 13842 } 13843 device = strchr(device, '/'); 13844 if (!device) { 13845 /* Bad format for ISDN span device name. */ 13846 return AST_DEVICE_UNKNOWN; 13847 } 13848 13849 /* 13850 * Since there are currently no other span devstate's defined, 13851 * it must be congestion. 13852 */ 13853 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER) 13854 ++device; 13855 if (!strcmp(device, "congestion")) 13856 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */ 13857 { 13858 return pris[span - 1].pri.congestion_devstate; 13859 } 13860 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER) 13861 else if (!strcmp(device, "threshold")) { 13862 return pris[span - 1].pri.threshold_devstate; 13863 } 13864 return AST_DEVICE_UNKNOWN; 13865 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */ 13866 #else 13867 return AST_DEVICE_UNKNOWN; 13868 #endif /* defined(HAVE_PRI) */ 13869 }
| static int dahdi_digit_begin | ( | struct ast_channel * | ast, | |
| char | digit | |||
| ) | [static] |
Definition at line 4454 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.
04455 { 04456 struct dahdi_pvt *pvt; 04457 int idx; 04458 int dtmf = -1; 04459 int res; 04460 04461 pvt = chan->tech_pvt; 04462 04463 ast_mutex_lock(&pvt->lock); 04464 04465 idx = dahdi_get_index(chan, pvt, 0); 04466 04467 if ((idx != SUB_REAL) || !pvt->owner) 04468 goto out; 04469 04470 #ifdef HAVE_PRI 04471 switch (pvt->sig) { 04472 case SIG_PRI_LIB_HANDLE_CASES: 04473 res = sig_pri_digit_begin(pvt->sig_pvt, chan, digit); 04474 if (!res) 04475 goto out; 04476 break; 04477 default: 04478 break; 04479 } 04480 #endif 04481 if ((dtmf = digit_to_dtmfindex(digit)) == -1) 04482 goto out; 04483 04484 if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) { 04485 struct dahdi_dialoperation zo = { 04486 .op = DAHDI_DIAL_OP_APPEND, 04487 }; 04488 04489 zo.dialstr[0] = 'T'; 04490 zo.dialstr[1] = digit; 04491 zo.dialstr[2] = '\0'; 04492 if ((res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo))) 04493 ast_log(LOG_WARNING, "Couldn't dial digit %c: %s\n", digit, strerror(errno)); 04494 else 04495 pvt->dialing = 1; 04496 } else { 04497 ast_debug(1, "Started VLDTMF digit '%c'\n", digit); 04498 pvt->dialing = 1; 04499 pvt->begindigit = digit; 04500 } 04501 04502 out: 04503 ast_mutex_unlock(&pvt->lock); 04504 04505 return 0; 04506 }
| static int dahdi_digit_end | ( | struct ast_channel * | ast, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Definition at line 4508 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.
04509 { 04510 struct dahdi_pvt *pvt; 04511 int res = 0; 04512 int idx; 04513 int x; 04514 04515 pvt = chan->tech_pvt; 04516 04517 ast_mutex_lock(&pvt->lock); 04518 04519 idx = dahdi_get_index(chan, pvt, 0); 04520 04521 if ((idx != SUB_REAL) || !pvt->owner || pvt->pulse) 04522 goto out; 04523 04524 #ifdef HAVE_PRI 04525 /* This means that the digit was already sent via PRI signalling */ 04526 if (dahdi_sig_pri_lib_handles(pvt->sig) && !pvt->begindigit) { 04527 goto out; 04528 } 04529 #endif 04530 04531 if (pvt->begindigit) { 04532 x = -1; 04533 ast_debug(1, "Ending VLDTMF digit '%c'\n", digit); 04534 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x); 04535 pvt->dialing = 0; 04536 pvt->begindigit = 0; 04537 } 04538 04539 out: 04540 ast_mutex_unlock(&pvt->lock); 04541 04542 return res; 04543 }
| static void dahdi_disable_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4958 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().
04959 { 04960 int res; 04961 04962 if (p->echocanon) { 04963 struct dahdi_echocanparams ecp = { .tap_length = 0 }; 04964 04965 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &ecp); 04966 04967 if (res) 04968 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno)); 04969 else 04970 ast_debug(1, "Disabled echo cancellation on channel %d\n", p->channel); 04971 } 04972 04973 p->echocanon = 0; 04974 }
| static int dahdi_dnd | ( | struct dahdi_pvt * | dahdichan, | |
| int | flag | |||
| ) | [static] |
enable or disable the chan_dahdi Do-Not-Disturb mode for a DAHDI channel
| dahdichan | "Physical" DAHDI channel (e.g: DAHDI/5) | |
| flag | on 1 to enable, 0 to disable, -1 return dnd value |
Definition at line 9867 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().
09868 { 09869 if (analog_lib_handles(dahdichan->sig, dahdichan->radio, dahdichan->oprmode)) { 09870 return analog_dnd(dahdichan->sig_pvt, flag); 09871 } 09872 09873 if (flag == -1) { 09874 return dahdichan->dnd; 09875 } 09876 09877 /* Do not disturb */ 09878 dahdichan->dnd = flag; 09879 ast_verb(3, "%s DND on channel %d\n", 09880 flag? "Enabled" : "Disabled", 09881 dahdichan->channel); 09882 manager_event(EVENT_FLAG_SYSTEM, "DNDState", 09883 "Channel: DAHDI/%d\r\n" 09884 "Status: %s\r\n", dahdichan->channel, 09885 flag? "enabled" : "disabled"); 09886 09887 return 0; 09888 }
| static void dahdi_enable_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4886 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().
04887 { 04888 int res; 04889 if (!p) 04890 return; 04891 if (p->echocanon) { 04892 ast_debug(1, "Echo cancellation already on\n"); 04893 return; 04894 } 04895 if (p->digital) { 04896 ast_debug(1, "Echo cancellation isn't required on digital connection\n"); 04897 return; 04898 } 04899 if (p->echocancel.head.tap_length) { 04900 #if defined(HAVE_PRI) || defined(HAVE_SS7) 04901 switch (p->sig) { 04902 #if defined(HAVE_PRI) 04903 case SIG_PRI_LIB_HANDLE_CASES: 04904 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 04905 /* 04906 * PRI nobch pseudo channel. Does not need ec anyway. 04907 * Does not handle ioctl(DAHDI_AUDIOMODE) 04908 */ 04909 return; 04910 } 04911 /* Fall through */ 04912 #endif /* defined(HAVE_PRI) */ 04913 #if defined(HAVE_SS7) 04914 case SIG_SS7: 04915 #endif /* defined(HAVE_SS7) */ 04916 { 04917 int x = 1; 04918 04919 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x); 04920 if (res) 04921 ast_log(LOG_WARNING, 04922 "Unable to enable audio mode on channel %d (%s)\n", 04923 p->channel, strerror(errno)); 04924 } 04925 break; 04926 default: 04927 break; 04928 } 04929 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 04930 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &p->echocancel); 04931 if (res) { 04932 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno)); 04933 } else { 04934 p->echocanon = 1; 04935 ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel); 04936 } 04937 } else 04938 ast_debug(1, "No echo cancellation requested\n"); 04939 }
| static struct ast_frame * dahdi_exception | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 8905 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.
08906 { 08907 struct dahdi_pvt *p = ast->tech_pvt; 08908 struct ast_frame *f; 08909 ast_mutex_lock(&p->lock); 08910 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 08911 struct analog_pvt *analog_p = p->sig_pvt; 08912 f = analog_exception(analog_p, ast); 08913 } else { 08914 f = __dahdi_exception(ast); 08915 } 08916 ast_mutex_unlock(&p->lock); 08917 return f; 08918 }
| static int dahdi_fake_event | ( | struct dahdi_pvt * | p, | |
| int | mode | |||
| ) | [static] |
Definition at line 15883 of file chan_dahdi.c.
References ast_channel_name(), ast_log(), dahdi_pvt::fake_event, HANGUP, LOG_WARNING, dahdi_pvt::owner, and TRANSFER.
Referenced by action_transfer(), and action_transferhangup().
15884 { 15885 if (p) { 15886 switch (mode) { 15887 case TRANSFER: 15888 p->fake_event = DAHDI_EVENT_WINKFLASH; 15889 break; 15890 case HANGUP: 15891 p->fake_event = DAHDI_EVENT_ONHOOK; 15892 break; 15893 default: 15894 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, ast_channel_name(p->owner)); 15895 } 15896 } 15897 return 0; 15898 }
| static int dahdi_fixup | ( | struct ast_channel * | oldchan, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
Definition at line 7605 of file chan_dahdi.c.
References ast_channel::_state, analog_fixup(), analog_lib_handles(), ast_channel_name(), 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().
07606 { 07607 struct dahdi_pvt *p = newchan->tech_pvt; 07608 int x; 07609 07610 ast_mutex_lock(&p->lock); 07611 07612 ast_debug(1, "New owner for channel %d is %s\n", p->channel, ast_channel_name(newchan)); 07613 if (p->owner == oldchan) { 07614 p->owner = newchan; 07615 } 07616 for (x = 0; x < 3; x++) { 07617 if (p->subs[x].owner == oldchan) { 07618 if (!x) { 07619 dahdi_unlink(NULL, p, 0); 07620 } 07621 p->subs[x].owner = newchan; 07622 } 07623 } 07624 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 07625 analog_fixup(oldchan, newchan, p->sig_pvt); 07626 #if defined(HAVE_PRI) 07627 } else if (dahdi_sig_pri_lib_handles(p->sig)) { 07628 sig_pri_fixup(oldchan, newchan, p->sig_pvt); 07629 #endif /* defined(HAVE_PRI) */ 07630 #if defined(HAVE_SS7) 07631 } else if (p->sig == SIG_SS7) { 07632 sig_ss7_fixup(oldchan, newchan, p->sig_pvt); 07633 #endif /* defined(HAVE_SS7) */ 07634 } 07635 update_conf(p); 07636 07637 ast_mutex_unlock(&p->lock); 07638 07639 if (newchan->_state == AST_STATE_RINGING) { 07640 dahdi_indicate(newchan, AST_CONTROL_RINGING, NULL, 0); 07641 } 07642 return 0; 07643 }
| static int dahdi_func_read | ( | struct ast_channel * | chan, | |
| const char * | function, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 6946 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.
06947 { 06948 struct dahdi_pvt *p = chan->tech_pvt; 06949 int res = 0; 06950 06951 if (!p) { 06952 /* No private structure! */ 06953 *buf = '\0'; 06954 return -1; 06955 } 06956 06957 if (!strcasecmp(data, "rxgain")) { 06958 ast_mutex_lock(&p->lock); 06959 snprintf(buf, len, "%f", p->rxgain); 06960 ast_mutex_unlock(&p->lock); 06961 } else if (!strcasecmp(data, "txgain")) { 06962 ast_mutex_lock(&p->lock); 06963 snprintf(buf, len, "%f", p->txgain); 06964 ast_mutex_unlock(&p->lock); 06965 } else if (!strcasecmp(data, "dahdi_channel")) { 06966 ast_mutex_lock(&p->lock); 06967 snprintf(buf, len, "%d", p->channel); 06968 ast_mutex_unlock(&p->lock); 06969 } else if (!strcasecmp(data, "dahdi_span")) { 06970 ast_mutex_lock(&p->lock); 06971 snprintf(buf, len, "%d", p->span); 06972 ast_mutex_unlock(&p->lock); 06973 } else if (!strcasecmp(data, "dahdi_type")) { 06974 ast_mutex_lock(&p->lock); 06975 switch (p->sig) { 06976 #if defined(HAVE_OPENR2) 06977 case SIG_MFCR2: 06978 ast_copy_string(buf, "mfc/r2", len); 06979 break; 06980 #endif /* defined(HAVE_OPENR2) */ 06981 #if defined(HAVE_PRI) 06982 case SIG_PRI_LIB_HANDLE_CASES: 06983 ast_copy_string(buf, "pri", len); 06984 break; 06985 #endif /* defined(HAVE_PRI) */ 06986 case 0: 06987 ast_copy_string(buf, "pseudo", len); 06988 break; 06989 #if defined(HAVE_SS7) 06990 case SIG_SS7: 06991 ast_copy_string(buf, "ss7", len); 06992 break; 06993 #endif /* defined(HAVE_SS7) */ 06994 default: 06995 /* The only thing left is analog ports. */ 06996 ast_copy_string(buf, "analog", len); 06997 break; 06998 } 06999 ast_mutex_unlock(&p->lock); 07000 #if defined(HAVE_PRI) 07001 #if defined(HAVE_PRI_REVERSE_CHARGE) 07002 } else if (!strcasecmp(data, "reversecharge")) { 07003 ast_mutex_lock(&p->lock); 07004 switch (p->sig) { 07005 case SIG_PRI_LIB_HANDLE_CASES: 07006 snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->reverse_charging_indication); 07007 break; 07008 default: 07009 *buf = '\0'; 07010 res = -1; 07011 break; 07012 } 07013 ast_mutex_unlock(&p->lock); 07014 #endif 07015 #if defined(HAVE_PRI_SETUP_KEYPAD) 07016 } else if (!strcasecmp(data, "keypad_digits")) { 07017 ast_mutex_lock(&p->lock); 07018 switch (p->sig) { 07019 case SIG_PRI_LIB_HANDLE_CASES: 07020 ast_copy_string(buf, ((struct sig_pri_chan *) p->sig_pvt)->keypad_digits, 07021 len); 07022 break; 07023 default: 07024 *buf = '\0'; 07025 res = -1; 07026 break; 07027 } 07028 ast_mutex_unlock(&p->lock); 07029 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */ 07030 } else if (!strcasecmp(data, "no_media_path")) { 07031 ast_mutex_lock(&p->lock); 07032 switch (p->sig) { 07033 case SIG_PRI_LIB_HANDLE_CASES: 07034 /* 07035 * TRUE if the call is on hold or is call waiting because 07036 * there is no media path available. 07037 */ 07038 snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel); 07039 break; 07040 default: 07041 *buf = '\0'; 07042 res = -1; 07043 break; 07044 } 07045 ast_mutex_unlock(&p->lock); 07046 #endif /* defined(HAVE_PRI) */ 07047 } else { 07048 *buf = '\0'; 07049 res = -1; 07050 } 07051 07052 return res; 07053 }
| static int dahdi_func_write | ( | struct ast_channel * | chan, | |
| const char * | function, | |||
| char * | data, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 7085 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.
07086 { 07087 struct dahdi_pvt *p = chan->tech_pvt; 07088 int res = 0; 07089 07090 if (!p) { 07091 /* No private structure! */ 07092 return -1; 07093 } 07094 07095 if (!strcasecmp(data, "buffers")) { 07096 int num_bufs, policy; 07097 07098 if (!(parse_buffers_policy(value, &num_bufs, &policy))) { 07099 struct dahdi_bufferinfo bi = { 07100 .txbufpolicy = policy, 07101 .rxbufpolicy = policy, 07102 .bufsize = p->bufsize, 07103 .numbufs = num_bufs, 07104 }; 07105 int bpres; 07106 07107 if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 07108 ast_log(LOG_WARNING, "Channel '%d' unable to override buffer policy: %s\n", p->channel, strerror(errno)); 07109 } else { 07110 p->bufferoverrideinuse = 1; 07111 } 07112 } else { 07113 res = -1; 07114 } 07115 } else if (!strcasecmp(data, "echocan_mode")) { 07116 if (!strcasecmp(value, "on")) { 07117 ast_mutex_lock(&p->lock); 07118 dahdi_enable_ec(p); 07119 ast_mutex_unlock(&p->lock); 07120 } else if (!strcasecmp(value, "off")) { 07121 ast_mutex_lock(&p->lock); 07122 dahdi_disable_ec(p); 07123 ast_mutex_unlock(&p->lock); 07124 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 07125 } else if (!strcasecmp(value, "fax")) { 07126 int blah = 1; 07127 07128 ast_mutex_lock(&p->lock); 07129 if (!p->echocanon) { 07130 dahdi_enable_ec(p); 07131 } 07132 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) { 07133 ast_log(LOG_WARNING, "Unable to place echocan into fax mode on channel %d: %s\n", p->channel, strerror(errno)); 07134 } 07135 ast_mutex_unlock(&p->lock); 07136 } else if (!strcasecmp(value, "voice")) { 07137 int blah = 0; 07138 07139 ast_mutex_lock(&p->lock); 07140 if (!p->echocanon) { 07141 dahdi_enable_ec(p); 07142 } 07143 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) { 07144 ast_log(LOG_WARNING, "Unable to place echocan into voice mode on channel %d: %s\n", p->channel, strerror(errno)); 07145 } 07146 ast_mutex_unlock(&p->lock); 07147 #endif 07148 } else { 07149 ast_log(LOG_WARNING, "Unsupported value '%s' provided for '%s' item.\n", value, data); 07150 res = -1; 07151 } 07152 } else { 07153 res = -1; 07154 } 07155 07156 return res; 07157 }
| static int dahdi_get_event | ( | int | fd | ) | [inline, static] |
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition at line 503 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().
00504 { 00505 int j; 00506 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1) 00507 return -1; 00508 return j; 00509 }
| static void dahdi_handle_dtmf | ( | struct ast_channel * | ast, | |
| int | idx, | |||
| struct ast_frame ** | dest | |||
| ) | [static] |
Definition at line 7782 of file chan_dahdi.c.
References ast_async_goto(), ast_channel_lock, ast_channel_name(), 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().
07783 { 07784 struct dahdi_pvt *p = ast->tech_pvt; 07785 struct ast_frame *f = *dest; 07786 07787 ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n", 07788 f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End", 07789 f->subclass.integer, f->subclass.integer, ast_channel_name(ast)); 07790 07791 if (p->confirmanswer) { 07792 if (f->frametype == AST_FRAME_DTMF_END) { 07793 ast_debug(1, "Confirm answer on %s!\n", ast_channel_name(ast)); 07794 /* Upon receiving a DTMF digit, consider this an answer confirmation instead 07795 of a DTMF digit */ 07796 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 07797 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 07798 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 07799 p->confirmanswer = 0; 07800 } else { 07801 p->subs[idx].f.frametype = AST_FRAME_NULL; 07802 p->subs[idx].f.subclass.integer = 0; 07803 } 07804 *dest = &p->subs[idx].f; 07805 } else if (p->callwaitcas) { 07806 if (f->frametype == AST_FRAME_DTMF_END) { 07807 if ((f->subclass.integer == 'A') || (f->subclass.integer == 'D')) { 07808 ast_debug(1, "Got some DTMF, but it's for the CAS\n"); 07809 ast_free(p->cidspill); 07810 p->cidspill = NULL; 07811 send_cwcidspill(p); 07812 } 07813 p->callwaitcas = 0; 07814 } 07815 p->subs[idx].f.frametype = AST_FRAME_NULL; 07816 p->subs[idx].f.subclass.integer = 0; 07817 *dest = &p->subs[idx].f; 07818 } else if (f->subclass.integer == 'f') { 07819 if (f->frametype == AST_FRAME_DTMF_END) { 07820 /* Fax tone -- Handle and return NULL */ 07821 if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) { 07822 /* If faxbuffers are configured, use them for the fax transmission */ 07823 if (p->usefaxbuffers && !p->bufferoverrideinuse) { 07824 struct dahdi_bufferinfo bi = { 07825 .txbufpolicy = p->faxbuf_policy, 07826 .bufsize = p->bufsize, 07827 .numbufs = p->faxbuf_no 07828 }; 07829 int res; 07830 07831 if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 07832 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno)); 07833 } else { 07834 p->bufferoverrideinuse = 1; 07835 } 07836 } 07837 p->faxhandled = 1; 07838 if (p->dsp) { 07839 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 07840 ast_dsp_set_features(p->dsp, p->dsp_features); 07841 ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast)); 07842 } 07843 if (strcmp(ast->exten, "fax")) { 07844 const char *target_context = S_OR(ast->macrocontext, ast->context); 07845 07846 /* We need to unlock 'ast' here because ast_exists_extension has the 07847 * potential to start autoservice on the channel. Such action is prone 07848 * to deadlock. 07849 */ 07850 ast_mutex_unlock(&p->lock); 07851 ast_channel_unlock(ast); 07852 if (ast_exists_extension(ast, target_context, "fax", 1, 07853 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 07854 ast_channel_lock(ast); 07855 ast_mutex_lock(&p->lock); 07856 ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast)); 07857 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 07858 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 07859 if (ast_async_goto(ast, target_context, "fax", 1)) 07860 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context); 07861 } else { 07862 ast_channel_lock(ast); 07863 ast_mutex_lock(&p->lock); 07864 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 07865 } 07866 } else { 07867 ast_debug(1, "Already in a fax extension, not redirecting\n"); 07868 } 07869 } else { 07870 ast_debug(1, "Fax already handled\n"); 07871 } 07872 dahdi_confmute(p, 0); 07873 } 07874 p->subs[idx].f.frametype = AST_FRAME_NULL; 07875 p->subs[idx].f.subclass.integer = 0; 07876 *dest = &p->subs[idx].f; 07877 } 07878 }
| static struct ast_frame* dahdi_handle_event | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 7901 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_name(), ast_channel_trylock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached, ast_queue_control(), ast_queue_control_data(), ast_queue_hangup_with_cause(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdup, ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, attempt_transfer(), ast_channel::caller, 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_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().
07902 { 07903 int res, x; 07904 int idx, mysig; 07905 char *c; 07906 struct dahdi_pvt *p = ast->tech_pvt; 07907 pthread_t threadid; 07908 struct ast_channel *chan; 07909 struct ast_frame *f; 07910 07911 idx = dahdi_get_index(ast, p, 0); 07912 mysig = p->sig; 07913 if (p->outsigmod > -1) 07914 mysig = p->outsigmod; 07915 p->subs[idx].f.frametype = AST_FRAME_NULL; 07916 p->subs[idx].f.subclass.integer = 0; 07917 p->subs[idx].f.datalen = 0; 07918 p->subs[idx].f.samples = 0; 07919 p->subs[idx].f.mallocd = 0; 07920 p->subs[idx].f.offset = 0; 07921 p->subs[idx].f.src = "dahdi_handle_event"; 07922 p->subs[idx].f.data.ptr = NULL; 07923 f = &p->subs[idx].f; 07924 07925 if (idx < 0) 07926 return &p->subs[idx].f; 07927 if (p->fake_event) { 07928 res = p->fake_event; 07929 p->fake_event = 0; 07930 } else 07931 res = dahdi_get_event(p->subs[idx].dfd); 07932 07933 ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, idx); 07934 07935 if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) { 07936 p->pulsedial = (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0; 07937 ast_debug(1, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff); 07938 #if defined(HAVE_PRI) 07939 if (dahdi_sig_pri_lib_handles(p->sig) 07940 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING 07941 && p->pri 07942 && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 07943 /* absorb event */ 07944 } else 07945 #endif /* defined(HAVE_PRI) */ 07946 { 07947 /* Unmute conference */ 07948 dahdi_confmute(p, 0); 07949 p->subs[idx].f.frametype = AST_FRAME_DTMF_END; 07950 p->subs[idx].f.subclass.integer = res & 0xff; 07951 dahdi_handle_dtmf(ast, idx, &f); 07952 } 07953 return f; 07954 } 07955 07956 if (res & DAHDI_EVENT_DTMFDOWN) { 07957 ast_debug(1, "DTMF Down '%c'\n", res & 0xff); 07958 #if defined(HAVE_PRI) 07959 if (dahdi_sig_pri_lib_handles(p->sig) 07960 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING 07961 && p->pri 07962 && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) { 07963 /* absorb event */ 07964 } else 07965 #endif /* defined(HAVE_PRI) */ 07966 { 07967 /* Mute conference */ 07968 dahdi_confmute(p, 1); 07969 p->subs[idx].f.frametype = AST_FRAME_DTMF_BEGIN; 07970 p->subs[idx].f.subclass.integer = res & 0xff; 07971 dahdi_handle_dtmf(ast, idx, &f); 07972 } 07973 return &p->subs[idx].f; 07974 } 07975 07976 switch (res) { 07977 case DAHDI_EVENT_EC_DISABLED: 07978 ast_verb(3, "Channel %d echo canceler disabled.\n", p->channel); 07979 p->echocanon = 0; 07980 break; 07981 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 07982 case DAHDI_EVENT_TX_CED_DETECTED: 07983 ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel); 07984 break; 07985 case DAHDI_EVENT_RX_CED_DETECTED: 07986 ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel); 07987 break; 07988 case DAHDI_EVENT_EC_NLP_DISABLED: 07989 ast_verb(3, "Channel %d echo canceler disabled its NLP.\n", p->channel); 07990 break; 07991 case DAHDI_EVENT_EC_NLP_ENABLED: 07992 ast_verb(3, "Channel %d echo canceler enabled its NLP.\n", p->channel); 07993 break; 07994 #endif 07995 case DAHDI_EVENT_BITSCHANGED: 07996 #ifdef HAVE_OPENR2 07997 if (p->sig != SIG_MFCR2) { 07998 ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig)); 07999 } else { 08000 ast_debug(1, "bits changed in chan %d\n", p->channel); 08001 openr2_chan_handle_cas(p->r2chan); 08002 } 08003 #else 08004 ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig)); 08005 #endif 08006 case DAHDI_EVENT_PULSE_START: 08007 /* Stop tone if there's a pulse start and the PBX isn't started */ 08008 if (!ast->pbx) 08009 tone_zone_play_tone(p->subs[idx].dfd, -1); 08010 break; 08011 case DAHDI_EVENT_DIALCOMPLETE: 08012 /* DAHDI has completed dialing all digits sent using DAHDI_DIAL. */ 08013 #if defined(HAVE_PRI) 08014 if (dahdi_sig_pri_lib_handles(p->sig)) { 08015 if (p->inalarm) { 08016 break; 08017 } 08018 if (ioctl(p->subs[idx].dfd, DAHDI_DIALING, &x) == -1) { 08019 ast_debug(1, "DAHDI_DIALING ioctl failed on %s: %s\n", 08020 ast_channel_name(ast), strerror(errno)); 08021 return NULL; 08022 } 08023 if (x) { 08024 /* Still dialing in DAHDI driver */ 08025 break; 08026 } 08027 /* 08028 * The ast channel is locked and the private may be locked more 08029 * than once. 08030 */ 08031 sig_pri_dial_complete(p->sig_pvt, ast); 08032 break; 08033 } 08034 #endif /* defined(HAVE_PRI) */ 08035 #ifdef HAVE_OPENR2 08036 if ((p->sig & SIG_MFCR2) && p->r2chan && ast->_state != AST_STATE_UP) { 08037 /* we don't need to do anything for this event for R2 signaling 08038 if the call is being setup */ 08039 break; 08040 } 08041 #endif 08042 if (p->inalarm) break; 08043 if ((p->radio || (p->oprmode < 0))) break; 08044 if (ioctl(p->subs[idx].dfd,DAHDI_DIALING,&x) == -1) { 08045 ast_debug(1, "DAHDI_DIALING ioctl failed on %s: %s\n",ast_channel_name(ast), strerror(errno)); 08046 return NULL; 08047 } 08048 if (!x) { /* if not still dialing in driver */ 08049 dahdi_enable_ec(p); 08050 if (p->echobreak) { 08051 dahdi_train_ec(p); 08052 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr)); 08053 p->dop.op = DAHDI_DIAL_OP_REPLACE; 08054 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08055 p->echobreak = 0; 08056 } else { 08057 p->dialing = 0; 08058 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) { 08059 /* if thru with dialing after offhook */ 08060 if (ast->_state == AST_STATE_DIALING_OFFHOOK) { 08061 ast_setstate(ast, AST_STATE_UP); 08062 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08063 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08064 break; 08065 } else { /* if to state wait for offhook to dial rest */ 08066 /* we now wait for off hook */ 08067 ast_setstate(ast,AST_STATE_DIALING_OFFHOOK); 08068 } 08069 } 08070 if (ast->_state == AST_STATE_DIALING) { 08071 if ((p->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 08072 ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n"); 08073 } else if (p->confirmanswer || (!p->dialednone 08074 && ((mysig == SIG_EM) || (mysig == SIG_EM_E1) 08075 || (mysig == SIG_EMWINK) || (mysig == SIG_FEATD) 08076 || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF) 08077 || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) 08078 || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB) 08079 || (mysig == SIG_SF) || (mysig == SIG_SFWINK) 08080 || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF) 08081 || (mysig == SIG_SF_FEATB)))) { 08082 ast_setstate(ast, AST_STATE_RINGING); 08083 } else if (!p->answeronpolarityswitch) { 08084 ast_setstate(ast, AST_STATE_UP); 08085 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08086 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08087 /* If aops=0 and hops=1, this is necessary */ 08088 p->polarity = POLARITY_REV; 08089 } else { 08090 /* Start clean, so we can catch the change to REV polarity when party answers */ 08091 p->polarity = POLARITY_IDLE; 08092 } 08093 } 08094 } 08095 } 08096 break; 08097 case DAHDI_EVENT_ALARM: 08098 switch (p->sig) { 08099 #if defined(HAVE_PRI) 08100 case SIG_PRI_LIB_HANDLE_CASES: 08101 sig_pri_chan_alarm_notify(p->sig_pvt, 0); 08102 break; 08103 #endif /* defined(HAVE_PRI) */ 08104 #if defined(HAVE_SS7) 08105 case SIG_SS7: 08106 sig_ss7_set_alarm(p->sig_pvt, 1); 08107 break; 08108 #endif /* defined(HAVE_SS7) */ 08109 default: 08110 p->inalarm = 1; 08111 break; 08112 } 08113 res = get_alarms(p); 08114 handle_alarms(p, res); 08115 #ifdef HAVE_PRI 08116 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) { 08117 /* fall through intentionally */ 08118 } else { 08119 break; 08120 } 08121 #endif 08122 #if defined(HAVE_SS7) 08123 if (p->sig == SIG_SS7) 08124 break; 08125 #endif /* defined(HAVE_SS7) */ 08126 #ifdef HAVE_OPENR2 08127 if (p->sig == SIG_MFCR2) 08128 break; 08129 #endif 08130 case DAHDI_EVENT_ONHOOK: 08131 if (p->radio) { 08132 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08133 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_UNKEY; 08134 break; 08135 } 08136 if (p->oprmode < 0) 08137 { 08138 if (p->oprmode != -1) break; 08139 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 08140 { 08141 /* Make sure it starts ringing */ 08142 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 08143 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RING); 08144 save_conference(p->oprpeer); 08145 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 08146 } 08147 break; 08148 } 08149 switch (p->sig) { 08150 case SIG_FXOLS: 08151 case SIG_FXOGS: 08152 case SIG_FXOKS: 08153 /* Check for some special conditions regarding call waiting */ 08154 if (idx == SUB_REAL) { 08155 /* The normal line was hung up */ 08156 if (p->subs[SUB_CALLWAIT].owner) { 08157 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ 08158 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 08159 ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel); 08160 unalloc_sub(p, SUB_CALLWAIT); 08161 #if 0 08162 p->subs[idx].needanswer = 0; 08163 p->subs[idx].needringing = 0; 08164 #endif 08165 p->callwaitingrepeat = 0; 08166 p->cidcwexpire = 0; 08167 p->cid_suppress_expire = 0; 08168 p->owner = NULL; 08169 /* Don't start streaming audio yet if the incoming call isn't up yet */ 08170 if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP) 08171 p->dialing = 1; 08172 dahdi_ring_phone(p); 08173 } else if (p->subs[SUB_THREEWAY].owner) { 08174 unsigned int mssinceflash; 08175 /* Here we have to retain the lock on both the main channel, the 3-way channel, and 08176 the private structure -- not especially easy or clean */ 08177 while (p->subs[SUB_THREEWAY].owner && ast_channel_trylock(p->subs[SUB_THREEWAY].owner)) { 08178 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */ 08179 DLA_UNLOCK(&p->lock); 08180 CHANNEL_DEADLOCK_AVOIDANCE(ast); 08181 /* We can grab ast and p in that order, without worry. We should make sure 08182 nothing seriously bad has happened though like some sort of bizarre double 08183 masquerade! */ 08184 DLA_LOCK(&p->lock); 08185 if (p->owner != ast) { 08186 ast_log(LOG_WARNING, "This isn't good...\n"); 08187 return NULL; 08188 } 08189 } 08190 if (!p->subs[SUB_THREEWAY].owner) { 08191 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n"); 08192 return NULL; 08193 } 08194 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime); 08195 ast_debug(1, "Last flash was %d ms ago\n", mssinceflash); 08196 if (mssinceflash < MIN_MS_SINCE_FLASH) { 08197 /* It hasn't been long enough since the last flashook. This is probably a bounce on 08198 hanging up. Hangup both channels now */ 08199 if (p->subs[SUB_THREEWAY].owner) 08200 ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY].owner, AST_CAUSE_NO_ANSWER); 08201 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08202 ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel); 08203 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08204 } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) { 08205 if (p->transfer) { 08206 /* In any case this isn't a threeway call anymore */ 08207 p->subs[SUB_REAL].inthreeway = 0; 08208 p->subs[SUB_THREEWAY].inthreeway = 0; 08209 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 08210 if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) { 08211 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08212 /* Swap subs and dis-own channel */ 08213 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08214 p->owner = NULL; 08215 /* Ring the phone */ 08216 dahdi_ring_phone(p); 08217 } else { 08218 if ((res = attempt_transfer(p)) < 0) { 08219 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08220 if (p->subs[SUB_THREEWAY].owner) 08221 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08222 } else if (res) { 08223 /* Don't actually hang up at this point */ 08224 if (p->subs[SUB_THREEWAY].owner) 08225 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08226 break; 08227 } 08228 } 08229 } else { 08230 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08231 if (p->subs[SUB_THREEWAY].owner) 08232 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08233 } 08234 } else { 08235 ast_channel_unlock(p->subs[SUB_THREEWAY].owner); 08236 /* Swap subs and dis-own channel */ 08237 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08238 p->owner = NULL; 08239 /* Ring the phone */ 08240 dahdi_ring_phone(p); 08241 } 08242 } 08243 } else { 08244 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", idx); 08245 } 08246 /* Fall through */ 08247 default: 08248 dahdi_disable_ec(p); 08249 return NULL; 08250 } 08251 break; 08252 case DAHDI_EVENT_RINGOFFHOOK: 08253 if (p->inalarm) break; 08254 if (p->oprmode < 0) 08255 { 08256 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) 08257 { 08258 /* Make sure it stops ringing */ 08259 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 08260 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, -1); 08261 restore_conference(p->oprpeer); 08262 } 08263 break; 08264 } 08265 if (p->radio) 08266 { 08267 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08268 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_KEY; 08269 break; 08270 } 08271 /* for E911, its supposed to wait for offhook then dial 08272 the second half of the dial string */ 08273 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) { 08274 c = strchr(p->dialdest, '/'); 08275 if (c) 08276 c++; 08277 else 08278 c = p->dialdest; 08279 if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c); 08280 else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr)); 08281 if (strlen(p->dop.dialstr) > 4) { 08282 memset(p->echorest, 'w', sizeof(p->echorest) - 1); 08283 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2); 08284 p->echorest[sizeof(p->echorest) - 1] = '\0'; 08285 p->echobreak = 1; 08286 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0'; 08287 } else 08288 p->echobreak = 0; 08289 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) { 08290 int saveerr = errno; 08291 08292 x = DAHDI_ONHOOK; 08293 ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 08294 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr)); 08295 return NULL; 08296 } 08297 p->dialing = 1; 08298 return &p->subs[idx].f; 08299 } 08300 switch (p->sig) { 08301 case SIG_FXOLS: 08302 case SIG_FXOGS: 08303 case SIG_FXOKS: 08304 switch (ast->_state) { 08305 case AST_STATE_RINGING: 08306 dahdi_enable_ec(p); 08307 dahdi_train_ec(p); 08308 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08309 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08310 /* Make sure it stops ringing */ 08311 p->subs[SUB_REAL].needringing = 0; 08312 dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 08313 ast_debug(1, "channel %d answered\n", p->channel); 08314 08315 /* Cancel any running CallerID spill */ 08316 ast_free(p->cidspill); 08317 p->cidspill = NULL; 08318 restore_conference(p); 08319 08320 p->dialing = 0; 08321 p->callwaitcas = 0; 08322 if (p->confirmanswer) { 08323 /* Ignore answer if "confirm answer" is enabled */ 08324 p->subs[idx].f.frametype = AST_FRAME_NULL; 08325 p->subs[idx].f.subclass.integer = 0; 08326 } else if (!ast_strlen_zero(p->dop.dialstr)) { 08327 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 08328 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08329 if (res < 0) { 08330 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08331 p->dop.dialstr[0] = '\0'; 08332 return NULL; 08333 } else { 08334 ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr); 08335 p->subs[idx].f.frametype = AST_FRAME_NULL; 08336 p->subs[idx].f.subclass.integer = 0; 08337 p->dialing = 1; 08338 } 08339 p->dop.dialstr[0] = '\0'; 08340 ast_setstate(ast, AST_STATE_DIALING); 08341 } else 08342 ast_setstate(ast, AST_STATE_UP); 08343 return &p->subs[idx].f; 08344 case AST_STATE_DOWN: 08345 ast_setstate(ast, AST_STATE_RING); 08346 ast->rings = 1; 08347 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08348 p->subs[idx].f.subclass.integer = AST_CONTROL_OFFHOOK; 08349 ast_debug(1, "channel %d picked up\n", p->channel); 08350 return &p->subs[idx].f; 08351 case AST_STATE_UP: 08352 /* Make sure it stops ringing */ 08353 dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 08354 /* Okay -- probably call waiting*/ 08355 if (ast_bridged_channel(p->owner)) 08356 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 08357 p->subs[idx].needunhold = 1; 08358 break; 08359 case AST_STATE_RESERVED: 08360 /* Start up dialtone */ 08361 if (has_voicemail(p)) 08362 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER); 08363 else 08364 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE); 08365 break; 08366 default: 08367 ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); 08368 } 08369 break; 08370 case SIG_FXSLS: 08371 case SIG_FXSGS: 08372 case SIG_FXSKS: 08373 if (ast->_state == AST_STATE_RING) { 08374 p->ringt = p->ringt_base; 08375 } 08376 08377 /* If we get a ring then we cannot be in 08378 * reversed polarity. So we reset to idle */ 08379 ast_debug(1, "Setting IDLE polarity due " 08380 "to ring. Old polarity was %d\n", 08381 p->polarity); 08382 p->polarity = POLARITY_IDLE; 08383 08384 /* Fall through */ 08385 case SIG_EM: 08386 case SIG_EM_E1: 08387 case SIG_EMWINK: 08388 case SIG_FEATD: 08389 case SIG_FEATDMF: 08390 case SIG_FEATDMF_TA: 08391 case SIG_E911: 08392 case SIG_FGC_CAMA: 08393 case SIG_FGC_CAMAMF: 08394 case SIG_FEATB: 08395 case SIG_SF: 08396 case SIG_SFWINK: 08397 case SIG_SF_FEATD: 08398 case SIG_SF_FEATDMF: 08399 case SIG_SF_FEATB: 08400 if (ast->_state == AST_STATE_PRERING) 08401 ast_setstate(ast, AST_STATE_RING); 08402 if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) { 08403 ast_debug(1, "Ring detected\n"); 08404 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08405 p->subs[idx].f.subclass.integer = AST_CONTROL_RING; 08406 } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) { 08407 ast_debug(1, "Line answered\n"); 08408 if (p->confirmanswer) { 08409 p->subs[idx].f.frametype = AST_FRAME_NULL; 08410 p->subs[idx].f.subclass.integer = 0; 08411 } else { 08412 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08413 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 08414 ast_setstate(ast, AST_STATE_UP); 08415 } 08416 } else if (ast->_state != AST_STATE_RING) 08417 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); 08418 break; 08419 default: 08420 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 08421 } 08422 break; 08423 case DAHDI_EVENT_RINGBEGIN: 08424 switch (p->sig) { 08425 case SIG_FXSLS: 08426 case SIG_FXSGS: 08427 case SIG_FXSKS: 08428 if (ast->_state == AST_STATE_RING) { 08429 p->ringt = p->ringt_base; 08430 } 08431 break; 08432 } 08433 break; 08434 case DAHDI_EVENT_RINGERON: 08435 break; 08436 case DAHDI_EVENT_NOALARM: 08437 switch (p->sig) { 08438 #if defined(HAVE_PRI) 08439 case SIG_PRI_LIB_HANDLE_CASES: 08440 sig_pri_chan_alarm_notify(p->sig_pvt, 1); 08441 break; 08442 #endif /* defined(HAVE_PRI) */ 08443 #if defined(HAVE_SS7) 08444 case SIG_SS7: 08445 sig_ss7_set_alarm(p->sig_pvt, 0); 08446 break; 08447 #endif /* defined(HAVE_SS7) */ 08448 default: 08449 p->inalarm = 0; 08450 break; 08451 } 08452 handle_clear_alarms(p); 08453 break; 08454 case DAHDI_EVENT_WINKFLASH: 08455 if (p->inalarm) break; 08456 if (p->radio) break; 08457 if (p->oprmode < 0) break; 08458 if (p->oprmode > 1) 08459 { 08460 struct dahdi_params par; 08461 08462 memset(&par, 0, sizeof(par)); 08463 if (ioctl(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par) != -1) 08464 { 08465 if (!par.rxisoffhook) 08466 { 08467 /* Make sure it stops ringing */ 08468 dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RINGOFF); 08469 dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RING); 08470 save_conference(p); 08471 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 08472 } 08473 } 08474 break; 08475 } 08476 /* Remember last time we got a flash-hook */ 08477 p->flashtime = ast_tvnow(); 08478 switch (mysig) { 08479 case SIG_FXOLS: 08480 case SIG_FXOGS: 08481 case SIG_FXOKS: 08482 ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", 08483 idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd); 08484 08485 /* Cancel any running CallerID spill */ 08486 ast_free(p->cidspill); 08487 p->cidspill = NULL; 08488 restore_conference(p); 08489 p->callwaitcas = 0; 08490 08491 if (idx != SUB_REAL) { 08492 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", idx, p->channel); 08493 goto winkflashdone; 08494 } 08495 08496 if (p->subs[SUB_CALLWAIT].owner) { 08497 /* Swap to call-wait */ 08498 swap_subs(p, SUB_REAL, SUB_CALLWAIT); 08499 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 08500 p->owner = p->subs[SUB_REAL].owner; 08501 ast_debug(1, "Making %s the new owner\n", ast_channel_name(p->owner)); 08502 if (p->owner->_state == AST_STATE_RINGING) { 08503 ast_setstate(p->owner, AST_STATE_UP); 08504 p->subs[SUB_REAL].needanswer = 1; 08505 } 08506 p->callwaitingrepeat = 0; 08507 p->cidcwexpire = 0; 08508 p->cid_suppress_expire = 0; 08509 /* Start music on hold if appropriate */ 08510 if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 08511 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 08512 S_OR(p->mohsuggest, NULL), 08513 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08514 } 08515 p->subs[SUB_CALLWAIT].needhold = 1; 08516 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) { 08517 ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD, 08518 S_OR(p->mohsuggest, NULL), 08519 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08520 } 08521 p->subs[SUB_REAL].needunhold = 1; 08522 } else if (!p->subs[SUB_THREEWAY].owner) { 08523 if (!p->threewaycalling) { 08524 /* Just send a flash if no 3-way calling */ 08525 p->subs[SUB_REAL].needflash = 1; 08526 goto winkflashdone; 08527 } else if (!check_for_conference(p)) { 08528 char cid_num[256]; 08529 char cid_name[256]; 08530 08531 cid_num[0] = 0; 08532 cid_name[0] = 0; 08533 if (p->dahditrcallerid && p->owner) { 08534 if (p->owner->caller.id.number.valid 08535 && p->owner->caller.id.number.str) { 08536 ast_copy_string(cid_num, p->owner->caller.id.number.str, 08537 sizeof(cid_num)); 08538 } 08539 if (p->owner->caller.id.name.valid 08540 && p->owner->caller.id.name.str) { 08541 ast_copy_string(cid_name, p->owner->caller.id.name.str, 08542 sizeof(cid_name)); 08543 } 08544 } 08545 /* XXX This section needs much more error checking!!! XXX */ 08546 /* Start a 3-way call if feasible */ 08547 if (!((ast->pbx) || 08548 (ast->_state == AST_STATE_UP) || 08549 (ast->_state == AST_STATE_RING))) { 08550 ast_debug(1, "Flash when call not up or ringing\n"); 08551 goto winkflashdone; 08552 } 08553 if (alloc_sub(p, SUB_THREEWAY)) { 08554 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n"); 08555 goto winkflashdone; 08556 } 08557 /* Make new channel */ 08558 chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, NULL); 08559 if (p->dahditrcallerid) { 08560 if (!p->origcid_num) 08561 p->origcid_num = ast_strdup(p->cid_num); 08562 if (!p->origcid_name) 08563 p->origcid_name = ast_strdup(p->cid_name); 08564 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num)); 08565 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name)); 08566 } 08567 /* Swap things around between the three-way and real call */ 08568 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08569 /* Disable echo canceller for better dialing */ 08570 dahdi_disable_ec(p); 08571 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALRECALL); 08572 if (res) 08573 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel); 08574 p->owner = chan; 08575 if (!chan) { 08576 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel); 08577 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 08578 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel); 08579 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 08580 dahdi_enable_ec(p); 08581 ast_hangup(chan); 08582 } else { 08583 ast_verb(3, "Started three way call on channel %d\n", p->channel); 08584 08585 /* Start music on hold if appropriate */ 08586 if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 08587 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 08588 S_OR(p->mohsuggest, NULL), 08589 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 08590 } 08591 p->subs[SUB_THREEWAY].needhold = 1; 08592 } 08593 } 08594 } else { 08595 /* Already have a 3 way call */ 08596 if (p->subs[SUB_THREEWAY].inthreeway) { 08597 /* Call is already up, drop the last person */ 08598 ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel); 08599 /* If the primary call isn't answered yet, use it */ 08600 if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) { 08601 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 08602 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08603 p->owner = p->subs[SUB_REAL].owner; 08604 } 08605 /* Drop the last call and stop the conference */ 08606 ast_verb(3, "Dropping three-way call on %s\n", ast_channel_name(p->subs[SUB_THREEWAY].owner)); 08607 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08608 p->subs[SUB_REAL].inthreeway = 0; 08609 p->subs[SUB_THREEWAY].inthreeway = 0; 08610 } else { 08611 /* Lets see what we're up to */ 08612 if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 08613 (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) { 08614 int otherindex = SUB_THREEWAY; 08615 08616 ast_verb(3, "Building conference call with %s and %s\n", 08617 ast_channel_name(p->subs[SUB_THREEWAY].owner), 08618 ast_channel_name(p->subs[SUB_REAL].owner)); 08619 /* Put them in the threeway, and flip */ 08620 p->subs[SUB_THREEWAY].inthreeway = 1; 08621 p->subs[SUB_REAL].inthreeway = 1; 08622 if (ast->_state == AST_STATE_UP) { 08623 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08624 otherindex = SUB_REAL; 08625 } 08626 if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner)) 08627 ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD); 08628 p->subs[otherindex].needunhold = 1; 08629 p->owner = p->subs[SUB_REAL].owner; 08630 } else { 08631 ast_verb(3, "Dumping incomplete call on on %s\n", ast_channel_name(p->subs[SUB_THREEWAY].owner)); 08632 swap_subs(p, SUB_THREEWAY, SUB_REAL); 08633 p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV; 08634 p->owner = p->subs[SUB_REAL].owner; 08635 if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner)) 08636 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 08637 p->subs[SUB_REAL].needunhold = 1; 08638 dahdi_enable_ec(p); 08639 } 08640 } 08641 } 08642 winkflashdone: 08643 update_conf(p); 08644 break; 08645 case SIG_EM: 08646 case SIG_EM_E1: 08647 case SIG_FEATD: 08648 case SIG_SF: 08649 case SIG_SFWINK: 08650 case SIG_SF_FEATD: 08651 case SIG_FXSLS: 08652 case SIG_FXSGS: 08653 if (p->dialing) 08654 ast_debug(1, "Ignoring wink on channel %d\n", p->channel); 08655 else 08656 ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); 08657 break; 08658 case SIG_FEATDMF_TA: 08659 switch (p->whichwink) { 08660 case 0: 08661 ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->caller.ani2, 08662 S_COR(p->owner->caller.ani.number.valid, 08663 p->owner->caller.ani.number.str, "")); 08664 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", 08665 p->owner->caller.ani2, 08666 S_COR(p->owner->caller.ani.number.valid, 08667 p->owner->caller.ani.number.str, "")); 08668 break; 08669 case 1: 08670 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr)); 08671 break; 08672 case 2: 08673 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n"); 08674 return NULL; 08675 } 08676 p->whichwink++; 08677 /* Fall through */ 08678 case SIG_FEATDMF: 08679 case SIG_E911: 08680 case SIG_FGC_CAMAMF: 08681 case SIG_FGC_CAMA: 08682 case SIG_FEATB: 08683 case SIG_SF_FEATDMF: 08684 case SIG_SF_FEATB: 08685 case SIG_EMWINK: 08686 /* FGD MF and EMWINK *Must* wait for wink */ 08687 if (!ast_strlen_zero(p->dop.dialstr)) { 08688 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08689 if (res < 0) { 08690 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08691 p->dop.dialstr[0] = '\0'; 08692 return NULL; 08693 } else 08694 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr); 08695 } 08696 p->dop.dialstr[0] = '\0'; 08697 break; 08698 default: 08699 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig); 08700 } 08701 break; 08702 case DAHDI_EVENT_HOOKCOMPLETE: 08703 if (p->inalarm) break; 08704 if ((p->radio || (p->oprmode < 0))) break; 08705 if (p->waitingfordt.tv_sec) break; 08706 switch (mysig) { 08707 case SIG_FXSLS: /* only interesting for FXS */ 08708 case SIG_FXSGS: 08709 case SIG_FXSKS: 08710 case SIG_EM: 08711 case SIG_EM_E1: 08712 case SIG_EMWINK: 08713 case SIG_FEATD: 08714 case SIG_SF: 08715 case SIG_SFWINK: 08716 case SIG_SF_FEATD: 08717 if (!ast_strlen_zero(p->dop.dialstr)) { 08718 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 08719 if (res < 0) { 08720 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno)); 08721 p->dop.dialstr[0] = '\0'; 08722 return NULL; 08723 } else 08724 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr); 08725 } 08726 p->dop.dialstr[0] = '\0'; 08727 p->dop.op = DAHDI_DIAL_OP_REPLACE; 08728 break; 08729 case SIG_FEATDMF: 08730 case SIG_FEATDMF_TA: 08731 case SIG_E911: 08732 case SIG_FGC_CAMA: 08733 case SIG_FGC_CAMAMF: 08734 case SIG_FEATB: 08735 case SIG_SF_FEATDMF: 08736 case SIG_SF_FEATB: 08737 ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel); 08738 break; 08739 default: 08740 break; 08741 } 08742 break; 08743 case DAHDI_EVENT_POLARITY: 08744 /* 08745 * If we get a Polarity Switch event, check to see 08746 * if we should change the polarity state and 08747 * mark the channel as UP or if this is an indication 08748 * of remote end disconnect. 08749 */ 08750 if (p->polarity == POLARITY_IDLE) { 08751 p->polarity = POLARITY_REV; 08752 if (p->answeronpolarityswitch && 08753 ((ast->_state == AST_STATE_DIALING) || 08754 (ast->_state == AST_STATE_RINGING))) { 08755 ast_debug(1, "Answering on polarity switch!\n"); 08756 ast_setstate(p->owner, AST_STATE_UP); 08757 if (p->hanguponpolarityswitch) { 08758 p->polaritydelaytv = ast_tvnow(); 08759 } 08760 } else 08761 ast_debug(1, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state); 08762 } 08763 /* Removed else statement from here as it was preventing hangups from ever happening*/ 08764 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */ 08765 if (p->hanguponpolarityswitch && 08766 (p->polarityonanswerdelay > 0) && 08767 (p->polarity == POLARITY_REV) && 08768 ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) { 08769 /* Added log_debug information below to provide a better indication of what is going on */ 08770 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) ); 08771 08772 if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) { 08773 ast_debug(1, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel); 08774 ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); 08775 p->polarity = POLARITY_IDLE; 08776 } else 08777 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); 08778 08779 } else { 08780 p->polarity = POLARITY_IDLE; 08781 ast_debug(1, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state); 08782 } 08783 /* Added more log_debug information below to provide a better indication of what is going on */ 08784 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) ); 08785 break; 08786 default: 08787 ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel); 08788 } 08789 return &p->subs[idx].f; 08790 }
| static int dahdi_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 6169 of file chan_dahdi.c.
References ast_channel::_state, analog_hangup(), analog_lib_handles(), ast_bridged_channel(), ast_channel_name(), 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, iflock, dahdi_pvt::ignoredtmf, dahdi_subchannel::inthreeway, dahdi_pvt::law, dahdi_pvt::law_default, dahdi_subchannel::linear, dahdi_pvt::lock, 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.
06170 { 06171 int res = 0; 06172 int idx,x; 06173 int law; 06174 /*static int restore_gains(struct dahdi_pvt *p);*/ 06175 struct dahdi_pvt *p = ast->tech_pvt; 06176 struct dahdi_params par; 06177 06178 ast_debug(1, "dahdi_hangup(%s)\n", ast_channel_name(ast)); 06179 if (!ast->tech_pvt) { 06180 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 06181 return 0; 06182 } 06183 06184 ast_mutex_lock(&p->lock); 06185 p->exten[0] = '\0'; 06186 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 06187 dahdi_confmute(p, 0); 06188 restore_gains(p); 06189 p->ignoredtmf = 0; 06190 p->waitingfordt.tv_sec = 0; 06191 06192 res = analog_hangup(p->sig_pvt, ast); 06193 revert_fax_buffers(p, ast); 06194 06195 goto hangup_out; 06196 } else { 06197 p->cid_num[0] = '\0'; 06198 p->cid_name[0] = '\0'; 06199 p->cid_subaddr[0] = '\0'; 06200 } 06201 06202 #if defined(HAVE_PRI) 06203 if (dahdi_sig_pri_lib_handles(p->sig)) { 06204 x = 1; 06205 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06206 06207 dahdi_confmute(p, 0); 06208 p->muting = 0; 06209 restore_gains(p); 06210 if (p->dsp) { 06211 ast_dsp_free(p->dsp); 06212 p->dsp = NULL; 06213 } 06214 p->ignoredtmf = 0; 06215 06216 /* Real channel, do some fixup */ 06217 p->subs[SUB_REAL].owner = NULL; 06218 p->subs[SUB_REAL].needbusy = 0; 06219 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 06220 06221 p->owner = NULL; 06222 p->cid_tag[0] = '\0'; 06223 p->ringt = 0;/* Probably not used in this mode. Reset anyway. */ 06224 p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */ 06225 p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */ 06226 p->outgoing = 0; 06227 p->digital = 0; 06228 p->faxhandled = 0; 06229 p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */ 06230 06231 revert_fax_buffers(p, ast); 06232 06233 p->law = p->law_default; 06234 law = p->law_default; 06235 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06236 if (res < 0) { 06237 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", 06238 p->channel, strerror(errno)); 06239 } 06240 06241 sig_pri_hangup(p->sig_pvt, ast); 06242 06243 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06244 dahdi_disable_ec(p); 06245 06246 x = 0; 06247 ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0); 06248 p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */ 06249 06250 p->rdnis[0] = '\0'; 06251 update_conf(p); 06252 reset_conf(p); 06253 06254 /* Restore data mode */ 06255 x = 0; 06256 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06257 06258 if (num_restart_pending == 0) { 06259 restart_monitor(); 06260 } 06261 goto hangup_out; 06262 } 06263 #endif /* defined(HAVE_PRI) */ 06264 06265 #if defined(HAVE_SS7) 06266 if (p->sig == SIG_SS7) { 06267 x = 1; 06268 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06269 06270 dahdi_confmute(p, 0); 06271 p->muting = 0; 06272 restore_gains(p); 06273 if (p->dsp) { 06274 ast_dsp_free(p->dsp); 06275 p->dsp = NULL; 06276 } 06277 p->ignoredtmf = 0; 06278 06279 /* Real channel, do some fixup */ 06280 p->subs[SUB_REAL].owner = NULL; 06281 p->subs[SUB_REAL].needbusy = 0; 06282 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 06283 06284 p->owner = NULL; 06285 p->ringt = 0;/* Probably not used in this mode. Reset anyway. */ 06286 p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */ 06287 p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */ 06288 p->outgoing = 0; 06289 p->digital = 0; 06290 p->faxhandled = 0; 06291 p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */ 06292 06293 revert_fax_buffers(p, ast); 06294 06295 p->law = p->law_default; 06296 law = p->law_default; 06297 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06298 if (res < 0) { 06299 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", 06300 p->channel, strerror(errno)); 06301 } 06302 06303 sig_ss7_hangup(p->sig_pvt, ast); 06304 06305 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06306 dahdi_disable_ec(p); 06307 06308 x = 0; 06309 ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0); 06310 p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */ 06311 06312 update_conf(p); 06313 reset_conf(p); 06314 06315 /* Restore data mode */ 06316 x = 0; 06317 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0); 06318 06319 if (num_restart_pending == 0) { 06320 restart_monitor(); 06321 } 06322 goto hangup_out; 06323 } 06324 #endif /* defined(HAVE_SS7) */ 06325 06326 idx = dahdi_get_index(ast, p, 1); 06327 06328 dahdi_confmute(p, 0); 06329 p->muting = 0; 06330 restore_gains(p); 06331 if (p->origcid_num) { 06332 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num)); 06333 ast_free(p->origcid_num); 06334 p->origcid_num = NULL; 06335 } 06336 if (p->origcid_name) { 06337 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name)); 06338 ast_free(p->origcid_name); 06339 p->origcid_name = NULL; 06340 } 06341 if (p->dsp) 06342 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 06343 06344 ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n", 06345 p->channel, idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd); 06346 p->ignoredtmf = 0; 06347 06348 if (idx > -1) { 06349 /* Real channel, do some fixup */ 06350 p->subs[idx].owner = NULL; 06351 p->subs[idx].needanswer = 0; 06352 p->subs[idx].needflash = 0; 06353 p->subs[idx].needringing = 0; 06354 p->subs[idx].needbusy = 0; 06355 p->subs[idx].needcongestion = 0; 06356 p->subs[idx].linear = 0; 06357 p->polarity = POLARITY_IDLE; 06358 dahdi_setlinear(p->subs[idx].dfd, 0); 06359 if (idx == SUB_REAL) { 06360 if ((p->subs[SUB_CALLWAIT].dfd > -1) && (p->subs[SUB_THREEWAY].dfd > -1)) { 06361 ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n"); 06362 if (p->subs[SUB_CALLWAIT].inthreeway) { 06363 /* We had flipped over to answer a callwait and now it's gone */ 06364 ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n"); 06365 /* Move to the call-wait, but un-own us until they flip back. */ 06366 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 06367 unalloc_sub(p, SUB_CALLWAIT); 06368 p->owner = NULL; 06369 } else { 06370 /* The three way hung up, but we still have a call wait */ 06371 ast_debug(1, "We were in the threeway and have a callwait still. Ditching the threeway.\n"); 06372 swap_subs(p, SUB_THREEWAY, SUB_REAL); 06373 unalloc_sub(p, SUB_THREEWAY); 06374 if (p->subs[SUB_REAL].inthreeway) { 06375 /* This was part of a three way call. Immediately make way for 06376 another call */ 06377 ast_debug(1, "Call was complete, setting owner to former third call\n"); 06378 p->owner = p->subs[SUB_REAL].owner; 06379 } else { 06380 /* This call hasn't been completed yet... Set owner to NULL */ 06381 ast_debug(1, "Call was incomplete, setting owner to NULL\n"); 06382 p->owner = NULL; 06383 } 06384 p->subs[SUB_REAL].inthreeway = 0; 06385 } 06386 } else if (p->subs[SUB_CALLWAIT].dfd > -1) { 06387 /* Move to the call-wait and switch back to them. */ 06388 swap_subs(p, SUB_CALLWAIT, SUB_REAL); 06389 unalloc_sub(p, SUB_CALLWAIT); 06390 p->owner = p->subs[SUB_REAL].owner; 06391 if (p->owner->_state != AST_STATE_UP) 06392 p->subs[SUB_REAL].needanswer = 1; 06393 if (ast_bridged_channel(p->subs[SUB_REAL].owner)) 06394 ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD); 06395 } else if (p->subs[SUB_THREEWAY].dfd > -1) { 06396 swap_subs(p, SUB_THREEWAY, SUB_REAL); 06397 unalloc_sub(p, SUB_THREEWAY); 06398 if (p->subs[SUB_REAL].inthreeway) { 06399 /* This was part of a three way call. Immediately make way for 06400 another call */ 06401 ast_debug(1, "Call was complete, setting owner to former third call\n"); 06402 p->owner = p->subs[SUB_REAL].owner; 06403 } else { 06404 /* This call hasn't been completed yet... Set owner to NULL */ 06405 ast_debug(1, "Call was incomplete, setting owner to NULL\n"); 06406 p->owner = NULL; 06407 } 06408 p->subs[SUB_REAL].inthreeway = 0; 06409 } 06410 } else if (idx == SUB_CALLWAIT) { 06411 /* Ditch the holding callwait call, and immediately make it availabe */ 06412 if (p->subs[SUB_CALLWAIT].inthreeway) { 06413 /* This is actually part of a three way, placed on hold. Place the third part 06414 on music on hold now */ 06415 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) { 06416 ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 06417 S_OR(p->mohsuggest, NULL), 06418 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 06419 } 06420 p->subs[SUB_THREEWAY].inthreeway = 0; 06421 /* Make it the call wait now */ 06422 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY); 06423 unalloc_sub(p, SUB_THREEWAY); 06424 } else 06425 unalloc_sub(p, SUB_CALLWAIT); 06426 } else if (idx == SUB_THREEWAY) { 06427 if (p->subs[SUB_CALLWAIT].inthreeway) { 06428 /* The other party of the three way call is currently in a call-wait state. 06429 Start music on hold for them, and take the main guy out of the third call */ 06430 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) { 06431 ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 06432 S_OR(p->mohsuggest, NULL), 06433 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 06434 } 06435 p->subs[SUB_CALLWAIT].inthreeway = 0; 06436 } 06437 p->subs[SUB_REAL].inthreeway = 0; 06438 /* If this was part of a three way call index, let us make 06439 another three way call */ 06440 unalloc_sub(p, SUB_THREEWAY); 06441 } else { 06442 /* This wasn't any sort of call, but how are we an index? */ 06443 ast_log(LOG_WARNING, "Index found but not any type of call?\n"); 06444 } 06445 } 06446 06447 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 06448 p->owner = NULL; 06449 p->ringt = 0; 06450 p->distinctivering = 0; 06451 p->confirmanswer = 0; 06452 p->outgoing = 0; 06453 p->digital = 0; 06454 p->faxhandled = 0; 06455 p->pulsedial = 0; 06456 if (p->dsp) { 06457 ast_dsp_free(p->dsp); 06458 p->dsp = NULL; 06459 } 06460 06461 revert_fax_buffers(p, ast); 06462 06463 p->law = p->law_default; 06464 law = p->law_default; 06465 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 06466 if (res < 0) 06467 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno)); 06468 /* Perform low level hangup if no owner left */ 06469 #ifdef HAVE_OPENR2 06470 if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) { 06471 ast_debug(1, "disconnecting MFC/R2 call on chan %d\n", p->channel); 06472 /* If it's an incoming call, check the mfcr2_forced_release setting */ 06473 if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) { 06474 dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE); 06475 } else { 06476 const char *r2causestr = pbx_builtin_getvar_helper(ast, "MFCR2_CAUSE"); 06477 int r2cause_user = r2causestr ? atoi(r2causestr) : 0; 06478 openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user) 06479 : dahdi_ast_cause_to_r2_cause(ast->hangupcause); 06480 dahdi_r2_disconnect_call(p, r2cause); 06481 } 06482 } else if (p->mfcr2call) { 06483 ast_debug(1, "Clearing call request on channel %d\n", p->channel); 06484 /* since ast_request() was called but not ast_call() we have not yet dialed 06485 and the openr2 stack will not call on_call_end callback, we need to unset 06486 the mfcr2call flag and bump the monitor count so the monitor thread can take 06487 care of this channel events from now on */ 06488 p->mfcr2call = 0; 06489 } 06490 #endif 06491 switch (p->sig) { 06492 case SIG_SS7: 06493 case SIG_MFCR2: 06494 case SIG_PRI_LIB_HANDLE_CASES: 06495 case 0: 06496 break; 06497 default: 06498 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 06499 break; 06500 } 06501 if (res < 0) { 06502 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast_channel_name(ast)); 06503 } 06504 switch (p->sig) { 06505 case SIG_FXOGS: 06506 case SIG_FXOLS: 06507 case SIG_FXOKS: 06508 memset(&par, 0, sizeof(par)); 06509 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par); 06510 if (!res) { 06511 struct analog_pvt *analog_p = p->sig_pvt; 06512 #if 0 06513 ast_debug(1, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook); 06514 #endif 06515 /* If they're off hook, try playing congestion */ 06516 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0)))) 06517 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 06518 else 06519 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06520 analog_p->fxsoffhookstate = par.rxisoffhook; 06521 } 06522 break; 06523 case SIG_FXSGS: 06524 case SIG_FXSLS: 06525 case SIG_FXSKS: 06526 /* Make sure we're not made available for at least two seconds assuming 06527 we were actually used for an inbound or outbound call. */ 06528 if (ast->_state != AST_STATE_RESERVED) { 06529 time(&p->guardtime); 06530 p->guardtime += 2; 06531 } 06532 break; 06533 default: 06534 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1); 06535 break; 06536 } 06537 if (p->sig) 06538 dahdi_disable_ec(p); 06539 x = 0; 06540 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0); 06541 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0); 06542 p->didtdd = 0; 06543 p->callwaitcas = 0; 06544 p->callwaiting = p->permcallwaiting; 06545 p->hidecallerid = p->permhidecallerid; 06546 p->waitingfordt.tv_sec = 0; 06547 p->dialing = 0; 06548 p->rdnis[0] = '\0'; 06549 update_conf(p); 06550 reset_conf(p); 06551 /* Restore data mode */ 06552 switch (p->sig) { 06553 case SIG_PRI_LIB_HANDLE_CASES: 06554 case SIG_SS7: 06555 x = 0; 06556 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0); 06557 break; 06558 default: 06559 break; 06560 } 06561 if (num_restart_pending == 0) 06562 restart_monitor(); 06563 } 06564 06565 p->callwaitingrepeat = 0; 06566 p->cidcwexpire = 0; 06567 p->cid_suppress_expire = 0; 06568 p->oprmode = 0; 06569 hangup_out: 06570 ast->tech_pvt = NULL; 06571 ast_free(p->cidspill); 06572 p->cidspill = NULL; 06573 06574 ast_mutex_unlock(&p->lock); 06575 ast_verb(3, "Hungup '%s'\n", ast_channel_name(ast)); 06576 06577 ast_mutex_lock(&iflock); 06578 if (p->restartpending) { 06579 num_restart_pending--; 06580 } 06581 06582 if (p->destroy) { 06583 destroy_channel(p, 0); 06584 } 06585 ast_mutex_unlock(&iflock); 06586 06587 ast_module_unref(ast_module_info->self); 06588 return 0; 06589 }
| static void dahdi_iflist_extract | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5570 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().
05571 { 05572 /* Extract from the forward chain. */ 05573 if (pvt->prev) { 05574 pvt->prev->next = pvt->next; 05575 } else if (iflist == pvt) { 05576 /* Node is at the head of the list. */ 05577 iflist = pvt->next; 05578 } 05579 05580 /* Extract from the reverse chain. */ 05581 if (pvt->next) { 05582 pvt->next->prev = pvt->prev; 05583 } else if (ifend == pvt) { 05584 /* Node is at the end of the list. */ 05585 ifend = pvt->prev; 05586 } 05587 05588 /* Node is no longer in the list. */ 05589 pvt->which_iflist = DAHDI_IFLIST_NONE; 05590 pvt->prev = NULL; 05591 pvt->next = NULL; 05592 }
| static void dahdi_iflist_insert | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5520 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().
05521 { 05522 struct dahdi_pvt *cur; 05523 05524 pvt->which_iflist = DAHDI_IFLIST_MAIN; 05525 05526 /* Find place in middle of list for the new interface. */ 05527 for (cur = iflist; cur; cur = cur->next) { 05528 if (pvt->channel < cur->channel) { 05529 /* New interface goes before the current interface. */ 05530 pvt->prev = cur->prev; 05531 pvt->next = cur; 05532 if (cur->prev) { 05533 /* Insert into the middle of the list. */ 05534 cur->prev->next = pvt; 05535 } else { 05536 /* Insert at head of list. */ 05537 iflist = pvt; 05538 } 05539 cur->prev = pvt; 05540 return; 05541 } 05542 } 05543 05544 /* New interface goes onto the end of the list */ 05545 pvt->prev = ifend; 05546 pvt->next = NULL; 05547 if (ifend) { 05548 ifend->next = pvt; 05549 } 05550 ifend = pvt; 05551 if (!iflist) { 05552 /* List was empty */ 05553 iflist = pvt; 05554 } 05555 }
| static int dahdi_indicate | ( | struct ast_channel * | chan, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 9431 of file chan_dahdi.c.
References ast_channel::_state, AST_CAUSE_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_USER_BUSY, ast_channel_name(), 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().
09432 { 09433 struct dahdi_pvt *p = chan->tech_pvt; 09434 int res=-1; 09435 int idx; 09436 int func = DAHDI_FLASH; 09437 09438 ast_mutex_lock(&p->lock); 09439 ast_debug(1, "Requested indication %d on channel %s\n", condition, ast_channel_name(chan)); 09440 switch (p->sig) { 09441 #if defined(HAVE_PRI) 09442 case SIG_PRI_LIB_HANDLE_CASES: 09443 res = sig_pri_indicate(p->sig_pvt, chan, condition, data, datalen); 09444 ast_mutex_unlock(&p->lock); 09445 return res; 09446 #endif /* defined(HAVE_PRI) */ 09447 #if defined(HAVE_SS7) 09448 case SIG_SS7: 09449 res = sig_ss7_indicate(p->sig_pvt, chan, condition, data, datalen); 09450 ast_mutex_unlock(&p->lock); 09451 return res; 09452 #endif /* defined(HAVE_SS7) */ 09453 default: 09454 break; 09455 } 09456 #ifdef HAVE_OPENR2 09457 if (p->mfcr2 && !p->mfcr2_call_accepted) { 09458 ast_mutex_unlock(&p->lock); 09459 /* if this is an R2 call and the call is not yet accepted, we don't want the 09460 tone indications to mess up with the MF tones */ 09461 return 0; 09462 } 09463 #endif 09464 idx = dahdi_get_index(chan, p, 0); 09465 if (idx == SUB_REAL) { 09466 switch (condition) { 09467 case AST_CONTROL_BUSY: 09468 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_BUSY); 09469 break; 09470 case AST_CONTROL_RINGING: 09471 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_RINGTONE); 09472 09473 if (chan->_state != AST_STATE_UP) { 09474 if ((chan->_state != AST_STATE_RING) || 09475 ((p->sig != SIG_FXSKS) && 09476 (p->sig != SIG_FXSLS) && 09477 (p->sig != SIG_FXSGS))) 09478 ast_setstate(chan, AST_STATE_RINGING); 09479 } 09480 break; 09481 case AST_CONTROL_INCOMPLETE: 09482 ast_debug(1, "Received AST_CONTROL_INCOMPLETE on %s\n", ast_channel_name(chan)); 09483 /* act as a progress or proceeding, allowing the caller to enter additional numbers */ 09484 res = 0; 09485 break; 09486 case AST_CONTROL_PROCEEDING: 09487 ast_debug(1, "Received AST_CONTROL_PROCEEDING on %s\n", ast_channel_name(chan)); 09488 /* don't continue in ast_indicate */ 09489 res = 0; 09490 break; 09491 case AST_CONTROL_PROGRESS: 09492 ast_debug(1, "Received AST_CONTROL_PROGRESS on %s\n", ast_channel_name(chan)); 09493 /* don't continue in ast_indicate */ 09494 res = 0; 09495 break; 09496 case AST_CONTROL_CONGESTION: 09497 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */ 09498 switch (chan->hangupcause) { 09499 case AST_CAUSE_USER_BUSY: 09500 case AST_CAUSE_NORMAL_CLEARING: 09501 case 0:/* Cause has not been set. */ 09502 /* Supply a more appropriate cause. */ 09503 chan->hangupcause = AST_CAUSE_CONGESTION; 09504 break; 09505 default: 09506 break; 09507 } 09508 break; 09509 case AST_CONTROL_HOLD: 09510 ast_moh_start(chan, data, p->mohinterpret); 09511 break; 09512 case AST_CONTROL_UNHOLD: 09513 ast_moh_stop(chan); 09514 break; 09515 case AST_CONTROL_RADIO_KEY: 09516 if (p->radio) 09517 res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK); 09518 res = 0; 09519 break; 09520 case AST_CONTROL_RADIO_UNKEY: 09521 if (p->radio) 09522 res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_RINGOFF); 09523 res = 0; 09524 break; 09525 case AST_CONTROL_FLASH: 09526 /* flash hookswitch */ 09527 if (ISTRUNK(p) && (p->sig != SIG_PRI)) { 09528 /* Clear out the dial buffer */ 09529 p->dop.dialstr[0] = '\0'; 09530 if ((ioctl(p->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) { 09531 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 09532 ast_channel_name(chan), strerror(errno)); 09533 } else 09534 res = 0; 09535 } else 09536 res = 0; 09537 break; 09538 case AST_CONTROL_SRCUPDATE: 09539 res = 0; 09540 break; 09541 case -1: 09542 res = tone_zone_play_tone(p->subs[idx].dfd, -1); 09543 break; 09544 } 09545 } else { 09546 res = 0; 09547 } 09548 ast_mutex_unlock(&p->lock); 09549 return res; 09550 }
Definition at line 7215 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().
07215 { 07216 int x; 07217 if (!slave || !master) { 07218 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n"); 07219 return; 07220 } 07221 for (x = 0; x < MAX_SLAVES; x++) { 07222 if (!master->slaves[x]) { 07223 master->slaves[x] = slave; 07224 break; 07225 } 07226 } 07227 if (x >= MAX_SLAVES) { 07228 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel); 07229 master->slaves[MAX_SLAVES - 1] = slave; 07230 } 07231 if (slave->master) 07232 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel); 07233 slave->master = master; 07234 07235 ast_debug(1, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x); 07236 }
| static void dahdi_lock_sub_owner | ( | struct dahdi_pvt * | pvt, | |
| int | sub_idx | |||
| ) | [static] |
Definition at line 3772 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().
03773 { 03774 for (;;) { 03775 if (!pvt->subs[sub_idx].owner) { 03776 /* No subchannel owner pointer */ 03777 break; 03778 } 03779 if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) { 03780 /* Got subchannel owner lock */ 03781 break; 03782 } 03783 /* We must unlock the private to avoid the possibility of a deadlock */ 03784 DEADLOCK_AVOIDANCE(&pvt->lock); 03785 } 03786 }
| 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 9600 of file chan_dahdi.c.
References 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_NAME, ast_channel_set_fd(), ast_copy_string(), ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), 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_FORMAT_ALAW, ast_format_cap_add(), ast_format_clear(), ast_format_copy(), ast_format_set(), 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_strlen_zero(), dahdi_pvt::busy_cadence, 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_party_redirecting::from, global_jbconf, dahdi_pvt::hardwaredtmf, ast_party_caller::id, 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, 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(), my_new_analog_ast_channel(), and register_translator().
09601 { 09602 struct ast_channel *tmp; 09603 struct ast_format deflaw; 09604 int x; 09605 int features; 09606 struct ast_str *chan_name; 09607 struct ast_variable *v; 09608 char *dashptr; 09609 char device_name[AST_CHANNEL_NAME]; 09610 09611 if (i->subs[idx].owner) { 09612 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[idx]); 09613 return NULL; 09614 } 09615 09616 ast_format_clear(&deflaw); 09617 #if defined(HAVE_PRI) 09618 /* 09619 * The dnid has been stuffed with the called-number[:subaddress] 09620 * by dahdi_request() for outgoing calls. 09621 */ 09622 chan_name = create_channel_name(i, i->outgoing, i->dnid); 09623 #else 09624 chan_name = create_channel_name(i); 09625 #endif /* defined(HAVE_PRI) */ 09626 if (!chan_name) { 09627 return NULL; 09628 } 09629 09630 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)); 09631 ast_free(chan_name); 09632 if (!tmp) 09633 return NULL; 09634 tmp->tech = &dahdi_tech; 09635 #if defined(HAVE_PRI) 09636 if (i->pri) { 09637 ast_cc_copy_config_params(i->cc_params, i->pri->cc_params); 09638 } 09639 #endif /* defined(HAVE_PRI) */ 09640 ast_channel_cc_params_init(tmp, i->cc_params); 09641 if (law) { 09642 i->law = law; 09643 if (law == DAHDI_LAW_ALAW) { 09644 ast_format_set(&deflaw, AST_FORMAT_ALAW, 0); 09645 } else { 09646 ast_format_set(&deflaw, AST_FORMAT_ULAW, 0); 09647 } 09648 } else { 09649 switch (i->sig) { 09650 case SIG_PRI_LIB_HANDLE_CASES: 09651 /* Make sure companding law is known. */ 09652 i->law = (i->law_default == DAHDI_LAW_ALAW) 09653 ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW; 09654 break; 09655 default: 09656 i->law = i->law_default; 09657 break; 09658 } 09659 if (i->law_default == DAHDI_LAW_ALAW) { 09660 ast_format_set(&deflaw, AST_FORMAT_ALAW, 0); 09661 } else { 09662 ast_format_set(&deflaw, AST_FORMAT_ULAW, 0); 09663 } 09664 } 09665 ast_channel_set_fd(tmp, 0, i->subs[idx].dfd); 09666 ast_format_cap_add(tmp->nativeformats, &deflaw); 09667 /* Start out assuming ulaw since it's smaller :) */ 09668 ast_format_copy(&tmp->rawreadformat, &deflaw); 09669 ast_format_copy(&tmp->readformat, &deflaw); 09670 ast_format_copy(&tmp->rawwriteformat, &deflaw); 09671 ast_format_copy(&tmp->writeformat, &deflaw); 09672 i->subs[idx].linear = 0; 09673 dahdi_setlinear(i->subs[idx].dfd, i->subs[idx].linear); 09674 features = 0; 09675 if (idx == SUB_REAL) { 09676 if (i->busydetect && CANBUSYDETECT(i)) 09677 features |= DSP_FEATURE_BUSY_DETECT; 09678 if ((i->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(i)) 09679 features |= DSP_FEATURE_CALL_PROGRESS; 09680 if ((i->waitfordialtone) && CANPROGRESSDETECT(i)) 09681 features |= DSP_FEATURE_WAITDIALTONE; 09682 if ((!i->outgoing && (i->callprogress & CALLPROGRESS_FAX_INCOMING)) || 09683 (i->outgoing && (i->callprogress & CALLPROGRESS_FAX_OUTGOING))) { 09684 features |= DSP_FEATURE_FAX_DETECT; 09685 } 09686 x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE; 09687 if (ioctl(i->subs[idx].dfd, DAHDI_TONEDETECT, &x)) { 09688 i->hardwaredtmf = 0; 09689 features |= DSP_FEATURE_DIGIT_DETECT; 09690 } else if (NEED_MFDETECT(i)) { 09691 i->hardwaredtmf = 1; 09692 features |= DSP_FEATURE_DIGIT_DETECT; 09693 } 09694 } 09695 if (features) { 09696 if (i->dsp) { 09697 ast_debug(1, "Already have a dsp on %s?\n", ast_channel_name(tmp)); 09698 } else { 09699 if (i->channel != CHAN_PSEUDO) 09700 i->dsp = ast_dsp_new(); 09701 else 09702 i->dsp = NULL; 09703 if (i->dsp) { 09704 i->dsp_features = features; 09705 #if defined(HAVE_PRI) || defined(HAVE_SS7) 09706 /* We cannot do progress detection until receive PROGRESS message */ 09707 if (i->outgoing && (dahdi_sig_pri_lib_handles(i->sig) || (i->sig == SIG_SS7))) { 09708 /* Remember requested DSP features, don't treat 09709 talking as ANSWER */ 09710 i->dsp_features = features & ~DSP_PROGRESS_TALK; 09711 features = 0; 09712 } 09713 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 09714 ast_dsp_set_features(i->dsp, features); 09715 ast_dsp_set_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax); 09716 if (!ast_strlen_zero(progzone)) 09717 ast_dsp_set_call_progress_zone(i->dsp, progzone); 09718 if (i->busydetect && CANBUSYDETECT(i)) { 09719 ast_dsp_set_busy_count(i->dsp, i->busycount); 09720 ast_dsp_set_busy_pattern(i->dsp, &i->busy_cadence); 09721 } 09722 } 09723 } 09724 } 09725 09726 if (state == AST_STATE_RING) 09727 tmp->rings = 1; 09728 tmp->tech_pvt = i; 09729 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { 09730 /* Only FXO signalled stuff can be picked up */ 09731 tmp->callgroup = i->callgroup; 09732 tmp->pickupgroup = i->pickupgroup; 09733 } 09734 if (!ast_strlen_zero(i->parkinglot)) 09735 ast_channel_parkinglot_set(tmp, i->parkinglot); 09736 if (!ast_strlen_zero(i->language)) 09737 ast_channel_language_set(tmp, i->language); 09738 if (!i->owner) 09739 i->owner = tmp; 09740 if (!ast_strlen_zero(i->accountcode)) 09741 ast_channel_accountcode_set(tmp, i->accountcode); 09742 if (i->amaflags) 09743 tmp->amaflags = i->amaflags; 09744 i->subs[idx].owner = tmp; 09745 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 09746 if (!analog_lib_handles(i->sig, i->radio, i->oprmode)) { 09747 ast_channel_call_forward_set(tmp, i->call_forward); 09748 } 09749 /* If we've been told "no ADSI" then enforce it */ 09750 if (!i->adsi) 09751 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 09752 if (!ast_strlen_zero(i->exten)) 09753 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 09754 if (!ast_strlen_zero(i->rdnis)) { 09755 tmp->redirecting.from.number.valid = 1; 09756 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 09757 } 09758 if (!ast_strlen_zero(i->dnid)) { 09759 tmp->dialed.number.str = ast_strdup(i->dnid); 09760 } 09761 09762 /* Don't use ast_set_callerid() here because it will 09763 * generate a needless NewCallerID event */ 09764 #if defined(HAVE_PRI) || defined(HAVE_SS7) 09765 if (!ast_strlen_zero(i->cid_ani)) { 09766 tmp->caller.ani.number.valid = 1; 09767 tmp->caller.ani.number.str = ast_strdup(i->cid_ani); 09768 } else if (!ast_strlen_zero(i->cid_num)) { 09769 tmp->caller.ani.number.valid = 1; 09770 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 09771 } 09772 #else 09773 if (!ast_strlen_zero(i->cid_num)) { 09774 tmp->caller.ani.number.valid = 1; 09775 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 09776 } 09777 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 09778 tmp->caller.id.name.presentation = i->callingpres; 09779 tmp->caller.id.number.presentation = i->callingpres; 09780 tmp->caller.id.number.plan = i->cid_ton; 09781 tmp->caller.ani2 = i->cid_ani2; 09782 tmp->caller.id.tag = ast_strdup(i->cid_tag); 09783 /* clear the fake event in case we posted one before we had ast_channel */ 09784 i->fake_event = 0; 09785 /* Assure there is no confmute on this channel */ 09786 dahdi_confmute(i, 0); 09787 i->muting = 0; 09788 /* Configure the new channel jb */ 09789 ast_jb_configure(tmp, &global_jbconf); 09790 09791 /* Set initial device state */ 09792 ast_copy_string(device_name, ast_channel_name(tmp), sizeof(device_name)); 09793 dashptr = strrchr(device_name, '-'); 09794 if (dashptr) { 09795 *dashptr = '\0'; 09796 } 09797 ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name); 09798 09799 for (v = i->vars ; v ; v = v->next) 09800 pbx_builtin_setvar_helper(tmp, v->name, v->value); 09801 09802 ast_module_ref(ast_module_info->self); 09803 09804 dahdi_ami_channel_event(i, tmp); 09805 if (startpbx) { 09806 #ifdef HAVE_OPENR2 09807 if (i->mfcr2call) { 09808 pbx_builtin_setvar_helper(tmp, "MFCR2_CATEGORY", openr2_proto_get_category_string(i->mfcr2_recvd_category)); 09809 } 09810 #endif 09811 if (ast_pbx_start(tmp)) { 09812 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp)); 09813 ast_hangup(tmp); 09814 return NULL; 09815 } 09816 } 09817 return tmp; 09818 }
| static int dahdi_open | ( | char * | fn | ) | [static] |
Definition at line 4303 of file chan_dahdi.c.
References ast_log(), errno, LOG_WARNING, and READ_SIZE.
Referenced by alloc_sub(), duplicate_pseudo(), and mkintf().
04304 { 04305 int fd; 04306 int isnum; 04307 int chan = 0; 04308 int bs; 04309 int x; 04310 isnum = 1; 04311 for (x = 0; x < strlen(fn); x++) { 04312 if (!isdigit(fn[x])) { 04313 isnum = 0; 04314 break; 04315 } 04316 } 04317 if (isnum) { 04318 chan = atoi(fn); 04319 if (chan < 1) { 04320 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn); 04321 return -1; 04322 } 04323 fn = "/dev/dahdi/channel"; 04324 } 04325 fd = open(fn, O_RDWR | O_NONBLOCK); 04326 if (fd < 0) { 04327 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno)); 04328 return -1; 04329 } 04330 if (chan) { 04331 if (ioctl(fd, DAHDI_SPECIFY, &chan)) { 04332 x = errno; 04333 close(fd); 04334 errno = x; 04335 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno)); 04336 return -1; 04337 } 04338 } 04339 bs = READ_SIZE; 04340 if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) { 04341 ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno)); 04342 x = errno; 04343 close(fd); 04344 errno = x; 04345 return -1; 04346 } 04347 return fd; 04348 }
| static int dahdi_queryoption | ( | struct ast_channel * | chan, | |
| int | option, | |||
| void * | data, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6686 of file chan_dahdi.c.
References ast_channel_name(), 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.
06687 { 06688 char *cp; 06689 struct dahdi_pvt *p = chan->tech_pvt; 06690 06691 /* all supported options require data */ 06692 if (!p || !data || (*datalen < 1)) { 06693 errno = EINVAL; 06694 return -1; 06695 } 06696 06697 switch (option) { 06698 case AST_OPTION_DIGIT_DETECT: 06699 cp = (char *) data; 06700 *cp = p->ignoredtmf ? 0 : 1; 06701 ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", ast_channel_name(chan)); 06702 break; 06703 case AST_OPTION_FAX_DETECT: 06704 cp = (char *) data; 06705 *cp = (p->dsp_features & DSP_FEATURE_FAX_DETECT) ? 0 : 1; 06706 ast_debug(1, "Reporting fax tone detection %sabled on %s\n", *cp ? "en" : "dis", ast_channel_name(chan)); 06707 break; 06708 case AST_OPTION_CC_AGENT_TYPE: 06709 #if defined(HAVE_PRI) 06710 #if defined(HAVE_PRI_CCSS) 06711 if (dahdi_sig_pri_lib_handles(p->sig)) { 06712 ast_copy_string((char *) data, dahdi_pri_cc_type, *datalen); 06713 break; 06714 } 06715 #endif /* defined(HAVE_PRI_CCSS) */ 06716 #endif /* defined(HAVE_PRI) */ 06717 return -1; 06718 default: 06719 return -1; 06720 } 06721 06722 errno = 0; 06723 06724 return 0; 06725 }
Definition at line 3797 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().
03798 { 03799 for (;;) { 03800 if (p->owner) { 03801 if (ast_channel_trylock(p->owner)) { 03802 DEADLOCK_AVOIDANCE(&p->lock); 03803 } else { 03804 ast_queue_frame(p->owner, f); 03805 ast_channel_unlock(p->owner); 03806 break; 03807 } 03808 } else 03809 break; 03810 } 03811 }
| static struct ast_frame * dahdi_read | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 8920 of file chan_dahdi.c.
References __dahdi_exception(), ast_channel::_state, analog_exception(), analog_handle_dtmf(), analog_lib_handles(), ast_channel_name(), 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_copy(), AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_getformatname(), ast_log(), ast_mutex_trylock, ast_mutex_unlock, ast_null_frame, ast_queue_frame(), ast_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, 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_subclass::format, ast_frame::frametype, ast_format::id, dahdi_pvt::ignoredtmf, dahdi_pvt::inalarm, ast_frame_subclass::integer, dahdi_subchannel::inthreeway, dahdi_subchannel::linear, dahdi_pvt::lock, 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.
08921 { 08922 struct dahdi_pvt *p; 08923 int res; 08924 int idx; 08925 void *readbuf; 08926 struct ast_frame *f; 08927 08928 /* 08929 * For analog channels, we must do deadlock avoidance because 08930 * analog ports can have more than one Asterisk channel using 08931 * the same private structure. 08932 */ 08933 p = ast->tech_pvt; 08934 while (ast_mutex_trylock(&p->lock)) { 08935 CHANNEL_DEADLOCK_AVOIDANCE(ast); 08936 08937 /* 08938 * For PRI channels, we must refresh the private pointer because 08939 * the call could move to another B channel while the Asterisk 08940 * channel is unlocked. 08941 */ 08942 p = ast->tech_pvt; 08943 } 08944 08945 idx = dahdi_get_index(ast, p, 0); 08946 08947 /* Hang up if we don't really exist */ 08948 if (idx < 0) { 08949 ast_log(LOG_WARNING, "We don't exist?\n"); 08950 ast_mutex_unlock(&p->lock); 08951 return NULL; 08952 } 08953 08954 if ((p->radio || (p->oprmode < 0)) && p->inalarm) { 08955 ast_mutex_unlock(&p->lock); 08956 return NULL; 08957 } 08958 08959 p->subs[idx].f.frametype = AST_FRAME_NULL; 08960 p->subs[idx].f.datalen = 0; 08961 p->subs[idx].f.samples = 0; 08962 p->subs[idx].f.mallocd = 0; 08963 p->subs[idx].f.offset = 0; 08964 p->subs[idx].f.subclass.integer = 0; 08965 p->subs[idx].f.delivery = ast_tv(0,0); 08966 p->subs[idx].f.src = "dahdi_read"; 08967 p->subs[idx].f.data.ptr = NULL; 08968 08969 /* make sure it sends initial key state as first frame */ 08970 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio)) 08971 { 08972 struct dahdi_params ps; 08973 08974 memset(&ps, 0, sizeof(ps)); 08975 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) { 08976 ast_mutex_unlock(&p->lock); 08977 return NULL; 08978 } 08979 p->firstradio = 1; 08980 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 08981 if (ps.rxisoffhook) 08982 { 08983 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_KEY; 08984 } 08985 else 08986 { 08987 p->subs[idx].f.subclass.integer = AST_CONTROL_RADIO_UNKEY; 08988 } 08989 ast_mutex_unlock(&p->lock); 08990 return &p->subs[idx].f; 08991 } 08992 if (p->ringt > 0) { 08993 if (!(--p->ringt)) { 08994 ast_mutex_unlock(&p->lock); 08995 return NULL; 08996 } 08997 } 08998 08999 #ifdef HAVE_OPENR2 09000 if (p->mfcr2) { 09001 openr2_chan_process_event(p->r2chan); 09002 if (OR2_DIR_FORWARD == openr2_chan_get_direction(p->r2chan)) { 09003 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_PROGRESS } }; 09004 /* if the call is already accepted and we already delivered AST_CONTROL_RINGING 09005 * now enqueue a progress frame to bridge the media up */ 09006 if (p->mfcr2_call_accepted && 09007 !p->mfcr2_progress_sent && 09008 ast->_state == AST_STATE_RINGING) { 09009 ast_debug(1, "Enqueuing progress frame after R2 accept in chan %d\n", p->channel); 09010 ast_queue_frame(p->owner, &fr); 09011 p->mfcr2_progress_sent = 1; 09012 } 09013 } 09014 } 09015 #endif 09016 09017 if (p->subs[idx].needringing) { 09018 /* Send ringing frame if requested */ 09019 p->subs[idx].needringing = 0; 09020 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09021 p->subs[idx].f.subclass.integer = AST_CONTROL_RINGING; 09022 ast_setstate(ast, AST_STATE_RINGING); 09023 ast_mutex_unlock(&p->lock); 09024 return &p->subs[idx].f; 09025 } 09026 09027 if (p->subs[idx].needbusy) { 09028 /* Send busy frame if requested */ 09029 p->subs[idx].needbusy = 0; 09030 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09031 p->subs[idx].f.subclass.integer = AST_CONTROL_BUSY; 09032 ast_mutex_unlock(&p->lock); 09033 return &p->subs[idx].f; 09034 } 09035 09036 if (p->subs[idx].needcongestion) { 09037 /* Send congestion frame if requested */ 09038 p->subs[idx].needcongestion = 0; 09039 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09040 p->subs[idx].f.subclass.integer = AST_CONTROL_CONGESTION; 09041 ast_mutex_unlock(&p->lock); 09042 return &p->subs[idx].f; 09043 } 09044 09045 if (p->subs[idx].needanswer) { 09046 /* Send answer frame if requested */ 09047 p->subs[idx].needanswer = 0; 09048 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09049 p->subs[idx].f.subclass.integer = AST_CONTROL_ANSWER; 09050 ast_mutex_unlock(&p->lock); 09051 return &p->subs[idx].f; 09052 } 09053 #ifdef HAVE_OPENR2 09054 if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) { 09055 /* openr2 took care of reading and handling any event 09056 (needanswer, needbusy etc), if we continue we will read() 09057 twice, lets just return a null frame. This should only 09058 happen when openr2 is dialing out */ 09059 ast_mutex_unlock(&p->lock); 09060 return &ast_null_frame; 09061 } 09062 #endif 09063 09064 if (p->subs[idx].needflash) { 09065 /* Send answer frame if requested */ 09066 p->subs[idx].needflash = 0; 09067 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09068 p->subs[idx].f.subclass.integer = AST_CONTROL_FLASH; 09069 ast_mutex_unlock(&p->lock); 09070 return &p->subs[idx].f; 09071 } 09072 09073 if (p->subs[idx].needhold) { 09074 /* Send answer frame if requested */ 09075 p->subs[idx].needhold = 0; 09076 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09077 p->subs[idx].f.subclass.integer = AST_CONTROL_HOLD; 09078 ast_mutex_unlock(&p->lock); 09079 ast_debug(1, "Sending hold on '%s'\n", ast_channel_name(ast)); 09080 return &p->subs[idx].f; 09081 } 09082 09083 if (p->subs[idx].needunhold) { 09084 /* Send answer frame if requested */ 09085 p->subs[idx].needunhold = 0; 09086 p->subs[idx].f.frametype = AST_FRAME_CONTROL; 09087 p->subs[idx].f.subclass.integer = AST_CONTROL_UNHOLD; 09088 ast_mutex_unlock(&p->lock); 09089 ast_debug(1, "Sending unhold on '%s'\n", ast_channel_name(ast)); 09090 return &p->subs[idx].f; 09091 } 09092 09093 /* 09094 * If we have a fake_event, fake an exception to handle it only 09095 * if this channel owns the private. 09096 */ 09097 if (p->fake_event && p->owner == ast) { 09098 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09099 struct analog_pvt *analog_p = p->sig_pvt; 09100 09101 f = analog_exception(analog_p, ast); 09102 } else { 09103 f = __dahdi_exception(ast); 09104 } 09105 ast_mutex_unlock(&p->lock); 09106 return f; 09107 } 09108 09109 if (ast->rawreadformat.id == AST_FORMAT_SLINEAR) { 09110 if (!p->subs[idx].linear) { 09111 p->subs[idx].linear = 1; 09112 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09113 if (res) 09114 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, idx); 09115 } 09116 } else if ((ast->rawreadformat.id == AST_FORMAT_ULAW) || 09117 (ast->rawreadformat.id == AST_FORMAT_ALAW)) { 09118 if (p->subs[idx].linear) { 09119 p->subs[idx].linear = 0; 09120 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09121 if (res) 09122 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, idx); 09123 } 09124 } else { 09125 ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(&ast->rawreadformat)); 09126 ast_mutex_unlock(&p->lock); 09127 return NULL; 09128 } 09129 readbuf = ((unsigned char *)p->subs[idx].buffer) + AST_FRIENDLY_OFFSET; 09130 CHECK_BLOCKING(ast); 09131 res = read(p->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE); 09132 ast_clear_flag(ast, AST_FLAG_BLOCKING); 09133 /* Check for hangup */ 09134 if (res < 0) { 09135 f = NULL; 09136 if (res == -1) { 09137 if (errno == EAGAIN) { 09138 /* Return "NULL" frame if there is nobody there */ 09139 ast_mutex_unlock(&p->lock); 09140 return &p->subs[idx].f; 09141 } else if (errno == ELAST) { 09142 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09143 struct analog_pvt *analog_p = p->sig_pvt; 09144 f = analog_exception(analog_p, ast); 09145 } else { 09146 f = __dahdi_exception(ast); 09147 } 09148 } else 09149 ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno)); 09150 } 09151 ast_mutex_unlock(&p->lock); 09152 return f; 09153 } 09154 if (res != (p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE)) { 09155 ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE); 09156 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09157 struct analog_pvt *analog_p = p->sig_pvt; 09158 f = analog_exception(analog_p, ast); 09159 } else { 09160 f = __dahdi_exception(ast); 09161 } 09162 ast_mutex_unlock(&p->lock); 09163 return f; 09164 } 09165 if (p->tdd) { /* if in TDD mode, see if we receive that */ 09166 int c; 09167 09168 c = tdd_feed(p->tdd,readbuf,READ_SIZE); 09169 if (c < 0) { 09170 ast_debug(1,"tdd_feed failed\n"); 09171 ast_mutex_unlock(&p->lock); 09172 return NULL; 09173 } 09174 if (c) { /* if a char to return */ 09175 p->subs[idx].f.subclass.integer = 0; 09176 p->subs[idx].f.frametype = AST_FRAME_TEXT; 09177 p->subs[idx].f.mallocd = 0; 09178 p->subs[idx].f.offset = AST_FRIENDLY_OFFSET; 09179 p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET; 09180 p->subs[idx].f.datalen = 1; 09181 *((char *) p->subs[idx].f.data.ptr) = c; 09182 ast_mutex_unlock(&p->lock); 09183 return &p->subs[idx].f; 09184 } 09185 } 09186 if (idx == SUB_REAL) { 09187 /* Ensure the CW timers decrement only on a single subchannel */ 09188 if (p->cidcwexpire) { 09189 if (!--p->cidcwexpire) { 09190 /* Expired CID/CW */ 09191 ast_verb(3, "CPE does not support Call Waiting Caller*ID.\n"); 09192 restore_conference(p); 09193 } 09194 } 09195 if (p->cid_suppress_expire) { 09196 --p->cid_suppress_expire; 09197 } 09198 if (p->callwaitingrepeat) { 09199 if (!--p->callwaitingrepeat) { 09200 /* Expired, Repeat callwaiting tone */ 09201 ++p->callwaitrings; 09202 dahdi_callwait(ast); 09203 } 09204 } 09205 } 09206 if (p->subs[idx].linear) { 09207 p->subs[idx].f.datalen = READ_SIZE * 2; 09208 } else 09209 p->subs[idx].f.datalen = READ_SIZE; 09210 09211 /* Handle CallerID Transmission */ 09212 if ((p->owner == ast) && p->cidspill) { 09213 send_callerid(p); 09214 } 09215 09216 p->subs[idx].f.frametype = AST_FRAME_VOICE; 09217 ast_format_copy(&p->subs[idx].f.subclass.format, &ast->rawreadformat); 09218 p->subs[idx].f.samples = READ_SIZE; 09219 p->subs[idx].f.mallocd = 0; 09220 p->subs[idx].f.offset = AST_FRIENDLY_OFFSET; 09221 p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[idx].buffer[0]); 09222 #if 0 09223 ast_debug(1, "Read %d of voice on %s\n", p->subs[idx].f.datalen, ast->name); 09224 #endif 09225 if (p->dialing || p->radio || /* Transmitting something */ 09226 (idx && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */ 09227 ((idx == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */ 09228 ) { 09229 /* Whoops, we're still dialing, or in a state where we shouldn't transmit.... 09230 don't send anything */ 09231 p->subs[idx].f.frametype = AST_FRAME_NULL; 09232 p->subs[idx].f.subclass.integer = 0; 09233 p->subs[idx].f.samples = 0; 09234 p->subs[idx].f.mallocd = 0; 09235 p->subs[idx].f.offset = 0; 09236 p->subs[idx].f.data.ptr = NULL; 09237 p->subs[idx].f.datalen= 0; 09238 } 09239 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress || p->waitingfordt.tv_sec) && !idx) { 09240 /* Perform busy detection etc on the dahdi line */ 09241 int mute; 09242 09243 f = ast_dsp_process(ast, p->dsp, &p->subs[idx].f); 09244 09245 /* Check if DSP code thinks we should be muting this frame and mute the conference if so */ 09246 mute = ast_dsp_was_muted(p->dsp); 09247 if (p->muting != mute) { 09248 p->muting = mute; 09249 dahdi_confmute(p, mute); 09250 } 09251 09252 if (f) { 09253 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_BUSY)) { 09254 if ((ast->_state == AST_STATE_UP) && !p->outgoing) { 09255 /* Treat this as a "hangup" instead of a "busy" on the assumption that 09256 a busy */ 09257 f = NULL; 09258 } 09259 } else if (f->frametype == AST_FRAME_DTMF_BEGIN 09260 || f->frametype == AST_FRAME_DTMF_END) { 09261 #ifdef HAVE_PRI 09262 if (dahdi_sig_pri_lib_handles(p->sig) 09263 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING 09264 && p->pri 09265 && ((!p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) 09266 || (p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)))) { 09267 /* Don't accept in-band DTMF when in overlap dial mode */ 09268 ast_debug(1, "Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n", 09269 f->frametype == AST_FRAME_DTMF_BEGIN ? "begin" : "end", 09270 f->subclass.integer, f->subclass.integer, ast_channel_name(ast)); 09271 09272 f->frametype = AST_FRAME_NULL; 09273 f->subclass.integer = 0; 09274 } 09275 #endif 09276 /* DSP clears us of being pulse */ 09277 p->pulsedial = 0; 09278 } else if (p->waitingfordt.tv_sec) { 09279 if (ast_tvdiff_ms(ast_tvnow(), p->waitingfordt) >= p->waitfordialtone ) { 09280 p->waitingfordt.tv_sec = 0; 09281 ast_log(LOG_WARNING, "Never saw dialtone on channel %d\n", p->channel); 09282 f=NULL; 09283 } else if (f->frametype == AST_FRAME_VOICE) { 09284 f->frametype = AST_FRAME_NULL; 09285 f->subclass.integer = 0; 09286 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) { 09287 p->waitingfordt.tv_sec = 0; 09288 p->dsp_features &= ~DSP_FEATURE_WAITDIALTONE; 09289 ast_dsp_set_features(p->dsp, p->dsp_features); 09290 ast_debug(1, "Got 10 samples of dialtone!\n"); 09291 if (!ast_strlen_zero(p->dop.dialstr)) { /* Dial deferred digits */ 09292 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop); 09293 if (res < 0) { 09294 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); 09295 p->dop.dialstr[0] = '\0'; 09296 ast_mutex_unlock(&p->lock); 09297 return NULL; 09298 } else { 09299 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr); 09300 p->dialing = 1; 09301 p->dop.dialstr[0] = '\0'; 09302 p->dop.op = DAHDI_DIAL_OP_REPLACE; 09303 ast_setstate(ast, AST_STATE_DIALING); 09304 } 09305 } 09306 } 09307 } 09308 } 09309 } 09310 } else 09311 f = &p->subs[idx].f; 09312 09313 if (f) { 09314 switch (f->frametype) { 09315 case AST_FRAME_DTMF_BEGIN: 09316 case AST_FRAME_DTMF_END: 09317 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 09318 analog_handle_dtmf(p->sig_pvt, ast, idx, &f); 09319 } else { 09320 dahdi_handle_dtmf(ast, idx, &f); 09321 } 09322 break; 09323 case AST_FRAME_VOICE: 09324 if (p->cidspill || p->cid_suppress_expire) { 09325 /* We are/were sending a caller id spill. Suppress any echo. */ 09326 p->subs[idx].f.frametype = AST_FRAME_NULL; 09327 p->subs[idx].f.subclass.integer = 0; 09328 p->subs[idx].f.samples = 0; 09329 p->subs[idx].f.mallocd = 0; 09330 p->subs[idx].f.offset = 0; 09331 p->subs[idx].f.data.ptr = NULL; 09332 p->subs[idx].f.datalen= 0; 09333 } 09334 break; 09335 default: 09336 break; 09337 } 09338 } 09339 09340 ast_mutex_unlock(&p->lock); 09341 return f; 09342 }
| static struct ast_channel * dahdi_request | ( | const char * | type, | |
| struct ast_format_cap * | cap, | |||
| const struct ast_channel * | requestor, | |||
| const char * | data, | |||
| int * | cause | |||
| ) | [static, read] |
Definition at line 13655 of file chan_dahdi.c.
References analog_lib_handles(), analog_request(), ast_atomic_fetchadd_int(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_channel_linkedid(), 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, iflock, is_group_or_channel_match(), dahdi_pvt::lock, 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.
13656 { 13657 int callwait = 0; 13658 struct dahdi_pvt *p; 13659 struct ast_channel *tmp = NULL; 13660 struct dahdi_pvt *exitpvt; 13661 int channelmatched = 0; 13662 int groupmatched = 0; 13663 #if defined(HAVE_PRI) || defined(HAVE_SS7) 13664 int transcapdigital = 0; 13665 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 13666 struct dahdi_starting_point start; 13667 13668 ast_mutex_lock(&iflock); 13669 p = determine_starting_point(data, &start); 13670 if (!p) { 13671 /* We couldn't determine a starting point, which likely means badly-formatted channel name. Abort! */ 13672 ast_mutex_unlock(&iflock); 13673 return NULL; 13674 } 13675 13676 /* Search for an unowned channel */ 13677 exitpvt = p; 13678 while (p && !tmp) { 13679 if (start.roundrobin) 13680 round_robin[start.rr_starting_point] = p; 13681 13682 if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched) 13683 && available(&p, channelmatched)) { 13684 ast_debug(1, "Using channel %d\n", p->channel); 13685 13686 callwait = (p->owner != NULL); 13687 #ifdef HAVE_OPENR2 13688 if (p->mfcr2) { 13689 ast_mutex_lock(&p->lock); 13690 if (p->mfcr2call) { 13691 ast_mutex_unlock(&p->lock); 13692 ast_debug(1, "Yay!, someone just beat us in the race for channel %d.\n", p->channel); 13693 goto next; 13694 } 13695 p->mfcr2call = 1; 13696 ast_mutex_unlock(&p->lock); 13697 } 13698 #endif 13699 if (p->channel == CHAN_PSEUDO) { 13700 p = duplicate_pseudo(p); 13701 if (!p) { 13702 break; 13703 } 13704 } 13705 13706 p->distinctivering = 0; 13707 /* Make special notes */ 13708 switch (start.opt) { 13709 case '\0': 13710 /* No option present. */ 13711 break; 13712 case 'c': 13713 /* Confirm answer */ 13714 p->confirmanswer = 1; 13715 break; 13716 case 'r': 13717 /* Distinctive ring */ 13718 p->distinctivering = start.cadance; 13719 break; 13720 case 'd': 13721 #if defined(HAVE_PRI) || defined(HAVE_SS7) 13722 /* If this is an ISDN call, make it digital */ 13723 transcapdigital = AST_TRANS_CAP_DIGITAL; 13724 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 13725 break; 13726 default: 13727 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", start.opt, data); 13728 break; 13729 } 13730 13731 p->outgoing = 1; 13732 if (analog_lib_handles(p->sig, p->radio, p->oprmode)) { 13733 tmp = analog_request(p->sig_pvt, &callwait, requestor); 13734 #ifdef HAVE_PRI 13735 } else if (dahdi_sig_pri_lib_handles(p->sig)) { 13736 /* 13737 * We already have the B channel reserved for this call. We 13738 * just need to make sure that dahdi_hangup() has completed 13739 * cleaning up before continuing. 13740 */ 13741 ast_mutex_lock(&p->lock); 13742 ast_mutex_unlock(&p->lock); 13743 13744 sig_pri_extract_called_num_subaddr(p->sig_pvt, data, p->dnid, 13745 sizeof(p->dnid)); 13746 tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW, requestor, transcapdigital); 13747 #endif 13748 #if defined(HAVE_SS7) 13749 } else if (p->sig == SIG_SS7) { 13750 tmp = sig_ss7_request(p->sig_pvt, SIG_SS7_DEFLAW, requestor, transcapdigital); 13751 #endif /* defined(HAVE_SS7) */ 13752 } else { 13753 tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, requestor ? ast_channel_linkedid(requestor) : ""); 13754 } 13755 if (!tmp) { 13756 p->outgoing = 0; 13757 #if defined(HAVE_PRI) 13758 switch (p->sig) { 13759 case SIG_PRI_LIB_HANDLE_CASES: 13760 #if defined(HAVE_PRI_CALL_WAITING) 13761 if (((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting) { 13762 ((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting = 0; 13763 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1); 13764 } 13765 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 13766 /* 13767 * This should be the last thing to clear when we are done with 13768 * the channel. 13769 */ 13770 ((struct sig_pri_chan *) p->sig_pvt)->allocated = 0; 13771 break; 13772 default: 13773 break; 13774 } 13775 #endif /* defined(HAVE_PRI) */ 13776 } else { 13777 snprintf(p->dialstring, sizeof(p->dialstring), "DAHDI/%s", data); 13778 } 13779 break; 13780 } 13781 #ifdef HAVE_OPENR2 13782 next: 13783 #endif 13784 if (start.backwards) { 13785 p = p->prev; 13786 if (!p) 13787 p = ifend; 13788 } else { 13789 p = p->next; 13790 if (!p) 13791 p = iflist; 13792 } 13793 /* stop when you roll to the one that we started from */ 13794 if (p == exitpvt) 13795 break; 13796 } 13797 ast_mutex_unlock(&iflock); 13798 restart_monitor(); 13799 if (cause && !tmp) { 13800 if (callwait || channelmatched) { 13801 *cause = AST_CAUSE_BUSY; 13802 } else if (groupmatched) { 13803 *cause = AST_CAUSE_CONGESTION; 13804 } else { 13805 /* 13806 * We did not match any channel requested. 13807 * Dialplan error requesting non-existant channel? 13808 */ 13809 } 13810 } 13811 13812 return tmp; 13813 }
| static int dahdi_restart | ( | void | ) | [static] |
Definition at line 15098 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, iflock, LOG_WARNING, monlock, dahdi_pvt::next, dahdi_pvt::owner, restart_lock, setup_dahdi(), sig_pri_init_pri(), sig_ss7_init_linkset(), SIG_SS7_NUM_DCHANS, ss_thread_lock, SUB_REAL, and dahdi_pvt::subs.
Referenced by action_dahdirestart(), and dahdi_restart_cmd().
15099 { 15100 #if defined(HAVE_PRI) || defined(HAVE_SS7) 15101 int i, j; 15102 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 15103 int cancel_code; 15104 struct dahdi_pvt *p; 15105 15106 ast_mutex_lock(&restart_lock); 15107 ast_verb(1, "Destroying channels and reloading DAHDI configuration.\n"); 15108 dahdi_softhangup_all(); 15109 ast_verb(4, "Initial softhangup of all DAHDI channels complete.\n"); 15110 #ifdef HAVE_OPENR2 15111 dahdi_r2_destroy_links(); 15112 #endif 15113 15114 #if defined(HAVE_PRI) 15115 for (i = 0; i < NUM_SPANS; i++) { 15116 if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) { 15117 cancel_code = pthread_cancel(pris[i].pri.master); 15118 pthread_kill(pris[i].pri.master, SIGURG); 15119 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); 15120 pthread_join(pris[i].pri.master, NULL); 15121 ast_debug(4, "Joined thread of span %d\n", i); 15122 } 15123 } 15124 #endif 15125 15126 #if defined(HAVE_SS7) 15127 for (i = 0; i < NUM_SPANS; i++) { 15128 if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) { 15129 cancel_code = pthread_cancel(linksets[i].ss7.master); 15130 pthread_kill(linksets[i].ss7.master, SIGURG); 15131 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); 15132 pthread_join(linksets[i].ss7.master, NULL); 15133 ast_debug(4, "Joined thread of span %d\n", i); 15134 } 15135 } 15136 #endif /* defined(HAVE_SS7) */ 15137 15138 ast_mutex_lock(&monlock); 15139 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 15140 cancel_code = pthread_cancel(monitor_thread); 15141 pthread_kill(monitor_thread, SIGURG); 15142 ast_debug(4, "Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (void *) monitor_thread, cancel_code); 15143 pthread_join(monitor_thread, NULL); 15144 ast_debug(4, "Joined monitor thread\n"); 15145 } 15146 monitor_thread = AST_PTHREADT_NULL; /* prepare to restart thread in setup_dahdi once channels are reconfigured */ 15147 15148 ast_mutex_lock(&ss_thread_lock); 15149 while (ss_thread_count > 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */ 15150 int x = DAHDI_FLASH; 15151 ast_debug(3, "Waiting on %d analog_ss_thread(s) to finish\n", ss_thread_count); 15152 15153 ast_mutex_lock(&iflock); 15154 for (p = iflist; p; p = p->next) { 15155 if (p->owner) { 15156 /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */ 15157 ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 15158 } 15159 } 15160 ast_mutex_unlock(&iflock); 15161 ast_cond_wait(&ss_thread_complete, &ss_thread_lock); 15162 } 15163 15164 /* ensure any created channels before monitor threads were stopped are hungup */ 15165 dahdi_softhangup_all(); 15166 ast_verb(4, "Final softhangup of all DAHDI channels complete.\n"); 15167 destroy_all_channels(); 15168 ast_debug(1, "Channels destroyed. Now re-reading config. %d active channels remaining.\n", ast_active_channels()); 15169 15170 ast_mutex_unlock(&monlock); 15171 15172 #ifdef HAVE_PRI 15173 for (i = 0; i < NUM_SPANS; i++) { 15174 for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) 15175 dahdi_close_pri_fd(&(pris[i]), j); 15176 } 15177 15178 memset(pris, 0, sizeof(pris)); 15179 for (i = 0; i < NUM_SPANS; i++) { 15180 sig_pri_init_pri(&pris[i].pri); 15181 } 15182 pri_set_error(dahdi_pri_error); 15183 pri_set_message(dahdi_pri_message); 15184 #endif 15185 #if defined(HAVE_SS7) 15186 for (i = 0; i < NUM_SPANS; i++) { 15187 for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) 15188 dahdi_close_ss7_fd(&(linksets[i]), j); 15189 } 15190 15191 memset(linksets, 0, sizeof(linksets)); 15192 for (i = 0; i < NUM_SPANS; i++) { 15193 sig_ss7_init_linkset(&linksets[i].ss7); 15194 } 15195 ss7_set_error(dahdi_ss7_error); 15196 ss7_set_message(dahdi_ss7_message); 15197 #endif /* defined(HAVE_SS7) */ 15198 15199 if (setup_dahdi(2) != 0) { 15200 ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n"); 15201 ast_mutex_unlock(&ss_thread_lock); 15202 return 1; 15203 } 15204 ast_mutex_unlock(&ss_thread_lock); 15205 ast_mutex_unlock(&restart_lock); 15206 return 0; 15207 }
| static char* dahdi_restart_cmd | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15209 of file chan_dahdi.c.
References ast_cli_args::argc, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_restart(), and ast_cli_entry::usage.
15210 { 15211 switch (cmd) { 15212 case CLI_INIT: 15213 e->command = "dahdi restart"; 15214 e->usage = 15215 "Usage: dahdi restart\n" 15216 " Restarts the DAHDI channels: destroys them all and then\n" 15217 " re-reads them from chan_dahdi.conf.\n" 15218 " Note that this will STOP any running CALL on DAHDI channels.\n" 15219 ""; 15220 return NULL; 15221 case CLI_GENERATE: 15222 return NULL; 15223 } 15224 if (a->argc != 2) 15225 return CLI_SHOWUSAGE; 15226 15227 if (dahdi_restart() != 0) 15228 return CLI_FAILURE; 15229 return CLI_SUCCESS; 15230 }
| static int dahdi_ring_phone | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 7645 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().
07646 { 07647 int x; 07648 int res; 07649 /* Make sure our transmit state is on hook */ 07650 x = 0; 07651 x = DAHDI_ONHOOK; 07652 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 07653 do { 07654 x = DAHDI_RING; 07655 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 07656 if (res) { 07657 switch (errno) { 07658 case EBUSY: 07659 case EINTR: 07660 /* Wait just in case */ 07661 usleep(10000); 07662 continue; 07663 case EINPROGRESS: 07664 res = 0; 07665 break; 07666 default: 07667 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno)); 07668 res = 0; 07669 } 07670 } 07671 } while (res); 07672 return res; 07673 }
| static int dahdi_sendtext | ( | struct ast_channel * | c, | |
| const char * | text | |||
| ) | [static] |
Definition at line 18888 of file chan_dahdi.c.
References ASCII_BYTES_PER_CHAR, ast_check_hangup(), ast_debug, ast_format_set(), ast_free, AST_LAW, ast_log(), ast_malloc, ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, dahdi_get_index, dahdi_sig_pri_lib_handles(), dahdi_subchannel::dfd, END_SILENCE_LEN, errno, HEADER_LEN, HEADER_MS, len(), dahdi_pvt::lock, LOG_ERROR, LOG_WARNING, dahdi_pvt::mate, PUT_CLID, PUT_CLID_MARKMS, READ_SIZE, dahdi_pvt::sig, dahdi_pvt::sig_pvt, dahdi_pvt::subs, dahdi_pvt::tdd, TDD_BYTES_PER_CHAR, tdd_generate(), ast_channel::tech_pvt, and TRAILER_MS.
18889 { 18890 #define END_SILENCE_LEN 400 18891 #define HEADER_MS 50 18892 #define TRAILER_MS 5 18893 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8) 18894 #define ASCII_BYTES_PER_CHAR 80 18895 18896 unsigned char *buf,*mybuf; 18897 struct dahdi_pvt *p = c->tech_pvt; 18898 struct pollfd fds[1]; 18899 int size,res,fd,len,x; 18900 int bytes=0; 18901 int idx; 18902 18903 /* 18904 * Initial carrier (imaginary) 18905 * 18906 * Note: The following float variables are used by the 18907 * PUT_CLID_MARKMS and PUT_CLID() macros. 18908 */ 18909 float cr = 1.0; 18910 float ci = 0.0; 18911 float scont = 0.0; 18912 18913 if (!text[0]) { 18914 return(0); /* if nothing to send, don't */ 18915 } 18916 idx = dahdi_get_index(c, p, 0); 18917 if (idx < 0) { 18918 ast_log(LOG_WARNING, "Huh? I don't exist?\n"); 18919 return -1; 18920 } 18921 if ((!p->tdd) && (!p->mate)) { 18922 #if defined(HAVE_PRI) 18923 #if defined(HAVE_PRI_DISPLAY_TEXT) 18924 ast_mutex_lock(&p->lock); 18925 if (dahdi_sig_pri_lib_handles(p->sig)) { 18926 sig_pri_sendtext(p->sig_pvt, text); 18927 } 18928 ast_mutex_unlock(&p->lock); 18929 #endif /* defined(HAVE_PRI_DISPLAY_TEXT) */ 18930 #endif /* defined(HAVE_PRI) */ 18931 return(0); /* if not in TDD mode, just return */ 18932 } 18933 if (p->mate) 18934 buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); 18935 else 18936 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); 18937 if (!buf) 18938 return -1; 18939 mybuf = buf; 18940 if (p->mate) { 18941 struct ast_format tmp; 18942 /* PUT_CLI_MARKMS is a macro and requires a format ptr called codec to be present */ 18943 struct ast_format *codec = &tmp; 18944 ast_format_set(codec, AST_LAW(p), 0); 18945 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */ 18946 PUT_CLID_MARKMS; 18947 } 18948 /* Put actual message */ 18949 for (x = 0; text[x]; x++) { 18950 PUT_CLID(text[x]); 18951 } 18952 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */ 18953 PUT_CLID_MARKMS; 18954 } 18955 len = bytes; 18956 buf = mybuf; 18957 } else { 18958 len = tdd_generate(p->tdd, buf, text); 18959 if (len < 1) { 18960 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text)); 18961 ast_free(mybuf); 18962 return -1; 18963 } 18964 } 18965 memset(buf + len, 0x7f, END_SILENCE_LEN); 18966 len += END_SILENCE_LEN; 18967 fd = p->subs[idx].dfd; 18968 while (len) { 18969 if (ast_check_hangup(c)) { 18970 ast_free(mybuf); 18971 return -1; 18972 } 18973 size = len; 18974 if (size > READ_SIZE) 18975 size = READ_SIZE; 18976 fds[0].fd = fd; 18977 fds[0].events = POLLOUT | POLLPRI; 18978 fds[0].revents = 0; 18979 res = poll(fds, 1, -1); 18980 if (!res) { 18981 ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel); 18982 continue; 18983 } 18984 /* if got exception */ 18985 if (fds[0].revents & POLLPRI) { 18986 ast_free(mybuf); 18987 return -1; 18988 } 18989 if (!(fds[0].revents & POLLOUT)) { 18990 ast_debug(1, "write fd not ready on channel %d\n", p->channel); 18991 continue; 18992 } 18993 res = write(fd, buf, size); 18994 if (res != size) { 18995 if (res == -1) { 18996 ast_free(mybuf); 18997 return -1; 18998 } 18999 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 19000 break; 19001 } 19002 len -= size; 19003 buf += size; 19004 } 19005 ast_free(mybuf); 19006 return(0); 19007 }
| static char* dahdi_set_dnd | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15810 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, iflock, dahdi_pvt::next, and ast_cli_entry::usage.
15811 { 15812 int channel; 15813 int on; 15814 struct dahdi_pvt *dahdi_chan = NULL; 15815 15816 switch (cmd) { 15817 case CLI_INIT: 15818 e->command = "dahdi set dnd"; 15819 e->usage = 15820 "Usage: dahdi set dnd <chan#> <on|off>\n" 15821 " Sets/resets DND (Do Not Disturb) mode on a channel.\n" 15822 " Changes take effect immediately.\n" 15823 " <chan num> is the channel number\n" 15824 " <on|off> Enable or disable DND mode?\n" 15825 ; 15826 return NULL; 15827 case CLI_GENERATE: 15828 return NULL; 15829 } 15830 15831 if (a->argc != 5) 15832 return CLI_SHOWUSAGE; 15833 15834 if ((channel = atoi(a->argv[3])) <= 0) { 15835 ast_cli(a->fd, "Expected channel number, got '%s'\n", a->argv[3]); 15836 return CLI_SHOWUSAGE; 15837 } 15838 15839 if (ast_true(a->argv[4])) 15840 on = 1; 15841 else if (ast_false(a->argv[4])) 15842 on = 0; 15843 else { 15844 ast_cli(a->fd, "Expected 'on' or 'off', got '%s'\n", a->argv[4]); 15845 return CLI_SHOWUSAGE; 15846 } 15847 15848 ast_mutex_lock(&iflock); 15849 for (dahdi_chan = iflist; dahdi_chan; dahdi_chan = dahdi_chan->next) { 15850 if (dahdi_chan->channel != channel) 15851 continue; 15852 15853 /* Found the channel. Actually set it */ 15854 dahdi_dnd(dahdi_chan, on); 15855 break; 15856 } 15857 ast_mutex_unlock(&iflock); 15858 15859 if (!dahdi_chan) { 15860 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15861 return CLI_FAILURE; 15862 } 15863 15864 return CLI_SUCCESS; 15865 }
| static int dahdi_set_hook | ( | int | fd, | |
| int | hs | |||
| ) | [inline, static] |
Definition at line 5149 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().
05150 { 05151 int x, res; 05152 05153 x = hs; 05154 res = ioctl(fd, DAHDI_HOOK, &x); 05155 05156 if (res < 0) { 05157 if (errno == EINPROGRESS) 05158 return 0; 05159 ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno)); 05160 /* will expectedly fail if phone is off hook during operation, such as during a restart */ 05161 } 05162 05163 return res; 05164 }
| static char* dahdi_set_hwgain | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15670 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, iflock, dahdi_pvt::next, SUB_REAL, dahdi_pvt::subs, and ast_cli_entry::usage.
15671 { 15672 int channel; 15673 int gain; 15674 int tx; 15675 struct dahdi_hwgain hwgain; 15676 struct dahdi_pvt *tmp = NULL; 15677 15678 switch (cmd) { 15679 case CLI_INIT: 15680 e->command = "dahdi set hwgain"; 15681 e->usage = 15682 "Usage: dahdi set hwgain <rx|tx> <chan#> <gain>\n" 15683 " Sets the hardware gain on a a given channel, overriding the\n" 15684 " value provided at module loadtime, whether the channel is in\n" 15685 " use or not. Changes take effect immediately.\n" 15686 " <rx|tx> which direction do you want to change (relative to our module)\n" 15687 " <chan num> is the channel number relative to the device\n" 15688 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"; 15689 return NULL; 15690 case CLI_GENERATE: 15691 return NULL; 15692 } 15693 15694 if (a->argc != 6) 15695 return CLI_SHOWUSAGE; 15696 15697 if (!strcasecmp("rx", a->argv[3])) 15698 tx = 0; /* rx */ 15699 else if (!strcasecmp("tx", a->argv[3])) 15700 tx = 1; /* tx */ 15701 else 15702 return CLI_SHOWUSAGE; 15703 15704 channel = atoi(a->argv[4]); 15705 gain = atof(a->argv[5])*10.0; 15706 15707 ast_mutex_lock(&iflock); 15708 15709 for (tmp = iflist; tmp; tmp = tmp->next) { 15710 15711 if (tmp->channel != channel) 15712 continue; 15713 15714 if (tmp->subs[SUB_REAL].dfd == -1) 15715 break; 15716 15717 hwgain.newgain = gain; 15718 hwgain.tx = tx; 15719 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_HWGAIN, &hwgain) < 0) { 15720 ast_cli(a->fd, "Unable to set the hardware gain for channel %d: %s\n", channel, strerror(errno)); 15721 ast_mutex_unlock(&iflock); 15722 return CLI_FAILURE; 15723 } 15724 ast_cli(a->fd, "hardware %s gain set to %d (%.1f dB) on channel %d\n", 15725 tx ? "tx" : "rx", gain, (float)gain/10.0, channel); 15726 break; 15727 } 15728 15729 ast_mutex_unlock(&iflock); 15730 15731 if (tmp) 15732 return CLI_SUCCESS; 15733 15734 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15735 return CLI_FAILURE; 15736 15737 }
| static char* dahdi_set_swgain | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15739 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, iflock, dahdi_pvt::law, dahdi_pvt::next, dahdi_pvt::rxdrc, set_actual_rxgain(), set_actual_txgain(), SUB_REAL, dahdi_pvt::subs, dahdi_pvt::txdrc, and ast_cli_entry::usage.
15740 { 15741 int channel; 15742 float gain; 15743 int tx; 15744 int res; 15745 struct dahdi_pvt *tmp = NULL; 15746 15747 switch (cmd) { 15748 case CLI_INIT: 15749 e->command = "dahdi set swgain"; 15750 e->usage = 15751 "Usage: dahdi set swgain <rx|tx> <chan#> <gain>\n" 15752 " Sets the software gain on a a given channel, overriding the\n" 15753 " value provided at module loadtime, whether the channel is in\n" 15754 " use or not. Changes take effect immediately.\n" 15755 " <rx|tx> which direction do you want to change (relative to our module)\n" 15756 " <chan num> is the channel number relative to the device\n" 15757 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"; 15758 return NULL; 15759 case CLI_GENERATE: 15760 return NULL; 15761 } 15762 15763 if (a->argc != 6) 15764 return CLI_SHOWUSAGE; 15765 15766 if (!strcasecmp("rx", a->argv[3])) 15767 tx = 0; /* rx */ 15768 else if (!strcasecmp("tx", a->argv[3])) 15769 tx = 1; /* tx */ 15770 else 15771 return CLI_SHOWUSAGE; 15772 15773 channel = atoi(a->argv[4]); 15774 gain = atof(a->argv[5]); 15775 15776 ast_mutex_lock(&iflock); 15777 for (tmp = iflist; tmp; tmp = tmp->next) { 15778 15779 if (tmp->channel != channel) 15780 continue; 15781 15782 if (tmp->subs[SUB_REAL].dfd == -1) 15783 break; 15784 15785 if (tx) 15786 res = set_actual_txgain(tmp->subs[SUB_REAL].dfd, gain, tmp->txdrc, tmp->law); 15787 else 15788 res = set_actual_rxgain(tmp->subs[SUB_REAL].dfd, gain, tmp->rxdrc, tmp->law); 15789 15790 if (res) { 15791 ast_cli(a->fd, "Unable to set the software gain for channel %d\n", channel); 15792 ast_mutex_unlock(&iflock); 15793 return CLI_FAILURE; 15794 } 15795 15796 ast_cli(a->fd, "software %s gain set to %.1f on channel %d\n", 15797 tx ? "tx" : "rx", gain, channel); 15798 break; 15799 } 15800 ast_mutex_unlock(&iflock); 15801 15802 if (tmp) 15803 return CLI_SUCCESS; 15804 15805 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15806 return CLI_FAILURE; 15807 15808 }
| static int dahdi_setlinear | ( | int | dfd, | |
| int | linear | |||
| ) | [static] |
Definition at line 4378 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 6727 of file chan_dahdi.c.
References ast_channel_name(), 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, pp, READ_SIZE, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, set_actual_rxgain(), set_actual_txgain(), dahdi_pvt::sig, dahdi_pvt::sig_pvt, SUB_REAL, dahdi_pvt::subs, dahdi_pvt::tdd, tdd_free(), tdd_new(), ast_channel::tech, ast_channel::tech_pvt, dahdi_pvt::txdrc, dahdi_pvt::txgain, and ast_channel_tech::type.
06728 { 06729 char *cp; 06730 signed char *scp; 06731 int x; 06732 int idx; 06733 struct dahdi_pvt *p = chan->tech_pvt, *pp; 06734 struct oprmode *oprmode; 06735 06736 06737 /* all supported options require data */ 06738 if (!p || !data || (datalen < 1)) { 06739 errno = EINVAL; 06740 return -1; 06741 } 06742 06743 switch (option) { 06744 case AST_OPTION_TXGAIN: 06745 scp = (signed char *) data; 06746 idx = dahdi_get_index(chan, p, 0); 06747 if (idx < 0) { 06748 ast_log(LOG_WARNING, "No index in TXGAIN?\n"); 06749 return -1; 06750 } 06751 ast_debug(1, "Setting actual tx gain on %s to %f\n", ast_channel_name(chan), p->txgain + (float) *scp); 06752 return set_actual_txgain(p->subs[idx].dfd, p->txgain + (float) *scp, p->txdrc, p->law); 06753 case AST_OPTION_RXGAIN: 06754 scp = (signed char *) data; 06755 idx = dahdi_get_index(chan, p, 0); 06756 if (idx < 0) { 06757 ast_log(LOG_WARNING, "No index in RXGAIN?\n"); 06758 return -1; 06759 } 06760 ast_debug(1, "Setting actual rx gain on %s to %f\n", ast_channel_name(chan), p->rxgain + (float) *scp); 06761 return set_actual_rxgain(p->subs[idx].dfd, p->rxgain + (float) *scp, p->rxdrc, p->law); 06762 case AST_OPTION_TONE_VERIFY: 06763 if (!p->dsp) 06764 break; 06765 cp = (char *) data; 06766 switch (*cp) { 06767 case 1: 06768 ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",ast_channel_name(chan)); 06769 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */ 06770 break; 06771 case 2: 06772 ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",ast_channel_name(chan)); 06773 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */ 06774 break; 06775 default: 06776 ast_debug(1, "Set option TONE VERIFY, mode: OFF(0) on %s\n",ast_channel_name(chan)); 06777 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */ 06778 break; 06779 } 06780 break; 06781 case AST_OPTION_TDD: 06782 /* turn on or off TDD */ 06783 cp = (char *) data; 06784 p->mate = 0; 06785 if (!*cp) { /* turn it off */ 06786 ast_debug(1, "Set option TDD MODE, value: OFF(0) on %s\n",ast_channel_name(chan)); 06787 if (p->tdd) 06788 tdd_free(p->tdd); 06789 p->tdd = 0; 06790 break; 06791 } 06792 ast_debug(1, "Set option TDD MODE, value: %s(%d) on %s\n", 06793 (*cp == 2) ? "MATE" : "ON", (int) *cp, ast_channel_name(chan)); 06794 dahdi_disable_ec(p); 06795 /* otherwise, turn it on */ 06796 if (!p->didtdd) { /* if havent done it yet */ 06797 unsigned char mybuf[41000];/*! \todo XXX This is an abuse of the stack!! */ 06798 unsigned char *buf; 06799 int size, res, fd, len; 06800 struct pollfd fds[1]; 06801 06802 buf = mybuf; 06803 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */ 06804 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */ 06805 len = 40000; 06806 idx = dahdi_get_index(chan, p, 0); 06807 if (idx < 0) { 06808 ast_log(LOG_WARNING, "No index in TDD?\n"); 06809 return -1; 06810 } 06811 fd = p->subs[idx].dfd; 06812 while (len) { 06813 if (ast_check_hangup(chan)) 06814 return -1; 06815 size = len; 06816 if (size > READ_SIZE) 06817 size = READ_SIZE; 06818 fds[0].fd = fd; 06819 fds[0].events = POLLPRI | POLLOUT; 06820 fds[0].revents = 0; 06821 res = poll(fds, 1, -1); 06822 if (!res) { 06823 ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel); 06824 continue; 06825 } 06826 /* if got exception */ 06827 if (fds[0].revents & POLLPRI) 06828 return -1; 06829 if (!(fds[0].revents & POLLOUT)) { 06830 ast_debug(1, "write fd not ready on channel %d\n", p->channel); 06831 continue; 06832 } 06833 res = write(fd, buf, size); 06834 if (res != size) { 06835 if (res == -1) return -1; 06836 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 06837 break; 06838 } 06839 len -= size; 06840 buf += size; 06841 } 06842 p->didtdd = 1; /* set to have done it now */ 06843 } 06844 if (*cp == 2) { /* Mate mode */ 06845 if (p->tdd) 06846 tdd_free(p->tdd); 06847 p->tdd = 0; 06848 p->mate = 1; 06849 break; 06850 } 06851 if (!p->tdd) { /* if we don't have one yet */ 06852 p->tdd = tdd_new(); /* allocate one */ 06853 } 06854 break; 06855 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */ 06856 if (!p->dsp) 06857 break; 06858 cp = (char *) data; 06859 ast_debug(1, "Set option RELAX DTMF, value: %s(%d) on %s\n", 06860 *cp ? "ON" : "OFF", (int) *cp, ast_channel_name(chan)); 06861 ast_dsp_set_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax); 06862 break; 06863 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */ 06864 #if defined(HAVE_PRI) 06865 if (dahdi_sig_pri_lib_handles(p->sig) 06866 && ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) { 06867 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */ 06868 break; 06869 } 06870 #endif /* defined(HAVE_PRI) */ 06871 06872 cp = (char *) data; 06873 if (!*cp) { 06874 ast_debug(1, "Set option AUDIO MODE, value: OFF(0) on %s\n", ast_channel_name(chan)); 06875 x = 0; 06876 dahdi_disable_ec(p); 06877 } else { 06878 ast_debug(1, "Set option AUDIO MODE, value: ON(1) on %s\n", ast_channel_name(chan)); 06879 x = 1; 06880 } 06881 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x) == -1) 06882 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, x, strerror(errno)); 06883 break; 06884 case AST_OPTION_OPRMODE: /* Operator services mode */ 06885 oprmode = (struct oprmode *) data; 06886 /* We don't support operator mode across technologies */ 06887 if (strcasecmp(chan->tech->type, oprmode->peer->tech->type)) { 06888 ast_log(LOG_NOTICE, "Operator mode not supported on %s to %s calls.\n", 06889 chan->tech->type, oprmode->peer->tech->type); 06890 errno = EINVAL; 06891 return -1; 06892 } 06893 pp = oprmode->peer->tech_pvt; 06894 p->oprmode = pp->oprmode = 0; 06895 /* setup peers */ 06896 p->oprpeer = pp; 06897 pp->oprpeer = p; 06898 /* setup modes, if any */ 06899 if (oprmode->mode) 06900 { 06901 pp->oprmode = oprmode->mode; 06902 p->oprmode = -oprmode->mode; 06903 } 06904 ast_debug(1, "Set Operator Services mode, value: %d on %s/%s\n", 06905 oprmode->mode, ast_channel_name(chan),ast_channel_name(oprmode->peer)); 06906 break; 06907 case AST_OPTION_ECHOCAN: 06908 cp = (char *) data; 06909 if (*cp) { 06910 ast_debug(1, "Enabling echo cancellation on %s\n", ast_channel_name(chan)); 06911 dahdi_enable_ec(p); 06912 } else { 06913 ast_debug(1, "Disabling echo cancellation on %s\n", ast_channel_name(chan)); 06914 dahdi_disable_ec(p); 06915 } 06916 break; 06917 case AST_OPTION_DIGIT_DETECT: 06918 cp = (char *) data; 06919 ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", ast_channel_name(chan)); 06920 if (*cp) { 06921 enable_dtmf_detect(p); 06922 } else { 06923 disable_dtmf_detect(p); 06924 } 06925 break; 06926 case AST_OPTION_FAX_DETECT: 06927 cp = (char *) data; 06928 if (p->dsp) { 06929 ast_debug(1, "%sabling fax tone detection on %s\n", *cp ? "En" : "Dis", ast_channel_name(chan)); 06930 if (*cp) { 06931 p->dsp_features |= DSP_FEATURE_FAX_DETECT; 06932 } else { 06933 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 06934 } 06935 ast_dsp_set_features(p->dsp, p->dsp_features); 06936 } 06937 break; 06938 default: 06939 return -1; 06940 } 06941 errno = 0; 06942 06943 return 0; 06944 }
| static char* dahdi_show_channel | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15328 of file chan_dahdi.c.
References sig_pri_chan::allocated, ast_cli_args::argc, ast_cli_args::argv, ast_channel_name(), ast_cli(), ast_log(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::busy_cadence, 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::description, 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, iflock, dahdi_pvt::inalarm, dahdi_pvt::inconference, dahdi_subchannel::inthreeway, dahdi_pvt::law_default, ast_dsp_busy_pattern::length, 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, ast_dsp_busy_pattern::pattern, 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, 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.
15329 { 15330 int channel; 15331 struct dahdi_pvt *tmp = NULL; 15332 struct dahdi_confinfo ci; 15333 struct dahdi_params ps; 15334 int x; 15335 15336 switch (cmd) { 15337 case CLI_INIT: 15338 e->command = "dahdi show channel"; 15339 e->usage = 15340 "Usage: dahdi show channel <chan num>\n" 15341 " Detailed information about a given channel\n"; 15342 return NULL; 15343 case CLI_GENERATE: 15344 return NULL; 15345 } 15346 15347 if (a->argc != 4) 15348 return CLI_SHOWUSAGE; 15349 15350 channel = atoi(a->argv[3]); 15351 15352 ast_mutex_lock(&iflock); 15353 for (tmp = iflist; tmp; tmp = tmp->next) { 15354 if (tmp->channel == channel) { 15355 ast_cli(a->fd, "Channel: %d\n", tmp->channel); 15356 ast_cli(a->fd, "Description: %s\n", tmp->description); 15357 ast_cli(a->fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].dfd); 15358 ast_cli(a->fd, "Span: %d\n", tmp->span); 15359 ast_cli(a->fd, "Extension: %s\n", tmp->exten); 15360 ast_cli(a->fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no"); 15361 ast_cli(a->fd, "Context: %s\n", tmp->context); 15362 ast_cli(a->fd, "Caller ID: %s\n", tmp->cid_num); 15363 ast_cli(a->fd, "Calling TON: %d\n", tmp->cid_ton); 15364 #if defined(HAVE_PRI) 15365 #if defined(HAVE_PRI_SUBADDR) 15366 ast_cli(a->fd, "Caller ID subaddress: %s\n", tmp->cid_subaddr); 15367 #endif /* defined(HAVE_PRI_SUBADDR) */ 15368 #endif /* defined(HAVE_PRI) */ 15369 ast_cli(a->fd, "Caller ID name: %s\n", tmp->cid_name); 15370 ast_cli(a->fd, "Mailbox: %s\n", S_OR(tmp->mailbox, "none")); 15371 if (tmp->vars) { 15372 struct ast_variable *v; 15373 ast_cli(a->fd, "Variables:\n"); 15374 for (v = tmp->vars ; v ; v = v->next) 15375 ast_cli(a->fd, " %s = %s\n", v->name, v->value); 15376 } 15377 ast_cli(a->fd, "Destroy: %d\n", tmp->destroy); 15378 ast_cli(a->fd, "InAlarm: %d\n", tmp->inalarm); 15379 ast_cli(a->fd, "Signalling Type: %s\n", sig2str(tmp->sig)); 15380 ast_cli(a->fd, "Radio: %d\n", tmp->radio); 15381 ast_cli(a->fd, "Owner: %s\n", tmp->owner ? ast_channel_name(tmp->owner) : "<None>"); 15382 ast_cli(a->fd, "Real: %s%s%s\n", tmp->subs[SUB_REAL].owner ? ast_channel_name(tmp->subs[SUB_REAL].owner) : "<None>", tmp->subs[SUB_REAL].inthreeway ? " (Confed)" : "", tmp->subs[SUB_REAL].linear ? " (Linear)" : ""); 15383 ast_cli(a->fd, "Callwait: %s%s%s\n", tmp->subs[SUB_CALLWAIT].owner ? ast_channel_name(tmp->subs[SUB_CALLWAIT].owner) : "<None>", tmp->subs[SUB_CALLWAIT].inthreeway ? " (Confed)" : "", tmp->subs[SUB_CALLWAIT].linear ? " (Linear)" : ""); 15384 ast_cli(a->fd, "Threeway: %s%s%s\n", tmp->subs[SUB_THREEWAY].owner ? ast_channel_name(tmp->subs[SUB_THREEWAY].owner) : "<None>", tmp->subs[SUB_THREEWAY].inthreeway ? " (Confed)" : "", tmp->subs[SUB_THREEWAY].linear ? " (Linear)" : ""); 15385 ast_cli(a->fd, "Confno: %d\n", tmp->confno); 15386 ast_cli(a->fd, "Propagated Conference: %d\n", tmp->propconfno); 15387 ast_cli(a->fd, "Real in conference: %d\n", tmp->inconference); 15388 ast_cli(a->fd, "DSP: %s\n", tmp->dsp ? "yes" : "no"); 15389 ast_cli(a->fd, "Busy Detection: %s\n", tmp->busydetect ? "yes" : "no"); 15390 if (tmp->busydetect) { 15391 #if defined(BUSYDETECT_TONEONLY) 15392 ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_TONEONLY\n"); 15393 #elif defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE) 15394 ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_COMPARE_TONE_AND_SILENCE\n"); 15395 #endif 15396 #ifdef BUSYDETECT_DEBUG 15397 ast_cli(a->fd, " Busy Detector Debug: Enabled\n"); 15398 #endif 15399 ast_cli(a->fd, " Busy Count: %d\n", tmp->busycount); 15400 ast_cli(a->fd, " Busy Pattern: %d,%d,%d,%d\n", tmp->busy_cadence.pattern[0], tmp->busy_cadence.pattern[1], (tmp->busy_cadence.length == 4) ? tmp->busy_cadence.pattern[2] : 0, (tmp->busy_cadence.length == 4) ? tmp->busy_cadence.pattern[3] : 0); 15401 } 15402 ast_cli(a->fd, "TDD: %s\n", tmp->tdd ? "yes" : "no"); 15403 ast_cli(a->fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no"); 15404 ast_cli(a->fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas); 15405 ast_cli(a->fd, "Default law: %s\n", tmp->law_default == DAHDI_LAW_MULAW ? "ulaw" : tmp->law_default == DAHDI_LAW_ALAW ? "alaw" : "unknown"); 15406 ast_cli(a->fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); 15407 ast_cli(a->fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); 15408 ast_cli(a->fd, "Gains (RX/TX): %.2f/%.2f\n", tmp->rxgain, tmp->txgain); 15409 ast_cli(a->fd, "Dynamic Range Compression (RX/TX): %.2f/%.2f\n", tmp->rxdrc, tmp->txdrc); 15410 ast_cli(a->fd, "DND: %s\n", dahdi_dnd(tmp, -1) ? "yes" : "no"); 15411 ast_cli(a->fd, "Echo Cancellation:\n"); 15412 15413 if (tmp->echocancel.head.tap_length) { 15414 ast_cli(a->fd, "\t%d taps\n", tmp->echocancel.head.tap_length); 15415 for (x = 0; x < tmp->echocancel.head.param_count; x++) { 15416 ast_cli(a->fd, "\t\t%s: %ud\n", tmp->echocancel.params[x].name, tmp->echocancel.params[x].value); 15417 } 15418 ast_cli(a->fd, "\t%scurrently %s\n", tmp->echocanbridged ? "" : "(unless TDM bridged) ", tmp->echocanon ? "ON" : "OFF"); 15419 } else { 15420 ast_cli(a->fd, "\tnone\n"); 15421 } 15422 ast_cli(a->fd, "Wait for dialtone: %dms\n", tmp->waitfordialtone); 15423 if (tmp->master) 15424 ast_cli(a->fd, "Master Channel: %d\n", tmp->master->channel); 15425 for (x = 0; x < MAX_SLAVES; x++) { 15426 if (tmp->slaves[x]) 15427 ast_cli(a->fd, "Slave Channel: %d\n", tmp->slaves[x]->channel); 15428 } 15429 #ifdef HAVE_OPENR2 15430 if (tmp->mfcr2) { 15431 char calldir[OR2_MAX_PATH]; 15432 openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan); 15433 openr2_variant_t r2variant = openr2_context_get_variant(r2context); 15434 ast_cli(a->fd, "MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan)); 15435 ast_cli(a->fd, "MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan)); 15436 ast_cli(a->fd, "MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan)); 15437 ast_cli(a->fd, "MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan)); 15438 ast_cli(a->fd, "MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ? "Yes" : "No"); 15439 ast_cli(a->fd, "MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant)); 15440 ast_cli(a->fd, "MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context)); 15441 ast_cli(a->fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context)); 15442 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2 15443 ast_cli(a->fd, "MFC/R2 DTMF Dialing: %s\n", openr2_context_get_dtmf_dialing(r2context, NULL, NULL) ? "Yes" : "No"); 15444 ast_cli(a->fd, "MFC/R2 DTMF Detection: %s\n", openr2_context_get_dtmf_detection(r2context) ? "Yes" : "No"); 15445 #endif 15446 ast_cli(a->fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No"); 15447 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 15448 ast_cli(a->fd, "MFC/R2 Skip Category Request: %s\n", openr2_context_get_skip_category_request(r2context) ? "Yes" : "No"); 15449 #endif 15450 ast_cli(a->fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No"); 15451 ast_cli(a->fd, "MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No"); 15452 ast_cli(a->fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No"); 15453 ast_cli(a->fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No"); 15454 ast_cli(a->fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No"); 15455 ast_cli(a->fd, "MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context)); 15456 ast_cli(a->fd, "MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context)); 15457 ast_cli(a->fd, "MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan)); 15458 ast_cli(a->fd, "MFC/R2 Tx CAS: %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan)); 15459 ast_cli(a->fd, "MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan)); 15460 ast_cli(a->fd, "MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan)); 15461 ast_cli(a->fd, "MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir, sizeof(calldir))); 15462 } 15463 #endif 15464 #if defined(HAVE_SS7) 15465 if (tmp->ss7) { 15466 struct sig_ss7_chan *chan = tmp->sig_pvt; 15467 15468 ast_cli(a->fd, "CIC: %d\n", chan->cic); 15469 } 15470 #endif /* defined(HAVE_SS7) */ 15471 #ifdef HAVE_PRI 15472 if (tmp->pri) { 15473 struct sig_pri_chan *chan = tmp->sig_pvt; 15474 15475 ast_cli(a->fd, "PRI Flags: "); 15476 if (chan->resetting) 15477 ast_cli(a->fd, "Resetting "); 15478 if (chan->call) 15479 ast_cli(a->fd, "Call "); 15480 if (chan->allocated) { 15481 ast_cli(a->fd, "Allocated "); 15482 } 15483 ast_cli(a->fd, "\n"); 15484 if (tmp->logicalspan) 15485 ast_cli(a->fd, "PRI Logical Span: %d\n", tmp->logicalspan); 15486 else 15487 ast_cli(a->fd, "PRI Logical Span: Implicit\n"); 15488 } 15489 #endif 15490 memset(&ci, 0, sizeof(ci)); 15491 ps.channo = tmp->channel; 15492 if (tmp->subs[SUB_REAL].dfd > -1) { 15493 memset(&ci, 0, sizeof(ci)); 15494 if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) { 15495 ast_cli(a->fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode); 15496 } 15497 if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONFMUTE, &x)) { 15498 ast_cli(a->fd, "Actual Confmute: %s\n", x ? "Yes" : "No"); 15499 } 15500 memset(&ps, 0, sizeof(ps)); 15501 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) { 15502 ast_log(LOG_WARNING, "Failed to get parameters on channel %d: %s\n", tmp->channel, strerror(errno)); 15503 } else { 15504 ast_cli(a->fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook"); 15505 } 15506 } 15507 ast_mutex_unlock(&iflock); 15508 return CLI_SUCCESS; 15509 } 15510 } 15511 ast_mutex_unlock(&iflock); 15512 15513 ast_cli(a->fd, "Unable to find given channel %d\n", channel); 15514 return CLI_FAILURE; 15515 }
| static char* dahdi_show_channels | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15242 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::description, dahdi_pvt::exten, ast_cli_args::fd, FORMAT, FORMAT2, dahdi_pvt::group, iflock, dahdi_pvt::language, dahdi_pvt::locallyblocked, dahdi_pvt::mohinterpret, dahdi_pvt::next, dahdi_pvt::remotelyblocked, and ast_cli_entry::usage.
15243 { 15244 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n" 15245 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n" 15246 unsigned int targetnum = 0; 15247 int filtertype = 0; 15248 struct dahdi_pvt *tmp = NULL; 15249 char tmps[20] = ""; 15250 char statestr[20] = ""; 15251 char blockstr[20] = ""; 15252 15253 switch (cmd) { 15254 case CLI_INIT: 15255 e->command = "dahdi show channels [group|context]"; 15256 e->usage = 15257 "Usage: dahdi show channels [ group <group> | context <context> ]\n" 15258 " Shows a list of available channels with optional filtering\n" 15259 " <group> must be a number between 0 and 63\n"; 15260 return NULL; 15261 case CLI_GENERATE: 15262 return NULL; 15263 } 15264 15265 /* syntax: dahdi show channels [ group <group> | context <context> ] */ 15266 15267 if (!((a->argc == 3) || (a->argc == 5))) 15268 return CLI_SHOWUSAGE; 15269 15270 if (a->argc == 5) { 15271 if (!strcasecmp(a->argv[3], "group")) { 15272 targetnum = atoi(a->argv[4]); 15273 if ((targetnum < 0) || (targetnum > 63)) 15274 return CLI_SHOWUSAGE; 15275 targetnum = 1 << targetnum; 15276 filtertype = 1; 15277 } else if (!strcasecmp(a->argv[3], "context")) { 15278 filtertype = 2; 15279 } 15280 } 15281 15282 ast_cli(a->fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret", "Blocked", "State", "Description"); 15283 ast_mutex_lock(&iflock); 15284 for (tmp = iflist; tmp; tmp = tmp->next) { 15285 if (filtertype) { 15286 switch(filtertype) { 15287 case 1: /* dahdi show channels group <group> */ 15288 if (!(tmp->group & targetnum)) { 15289 continue; 15290 } 15291 break; 15292 case 2: /* dahdi show channels context <context> */ 15293 if (strcasecmp(tmp->context, a->argv[4])) { 15294 continue; 15295 } 15296 break; 15297 default: 15298 break; 15299 } 15300 } 15301 if (tmp->channel > 0) { 15302 snprintf(tmps, sizeof(tmps), "%d", tmp->channel); 15303 } else 15304 ast_copy_string(tmps, "pseudo", sizeof(tmps)); 15305 15306 if (tmp->locallyblocked) 15307 blockstr[0] = 'L'; 15308 else 15309 blockstr[0] = ' '; 15310 15311 if (tmp->remotelyblocked) 15312 blockstr[1] = 'R'; 15313 else 15314 blockstr[1] = ' '; 15315 15316 blockstr[2] = '\0'; 15317 15318 snprintf(statestr, sizeof(statestr), "%s", "In Service"); 15319 15320 ast_cli(a->fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret, blockstr, statestr, tmp->description); 15321 } 15322 ast_mutex_unlock(&iflock); 15323 return CLI_SUCCESS; 15324 #undef FORMAT 15325 #undef FORMAT2 15326 }
| static char* dahdi_show_status | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15554 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.
15555 { 15556 #define FORMAT "%-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n" 15557 #define FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n" 15558 int span; 15559 int res; 15560 char alarmstr[50]; 15561 15562 int ctl; 15563 struct dahdi_spaninfo s; 15564 15565 switch (cmd) { 15566 case CLI_INIT: 15567 e->command = "dahdi show status"; 15568 e->usage = 15569 "Usage: dahdi show status\n" 15570 " Shows a list of DAHDI cards with status\n"; 15571 return NULL; 15572 case CLI_GENERATE: 15573 return NULL; 15574 } 15575 ctl = open("/dev/dahdi/ctl", O_RDWR); 15576 if (ctl < 0) { 15577 ast_cli(a->fd, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); 15578 return CLI_FAILURE; 15579 } 15580 ast_cli(a->fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC", "Framing", "Coding", "Options", "LBO"); 15581 15582 for (span = 1; span < DAHDI_MAX_SPANS; ++span) { 15583 s.spanno = span; 15584 res = ioctl(ctl, DAHDI_SPANSTAT, &s); 15585 if (res) { 15586 continue; 15587 } 15588 alarmstr[0] = '\0'; 15589 if (s.alarms > 0) { 15590 if (s.alarms & DAHDI_ALARM_BLUE) 15591 strcat(alarmstr, "BLU/"); 15592 if (s.alarms & DAHDI_ALARM_YELLOW) 15593 strcat(alarmstr, "YEL/"); 15594 if (s.alarms & DAHDI_ALARM_RED) 15595 strcat(alarmstr, "RED/"); 15596 if (s.alarms & DAHDI_ALARM_LOOPBACK) 15597 strcat(alarmstr, "LB/"); 15598 if (s.alarms & DAHDI_ALARM_RECOVER) 15599 strcat(alarmstr, "REC/"); 15600 if (s.alarms & DAHDI_ALARM_NOTOPEN) 15601 strcat(alarmstr, "NOP/"); 15602 if (!strlen(alarmstr)) 15603 strcat(alarmstr, "UUU/"); 15604 if (strlen(alarmstr)) { 15605 /* Strip trailing / */ 15606 alarmstr[strlen(alarmstr) - 1] = '\0'; 15607 } 15608 } else { 15609 if (s.numchans) 15610 strcpy(alarmstr, "OK"); 15611 else 15612 strcpy(alarmstr, "UNCONFIGURED"); 15613 } 15614 15615 ast_cli(a->fd, FORMAT, s.desc, alarmstr, s.irqmisses, s.bpvcount, s.crc4count, 15616 s.lineconfig & DAHDI_CONFIG_D4 ? "D4" : 15617 s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" : 15618 s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" : 15619 "CAS", 15620 s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" : 15621 s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" : 15622 s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" : 15623 "Unk", 15624 s.lineconfig & DAHDI_CONFIG_CRC4 ? 15625 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" : 15626 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : "", 15627 lbostr[s.lbo] 15628 ); 15629 } 15630 close(ctl); 15631 15632 return CLI_SUCCESS; 15633 #undef FORMAT 15634 #undef FORMAT2 15635 }
| static char* dahdi_show_version | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15637 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.
15638 { 15639 int pseudo_fd = -1; 15640 struct dahdi_versioninfo vi; 15641 15642 switch (cmd) { 15643 case CLI_INIT: 15644 e->command = "dahdi show version"; 15645 e->usage = 15646 "Usage: dahdi show version\n" 15647 " Shows the DAHDI version in use\n"; 15648 return NULL; 15649 case CLI_GENERATE: 15650 return NULL; 15651 } 15652 if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) { 15653 ast_cli(a->fd, "Failed to open control file to get version.\n"); 15654 return CLI_SUCCESS; 15655 } 15656 15657 strcpy(vi.version, "Unknown"); 15658 strcpy(vi.echo_canceller, "Unknown"); 15659 15660 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi)) 15661 ast_cli(a->fd, "Failed to get DAHDI version: %s\n", strerror(errno)); 15662 else 15663 ast_cli(a->fd, "DAHDI Version: %s Echo Canceller: %s\n", vi.version, vi.echo_canceller); 15664 15665 close(pseudo_fd); 15666 15667 return CLI_SUCCESS; 15668 }
| static char* dahdi_sig2str | ( | int | sig | ) | [static] |
Definition at line 4599 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().
04600 { 04601 static char buf[256]; 04602 switch (sig) { 04603 case SIG_EM: 04604 return "E & M Immediate"; 04605 case SIG_EMWINK: 04606 return "E & M Wink"; 04607 case SIG_EM_E1: 04608 return "E & M E1"; 04609 case SIG_FEATD: 04610 return "Feature Group D (DTMF)"; 04611 case SIG_FEATDMF: 04612 return "Feature Group D (MF)"; 04613 case SIG_FEATDMF_TA: 04614 return "Feature Groud D (MF) Tandem Access"; 04615 case SIG_FEATB: 04616 return "Feature Group B (MF)"; 04617 case SIG_E911: 04618 return "E911 (MF)"; 04619 case SIG_FGC_CAMA: 04620 return "FGC/CAMA (Dialpulse)"; 04621 case SIG_FGC_CAMAMF: 04622 return "FGC/CAMA (MF)"; 04623 case SIG_FXSLS: 04624 return "FXS Loopstart"; 04625 case SIG_FXSGS: 04626 return "FXS Groundstart"; 04627 case SIG_FXSKS: 04628 return "FXS Kewlstart"; 04629 case SIG_FXOLS: 04630 return "FXO Loopstart"; 04631 case SIG_FXOGS: 04632 return "FXO Groundstart"; 04633 case SIG_FXOKS: 04634 return "FXO Kewlstart"; 04635 case SIG_PRI: 04636 return "ISDN PRI"; 04637 case SIG_BRI: 04638 return "ISDN BRI Point to Point"; 04639 case SIG_BRI_PTMP: 04640 return "ISDN BRI Point to MultiPoint"; 04641 case SIG_SS7: 04642 return "SS7"; 04643 case SIG_MFCR2: 04644 return "MFC/R2"; 04645 case SIG_SF: 04646 return "SF (Tone) Immediate"; 04647 case SIG_SFWINK: 04648 return "SF (Tone) Wink"; 04649 case SIG_SF_FEATD: 04650 return "SF (Tone) with Feature Group D (DTMF)"; 04651 case SIG_SF_FEATDMF: 04652 return "SF (Tone) with Feature Group D (MF)"; 04653 case SIG_SF_FEATB: 04654 return "SF (Tone) with Feature Group B (MF)"; 04655 case 0: 04656 return "Pseudo"; 04657 default: 04658 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig); 04659 return buf; 04660 } 04661 }
| static int dahdi_sig_pri_lib_handles | ( | int | signaling | ) | [inline, static] |
Definition at line 1567 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_sendtext(), dahdi_setoption(), and mkintf().
01568 { 01569 int handles; 01570 01571 switch (signaling) { 01572 case SIG_PRI_LIB_HANDLE_CASES: 01573 handles = 1; 01574 break; 01575 default: 01576 handles = 0; 01577 break; 01578 } 01579 01580 return handles; 01581 }
| static void dahdi_softhangup_all | ( | void | ) | [static] |
Definition at line 15069 of file chan_dahdi.c.
References ast_channel_name(), ast_channel_trylock, ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, AST_SOFTHANGUP_EXPLICIT, ast_softhangup_nolock(), ast_verbose, iflock, dahdi_pvt::lock, dahdi_pvt::next, option_debug, dahdi_pvt::owner, and dahdi_pvt::restartpending.
Referenced by dahdi_restart().
15070 { 15071 struct dahdi_pvt *p; 15072 retry: 15073 ast_mutex_lock(&iflock); 15074 for (p = iflist; p; p = p->next) { 15075 ast_mutex_lock(&p->lock); 15076 if (p->owner && !p->restartpending) { 15077 if (ast_channel_trylock(p->owner)) { 15078 if (option_debug > 2) 15079 ast_verbose("Avoiding deadlock\n"); 15080 /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */ 15081 ast_mutex_unlock(&p->lock); 15082 ast_mutex_unlock(&iflock); 15083 goto retry; 15084 } 15085 if (option_debug > 2) 15086 ast_verbose("Softhanging up on %s\n", ast_channel_name(p->owner)); 15087 ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_EXPLICIT); 15088 p->restartpending = 1; 15089 num_restart_pending++; 15090 ast_channel_unlock(p->owner); 15091 } 15092 ast_mutex_unlock(&p->lock); 15093 } 15094 ast_mutex_unlock(&iflock); 15095 }
| static int dahdi_status_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 18646 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.
18648 { 18649 int ctl, res, span; 18650 struct ast_data *data_span, *data_alarms; 18651 struct dahdi_spaninfo s; 18652 18653 ctl = open("/dev/dahdi/ctl", O_RDWR); 18654 if (ctl < 0) { 18655 ast_log(LOG_ERROR, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); 18656 return -1; 18657 } 18658 for (span = 1; span < DAHDI_MAX_SPANS; ++span) { 18659 s.spanno = span; 18660 res = ioctl(ctl, DAHDI_SPANSTAT, &s); 18661 if (res) { 18662 continue; 18663 } 18664 18665 data_span = ast_data_add_node(data_root, "span"); 18666 if (!data_span) { 18667 continue; 18668 } 18669 ast_data_add_str(data_span, "description", s.desc); 18670 18671 /* insert the alarms status */ 18672 data_alarms = ast_data_add_node(data_span, "alarms"); 18673 if (!data_alarms) { 18674 continue; 18675 } 18676 18677 ast_data_add_bool(data_alarms, "BLUE", s.alarms & DAHDI_ALARM_BLUE); 18678 ast_data_add_bool(data_alarms, "YELLOW", s.alarms & DAHDI_ALARM_YELLOW); 18679 ast_data_add_bool(data_alarms, "RED", s.alarms & DAHDI_ALARM_RED); 18680 ast_data_add_bool(data_alarms, "LOOPBACK", s.alarms & DAHDI_ALARM_LOOPBACK); 18681 ast_data_add_bool(data_alarms, "RECOVER", s.alarms & DAHDI_ALARM_RECOVER); 18682 ast_data_add_bool(data_alarms, "NOTOPEN", s.alarms & DAHDI_ALARM_NOTOPEN); 18683 18684 ast_data_add_int(data_span, "irqmisses", s.irqmisses); 18685 ast_data_add_int(data_span, "bpviol", s.bpvcount); 18686 ast_data_add_int(data_span, "crc4", s.crc4count); 18687 ast_data_add_str(data_span, "framing", s.lineconfig & DAHDI_CONFIG_D4 ? "D4" : 18688 s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" : 18689 s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" : 18690 "CAS"); 18691 ast_data_add_str(data_span, "coding", s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" : 18692 s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" : 18693 s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" : 18694 "Unknown"); 18695 ast_data_add_str(data_span, "options", s.lineconfig & DAHDI_CONFIG_CRC4 ? 18696 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" : 18697 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : ""); 18698 ast_data_add_str(data_span, "lbo", lbostr[s.lbo]); 18699 18700 /* if this span doesn't match remove it. */ 18701 if (!ast_data_search_match(search, data_span)) { 18702 ast_data_remove_node(data_root, data_span); 18703 } 18704 } 18705 close(ctl); 18706 18707 return 0; 18708 }
| static void dahdi_train_ec | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4941 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().
04942 { 04943 int x; 04944 int res; 04945 04946 if (p && p->echocanon && p->echotraining) { 04947 x = p->echotraining; 04948 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x); 04949 if (res) 04950 ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno)); 04951 else 04952 ast_debug(1, "Engaged echo training on channel %d\n", p->channel); 04953 } else { 04954 ast_debug(1, "No echo training requested\n"); 04955 } 04956 }
| static void dahdi_unlink | ( | struct dahdi_pvt * | slave, | |
| struct dahdi_pvt * | master, | |||
| int | needlock | |||
| ) | [static] |
Definition at line 7159 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().
07160 { 07161 /* Unlink a specific slave or all slaves/masters from a given master */ 07162 int x; 07163 int hasslaves; 07164 if (!master) 07165 return; 07166 if (needlock) { 07167 ast_mutex_lock(&master->lock); 07168 if (slave) { 07169 while (ast_mutex_trylock(&slave->lock)) { 07170 DEADLOCK_AVOIDANCE(&master->lock); 07171 } 07172 } 07173 } 07174 hasslaves = 0; 07175 for (x = 0; x < MAX_SLAVES; x++) { 07176 if (master->slaves[x]) { 07177 if (!slave || (master->slaves[x] == slave)) { 07178 /* Take slave out of the conference */ 07179 ast_debug(1, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel); 07180 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL); 07181 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL); 07182 master->slaves[x]->master = NULL; 07183 master->slaves[x] = NULL; 07184 } else 07185 hasslaves = 1; 07186 } 07187 if (!hasslaves) 07188 master->inconference = 0; 07189 } 07190 if (!slave) { 07191 if (master->master) { 07192 /* Take master out of the conference */ 07193 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL); 07194 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL); 07195 hasslaves = 0; 07196 for (x = 0; x < MAX_SLAVES; x++) { 07197 if (master->master->slaves[x] == master) 07198 master->master->slaves[x] = NULL; 07199 else if (master->master->slaves[x]) 07200 hasslaves = 1; 07201 } 07202 if (!hasslaves) 07203 master->master->inconference = 0; 07204 } 07205 master->master = NULL; 07206 } 07207 update_conf(master); 07208 if (needlock) { 07209 if (slave) 07210 ast_mutex_unlock(&slave->lock); 07211 ast_mutex_unlock(&master->lock); 07212 } 07213 }
| static int dahdi_version_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 18749 of file chan_dahdi.c.
References ast_data_add_str(), ast_log(), errno, and LOG_ERROR.
18751 { 18752 int pseudo_fd = -1; 18753 struct dahdi_versioninfo vi = { 18754 .version = "Unknown", 18755 .echo_canceller = "Unknown" 18756 }; 18757 18758 if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) { 18759 ast_log(LOG_ERROR, "Failed to open control file to get version.\n"); 18760 return -1; 18761 } 18762 18763 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi)) { 18764 ast_log(LOG_ERROR, "Failed to get DAHDI version: %s\n", strerror(errno)); 18765 } 18766 18767 close(pseudo_fd); 18768 18769 ast_data_add_str(data_root, "value", vi.version); 18770 ast_data_add_str(data_root, "echocanceller", vi.echo_canceller); 18771 18772 return 0; 18773 }
| static int dahdi_wait_event | ( | int | fd | ) | [inline, static] |
Avoid the silly dahdi_waitevent which ignores a bunch of events.
Definition at line 512 of file chan_dahdi.c.
00513 { 00514 int i, j = 0; 00515 i = DAHDI_IOMUX_SIGEVENT; 00516 if (ioctl(fd, DAHDI_IOMUX, &i) == -1) 00517 return -1; 00518 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1) 00519 return -1; 00520 return j; 00521 }
| static int dahdi_wink | ( | struct dahdi_pvt * | p, | |
| int | index | |||
| ) | [static] |
Definition at line 9840 of file chan_dahdi.c.
References dahdi_set_hook(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
Referenced by analog_ss_thread(), and my_wink().
09841 { 09842 int j; 09843 dahdi_set_hook(p->subs[idx].dfd, DAHDI_WINK); 09844 for (;;) 09845 { 09846 /* set bits of interest */ 09847 j = DAHDI_IOMUX_SIGEVENT; 09848 /* wait for some happening */ 09849 if (ioctl(p->subs[idx].dfd,DAHDI_IOMUX,&j) == -1) return(-1); 09850 /* exit loop if we have it */ 09851 if (j & DAHDI_IOMUX_SIGEVENT) break; 09852 } 09853 /* get the event info */ 09854 if (ioctl(p->subs[idx].dfd,DAHDI_GETEVENT,&j) == -1) return(-1); 09855 return 0; 09856 }
| static int dahdi_write | ( | struct ast_channel * | ast, | |
| struct ast_frame * | frame | |||
| ) | [static] |
Definition at line 9366 of file chan_dahdi.c.
References ast_channel_name(), 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, dahdi_get_index, dahdi_setlinear(), ast_frame::data, ast_frame::datalen, dahdi_subchannel::dfd, dahdi_pvt::dialing, errno, ast_frame_subclass::format, ast_frame::frametype, ast_format::id, 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.
09367 { 09368 struct dahdi_pvt *p = ast->tech_pvt; 09369 int res; 09370 int idx; 09371 idx = dahdi_get_index(ast, p, 0); 09372 if (idx < 0) { 09373 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast_channel_name(ast)); 09374 return -1; 09375 } 09376 09377 /* Write a frame of (presumably voice) data */ 09378 if (frame->frametype != AST_FRAME_VOICE) { 09379 if (frame->frametype != AST_FRAME_IMAGE) 09380 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 09381 return 0; 09382 } 09383 if ((frame->subclass.format.id != AST_FORMAT_SLINEAR) && 09384 (frame->subclass.format.id != AST_FORMAT_ULAW) && 09385 (frame->subclass.format.id != AST_FORMAT_ALAW)) { 09386 ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format)); 09387 return -1; 09388 } 09389 if (p->dialing) { 09390 ast_debug(1, "Dropping frame since I'm still dialing on %s...\n",ast_channel_name(ast)); 09391 return 0; 09392 } 09393 if (!p->owner) { 09394 ast_debug(1, "Dropping frame since there is no active owner on %s...\n",ast_channel_name(ast)); 09395 return 0; 09396 } 09397 if (p->cidspill) { 09398 ast_debug(1, "Dropping frame since I've still got a callerid spill on %s...\n", 09399 ast_channel_name(ast)); 09400 return 0; 09401 } 09402 /* Return if it's not valid data */ 09403 if (!frame->data.ptr || !frame->datalen) 09404 return 0; 09405 09406 if (frame->subclass.format.id == AST_FORMAT_SLINEAR) { 09407 if (!p->subs[idx].linear) { 09408 p->subs[idx].linear = 1; 09409 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09410 if (res) 09411 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel); 09412 } 09413 res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 1); 09414 } else { 09415 /* x-law already */ 09416 if (p->subs[idx].linear) { 09417 p->subs[idx].linear = 0; 09418 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 09419 if (res) 09420 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel); 09421 } 09422 res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 0); 09423 } 09424 if (res < 0) { 09425 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 09426 return -1; 09427 } 09428 return 0; 09429 }
| static enum analog_event dahdievent_to_analogevent | ( | int | event | ) | [static] |
Definition at line 2754 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().
02755 { 02756 enum analog_event res; 02757 02758 switch (event) { 02759 case DAHDI_EVENT_ONHOOK: 02760 res = ANALOG_EVENT_ONHOOK; 02761 break; 02762 case DAHDI_EVENT_RINGOFFHOOK: 02763 res = ANALOG_EVENT_RINGOFFHOOK; 02764 break; 02765 case DAHDI_EVENT_WINKFLASH: 02766 res = ANALOG_EVENT_WINKFLASH; 02767 break; 02768 case DAHDI_EVENT_ALARM: 02769 res = ANALOG_EVENT_ALARM; 02770 break; 02771 case DAHDI_EVENT_NOALARM: 02772 res = ANALOG_EVENT_NOALARM; 02773 break; 02774 case DAHDI_EVENT_DIALCOMPLETE: 02775 res = ANALOG_EVENT_DIALCOMPLETE; 02776 break; 02777 case DAHDI_EVENT_RINGERON: 02778 res = ANALOG_EVENT_RINGERON; 02779 break; 02780 case DAHDI_EVENT_RINGEROFF: 02781 res = ANALOG_EVENT_RINGEROFF; 02782 break; 02783 case DAHDI_EVENT_HOOKCOMPLETE: 02784 res = ANALOG_EVENT_HOOKCOMPLETE; 02785 break; 02786 case DAHDI_EVENT_PULSE_START: 02787 res = ANALOG_EVENT_PULSE_START; 02788 break; 02789 case DAHDI_EVENT_POLARITY: 02790 res = ANALOG_EVENT_POLARITY; 02791 break; 02792 case DAHDI_EVENT_RINGBEGIN: 02793 res = ANALOG_EVENT_RINGBEGIN; 02794 break; 02795 case DAHDI_EVENT_EC_DISABLED: 02796 res = ANALOG_EVENT_EC_DISABLED; 02797 break; 02798 case DAHDI_EVENT_REMOVED: 02799 res = ANALOG_EVENT_REMOVED; 02800 break; 02801 case DAHDI_EVENT_NEONMWI_ACTIVE: 02802 res = ANALOG_EVENT_NEONMWI_ACTIVE; 02803 break; 02804 case DAHDI_EVENT_NEONMWI_INACTIVE: 02805 res = ANALOG_EVENT_NEONMWI_INACTIVE; 02806 break; 02807 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 02808 case DAHDI_EVENT_TX_CED_DETECTED: 02809 res = ANALOG_EVENT_TX_CED_DETECTED; 02810 break; 02811 case DAHDI_EVENT_RX_CED_DETECTED: 02812 res = ANALOG_EVENT_RX_CED_DETECTED; 02813 break; 02814 case DAHDI_EVENT_EC_NLP_DISABLED: 02815 res = ANALOG_EVENT_EC_NLP_DISABLED; 02816 break; 02817 case DAHDI_EVENT_EC_NLP_ENABLED: 02818 res = ANALOG_EVENT_EC_NLP_ENABLED; 02819 break; 02820 #endif 02821 case DAHDI_EVENT_PULSEDIGIT: 02822 res = ANALOG_EVENT_PULSEDIGIT; 02823 break; 02824 case DAHDI_EVENT_DTMFDOWN: 02825 res = ANALOG_EVENT_DTMFDOWN; 02826 break; 02827 case DAHDI_EVENT_DTMFUP: 02828 res = ANALOG_EVENT_DTMFUP; 02829 break; 02830 default: 02831 switch(event & 0xFFFF0000) { 02832 case DAHDI_EVENT_PULSEDIGIT: 02833 case DAHDI_EVENT_DTMFDOWN: 02834 case DAHDI_EVENT_DTMFUP: 02835 /* The event includes a digit number in the low word. 02836 * Converting it to a 'enum analog_event' would remove 02837 * that information. Thus it is returned as-is. 02838 */ 02839 return event; 02840 } 02841 02842 res = ANALOG_EVENT_ERROR; 02843 break; 02844 } 02845 02846 return res; 02847 }
| static enum analog_sigtype dahdisig_to_analogsig | ( | int | sig | ) | [static] |
Definition at line 1583 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().
01584 { 01585 switch (sig) { 01586 case SIG_FXOLS: 01587 return ANALOG_SIG_FXOLS; 01588 case SIG_FXOGS: 01589 return ANALOG_SIG_FXOGS; 01590 case SIG_FXOKS: 01591 return ANALOG_SIG_FXOKS; 01592 case SIG_FXSLS: 01593 return ANALOG_SIG_FXSLS; 01594 case SIG_FXSGS: 01595 return ANALOG_SIG_FXSGS; 01596 case SIG_FXSKS: 01597 return ANALOG_SIG_FXSKS; 01598 case SIG_EMWINK: 01599 return ANALOG_SIG_EMWINK; 01600 case SIG_EM: 01601 return ANALOG_SIG_EM; 01602 case SIG_EM_E1: 01603 return ANALOG_SIG_EM_E1; 01604 case SIG_FEATD: 01605 return ANALOG_SIG_FEATD; 01606 case SIG_FEATDMF: 01607 return ANALOG_SIG_FEATDMF; 01608 case SIG_E911: 01609 return SIG_E911; 01610 case SIG_FGC_CAMA: 01611 return ANALOG_SIG_FGC_CAMA; 01612 case SIG_FGC_CAMAMF: 01613 return ANALOG_SIG_FGC_CAMAMF; 01614 case SIG_FEATB: 01615 return ANALOG_SIG_FEATB; 01616 case SIG_SFWINK: 01617 return ANALOG_SIG_SFWINK; 01618 case SIG_SF: 01619 return ANALOG_SIG_SF; 01620 case SIG_SF_FEATD: 01621 return ANALOG_SIG_SF_FEATD; 01622 case SIG_SF_FEATDMF: 01623 return ANALOG_SIG_SF_FEATDMF; 01624 case SIG_FEATDMF_TA: 01625 return ANALOG_SIG_FEATDMF_TA; 01626 case SIG_SF_FEATB: 01627 return ANALOG_SIG_FEATB; 01628 default: 01629 return -1; 01630 } 01631 }
| static void deep_copy_dahdi_chan_conf | ( | struct dahdi_chan_conf * | dest, | |
| const struct dahdi_chan_conf * | src | |||
| ) | [static] |
Definition at line 18311 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().
18312 { 18313 struct ast_cc_config_params *cc_params; 18314 18315 cc_params = dest->chan.cc_params; 18316 *dest = *src; 18317 dest->chan.cc_params = cc_params; 18318 ast_cc_copy_config_params(dest->chan.cc_params, src->chan.cc_params); 18319 }
| static void destroy_all_channels | ( | void | ) | [static] |
Definition at line 5852 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(), iflock, 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().
05853 { 05854 int chan; 05855 #if defined(HAVE_PRI) 05856 unsigned span; 05857 struct sig_pri_span *pri; 05858 #endif /* defined(HAVE_PRI) */ 05859 struct dahdi_pvt *p; 05860 05861 while (num_restart_pending) { 05862 usleep(1); 05863 } 05864 05865 ast_mutex_lock(&iflock); 05866 /* Destroy all the interfaces and free their memory */ 05867 while (iflist) { 05868 p = iflist; 05869 05870 chan = p->channel; 05871 #if defined(HAVE_PRI_SERVICE_MESSAGES) 05872 { 05873 char db_chan_name[20]; 05874 char db_answer[5]; 05875 char state; 05876 int why = -1; 05877 05878 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, p->span, chan); 05879 if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) { 05880 sscanf(db_answer, "%1c:%30d", &state, &why); 05881 } 05882 if (!why) { 05883 /* SRVST persistence is not required */ 05884 ast_db_del(db_chan_name, SRVST_DBKEY); 05885 } 05886 } 05887 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 05888 /* Free associated memory */ 05889 destroy_dahdi_pvt(p); 05890 ast_verb(3, "Unregistered channel %d\n", chan); 05891 } 05892 ifcount = 0; 05893 ast_mutex_unlock(&iflock); 05894 05895 #if defined(HAVE_PRI) 05896 /* Destroy all of the no B channel interface lists */ 05897 for (span = 0; span < NUM_SPANS; ++span) { 05898 if (!pris[span].dchannels[0]) { 05899 break; 05900 } 05901 pri = &pris[span].pri; 05902 ast_mutex_lock(&pri->lock); 05903 while (pri->no_b_chan_iflist) { 05904 p = pri->no_b_chan_iflist; 05905 05906 /* Free associated memory */ 05907 destroy_dahdi_pvt(p); 05908 } 05909 ast_mutex_unlock(&pri->lock); 05910 } 05911 #endif /* defined(HAVE_PRI) */ 05912 }
| static void destroy_channel | ( | struct dahdi_pvt * | cur, | |
| int | now | |||
| ) | [static] |
Definition at line 5834 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().
05835 { 05836 int i; 05837 05838 if (!now) { 05839 /* Do not destroy the channel now if it is owned by someone. */ 05840 if (cur->owner) { 05841 return; 05842 } 05843 for (i = 0; i < 3; i++) { 05844 if (cur->subs[i].owner) { 05845 return; 05846 } 05847 } 05848 } 05849 destroy_dahdi_pvt(cur); 05850 }
| static void destroy_dahdi_pvt | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 5764 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().
05765 { 05766 struct dahdi_pvt *p = pvt; 05767 05768 if (p->manages_span_alarms) { 05769 struct dahdi_pvt *next = find_next_iface_in_span(p); 05770 if (next) { 05771 next->manages_span_alarms = 1; 05772 } 05773 } 05774 05775 /* Remove channel from the list */ 05776 #if defined(HAVE_PRI) 05777 dahdi_unlink_pri_pvt(p); 05778 #endif /* defined(HAVE_PRI) */ 05779 #if defined(HAVE_SS7) 05780 dahdi_unlink_ss7_pvt(p); 05781 #endif /* defined(HAVE_SS7) */ 05782 switch (pvt->which_iflist) { 05783 case DAHDI_IFLIST_NONE: 05784 break; 05785 case DAHDI_IFLIST_MAIN: 05786 dahdi_iflist_extract(p); 05787 break; 05788 #if defined(HAVE_PRI) 05789 case DAHDI_IFLIST_NO_B_CHAN: 05790 if (p->pri) { 05791 dahdi_nobch_extract(p->pri, p); 05792 } 05793 break; 05794 #endif /* defined(HAVE_PRI) */ 05795 } 05796 05797 if (p->sig_pvt) { 05798 if (analog_lib_handles(p->sig, 0, 0)) { 05799 analog_delete(p->sig_pvt); 05800 } 05801 switch (p->sig) { 05802 #if defined(HAVE_PRI) 05803 case SIG_PRI_LIB_HANDLE_CASES: 05804 sig_pri_chan_delete(p->sig_pvt); 05805 break; 05806 #endif /* defined(HAVE_PRI) */ 05807 #if defined(HAVE_SS7) 05808 case SIG_SS7: 05809 sig_ss7_chan_delete(p->sig_pvt); 05810 break; 05811 #endif /* defined(HAVE_SS7) */ 05812 default: 05813 break; 05814 } 05815 } 05816 ast_free(p->cidspill); 05817 if (p->use_smdi) 05818 ast_smdi_interface_unref(p->smdi_iface); 05819 if (p->mwi_event_sub) 05820 ast_event_unsubscribe(p->mwi_event_sub); 05821 if (p->vars) { 05822 ast_variables_destroy(p->vars); 05823 } 05824 if (p->cc_params) { 05825 ast_cc_config_params_destroy(p->cc_params); 05826 } 05827 ast_mutex_destroy(&p->lock); 05828 dahdi_close_sub(p, SUB_REAL); 05829 if (p->owner) 05830 p->owner->tech_pvt = NULL; 05831 ast_free(p); 05832 }
| static struct dahdi_pvt* determine_starting_point | ( | const char * | data, | |
| struct dahdi_starting_point * | param | |||
| ) | [static, read] |
Definition at line 13494 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().
13495 { 13496 char *dest; 13497 char *s; 13498 int x; 13499 int res = 0; 13500 struct dahdi_pvt *p; 13501 char *subdir = NULL; 13502 AST_DECLARE_APP_ARGS(args, 13503 AST_APP_ARG(group); /* channel/group token */ 13504 //AST_APP_ARG(ext); /* extension token */ 13505 //AST_APP_ARG(opts); /* options token */ 13506 AST_APP_ARG(other); /* Any remining unused arguments */ 13507 ); 13508 13509 /* 13510 * data is ---v 13511 * Dial(DAHDI/pseudo[/extension[/options]]) 13512 * Dial(DAHDI/<channel#>[c|r<cadance#>|d][/extension[/options]]) 13513 * Dial(DAHDI/<subdir>!<channel#>[c|r<cadance#>|d][/extension[/options]]) 13514 * Dial(DAHDI/i<span>[/extension[/options]]) 13515 * Dial(DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]) 13516 * 13517 * i - ISDN span channel restriction. 13518 * Used by CC to ensure that the CC recall goes out the same span. 13519 * Also to make ISDN channel names dialable when the sequence number 13520 * is stripped off. (Used by DTMF attended transfer feature.) 13521 * 13522 * g - channel group allocation search forward 13523 * G - channel group allocation search backward 13524 * r - channel group allocation round robin search forward 13525 * R - channel group allocation round robin search backward 13526 * 13527 * c - Wait for DTMF digit to confirm answer 13528 * r<cadance#> - Set distintive ring cadance number 13529 * d - Force bearer capability for ISDN/SS7 call to digital. 13530 */ 13531 13532 if (data) { 13533 dest = ast_strdupa(data); 13534 } else { 13535 ast_log(LOG_WARNING, "Channel requested with no data\n"); 13536 return NULL; 13537 } 13538 AST_NONSTANDARD_APP_ARGS(args, dest, '/'); 13539 if (!args.argc || ast_strlen_zero(args.group)) { 13540 ast_log(LOG_WARNING, "No channel/group specified\n"); 13541 return NULL; 13542 } 13543 13544 /* Initialize the output parameters */ 13545 memset(param, 0, sizeof(*param)); 13546 param->channelmatch = -1; 13547 13548 if (strchr(args.group, '!') != NULL) { 13549 char *prev = args.group; 13550 while ((s = strchr(prev, '!')) != NULL) { 13551 *s++ = '/'; 13552 prev = s; 13553 } 13554 *(prev - 1) = '\0'; 13555 subdir = args.group; 13556 args.group = prev; 13557 } else if (args.group[0] == 'i') { 13558 /* Extract the ISDN span channel restriction specifier. */ 13559 res = sscanf(args.group + 1, "%30d", &x); 13560 if (res < 1) { 13561 ast_log(LOG_WARNING, "Unable to determine ISDN span for data %s\n", data); 13562 return NULL; 13563 } 13564 param->span = x; 13565 13566 /* Remove the ISDN span channel restriction specifier. */ 13567 s = strchr(args.group, '-'); 13568 if (!s) { 13569 /* Search all groups since we are ISDN span restricted. */ 13570 return iflist; 13571 } 13572 args.group = s + 1; 13573 res = 0; 13574 } 13575 if (toupper(args.group[0]) == 'G' || toupper(args.group[0])=='R') { 13576 /* Retrieve the group number */ 13577 s = args.group + 1; 13578 res = sscanf(s, "%30d%1c%30d", &x, ¶m->opt, ¶m->cadance); 13579 if (res < 1) { 13580 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", data); 13581 return NULL; 13582 } 13583 param->groupmatch = ((ast_group_t) 1 << x); 13584 13585 if (toupper(args.group[0]) == 'G') { 13586 if (args.group[0] == 'G') { 13587 param->backwards = 1; 13588 p = ifend; 13589 } else 13590 p = iflist; 13591 } else { 13592 if (ARRAY_LEN(round_robin) <= x) { 13593 ast_log(LOG_WARNING, "Round robin index %d out of range for data %s\n", 13594 x, data); 13595 return NULL; 13596 } 13597 if (args.group[0] == 'R') { 13598 param->backwards = 1; 13599 p = round_robin[x] ? round_robin[x]->prev : ifend; 13600 if (!p) 13601 p = ifend; 13602 } else { 13603 p = round_robin[x] ? round_robin[x]->next : iflist; 13604 if (!p) 13605 p = iflist; 13606 } 13607 param->roundrobin = 1; 13608 param->rr_starting_point = x; 13609 } 13610 } else { 13611 s = args.group; 13612 if (!strcasecmp(s, "pseudo")) { 13613 /* Special case for pseudo */ 13614 x = CHAN_PSEUDO; 13615 param->channelmatch = x; 13616 } else { 13617 res = sscanf(s, "%30d%1c%30d", &x, ¶m->opt, ¶m->cadance); 13618 if (res < 1) { 13619 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", data); 13620 return NULL; 13621 } else { 13622 param->channelmatch = x; 13623 } 13624 } 13625 if (subdir) { 13626 char path[PATH_MAX]; 13627 struct stat stbuf; 13628 13629 snprintf(path, sizeof(path), "/dev/dahdi/%s/%d", 13630 subdir, param->channelmatch); 13631 if (stat(path, &stbuf) < 0) { 13632 ast_log(LOG_WARNING, "stat(%s) failed: %s\n", 13633 path, strerror(errno)); 13634 return NULL; 13635 } 13636 if (!S_ISCHR(stbuf.st_mode)) { 13637 ast_log(LOG_ERROR, "%s: Not a character device file\n", 13638 path); 13639 return NULL; 13640 } 13641 param->channelmatch = minor(stbuf.st_rdev); 13642 } 13643 13644 p = iflist; 13645 } 13646 13647 if (param->opt == 'r' && res < 3) { 13648 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", data); 13649 param->opt = '\0'; 13650 } 13651 13652 return p; 13653 }
| static int device2chan | ( | const char * | subdir, | |
| int | channel, | |||
| char * | path, | |||
| int | pathlen | |||
| ) | [static] |
Definition at line 12259 of file chan_dahdi.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by build_channels().
12260 { 12261 struct stat stbuf; 12262 int num; 12263 12264 snprintf(path, pathlen, "/dev/dahdi/%s/%d", subdir, channel); 12265 if (stat(path, &stbuf) < 0) { 12266 ast_log(LOG_ERROR, "stat(%s) failed: %s\n", path, strerror(errno)); 12267 return -errno; 12268 } 12269 if (!S_ISCHR(stbuf.st_mode)) { 12270 ast_log(LOG_ERROR, "%s: Not a character device file\n", path); 12271 return -EINVAL; 12272 } 12273 num = minor(stbuf.st_rdev); 12274 ast_debug(1, "%s -> %d\n", path, num); 12275 return num; 12276 12277 }
| static int digit_to_dtmfindex | ( | char | digit | ) | [static] |
Definition at line 4438 of file chan_dahdi.c.
Referenced by dahdi_digit_begin().
04439 { 04440 if (isdigit(digit)) 04441 return DAHDI_TONE_DTMF_BASE + (digit - '0'); 04442 else if (digit >= 'A' && digit <= 'D') 04443 return DAHDI_TONE_DTMF_A + (digit - 'A'); 04444 else if (digit >= 'a' && digit <= 'd') 04445 return DAHDI_TONE_DTMF_A + (digit - 'a'); 04446 else if (digit == '*') 04447 return DAHDI_TONE_DTMF_s; 04448 else if (digit == '#') 04449 return DAHDI_TONE_DTMF_p; 04450 else 04451 return -1; 04452 }
| static void disable_dtmf_detect | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 6655 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().
06656 { 06657 int val = 0; 06658 06659 p->ignoredtmf = 1; 06660 06661 ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val); 06662 06663 if (!p->hardwaredtmf && p->dsp) { 06664 p->dsp_features &= ~DSP_FEATURE_DIGIT_DETECT; 06665 ast_dsp_set_features(p->dsp, p->dsp_features); 06666 } 06667 }
| static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 11676 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_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(), iflock, last, mwi_thread_data::len, dahdi_pvt::lock, LOG_ERROR, LOG_WARNING, dahdi_pvt::mailbox, 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().
11677 { 11678 int count, res, res2, spoint, pollres=0; 11679 struct dahdi_pvt *i; 11680 struct dahdi_pvt *last = NULL; 11681 struct dahdi_pvt *doomed; 11682 time_t thispass = 0, lastpass = 0; 11683 int found; 11684 char buf[1024]; 11685 struct pollfd *pfds=NULL; 11686 int lastalloc = -1; 11687 /* This thread monitors all the frame relay interfaces which are not yet in use 11688 (and thus do not have a separate thread) indefinitely */ 11689 /* From here on out, we die whenever asked */ 11690 #if 0 11691 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) { 11692 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n"); 11693 return NULL; 11694 } 11695 ast_debug(1, "Monitor starting...\n"); 11696 #endif 11697 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 11698 11699 for (;;) { 11700 /* Lock the interface list */ 11701 ast_mutex_lock(&iflock); 11702 if (!pfds || (lastalloc != ifcount)) { 11703 if (pfds) { 11704 ast_free(pfds); 11705 pfds = NULL; 11706 } 11707 if (ifcount) { 11708 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) { 11709 ast_mutex_unlock(&iflock); 11710 return NULL; 11711 } 11712 } 11713 lastalloc = ifcount; 11714 } 11715 /* Build the stuff we're going to poll on, that is the socket of every 11716 dahdi_pvt that does not have an associated owner channel */ 11717 count = 0; 11718 for (i = iflist; i; i = i->next) { 11719 ast_mutex_lock(&i->lock); 11720 if ((i->subs[SUB_REAL].dfd > -1) && i->sig && (!i->radio) && !(i->sig & SIG_MFCR2)) { 11721 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) { 11722 struct analog_pvt *p = i->sig_pvt; 11723 11724 if (!p) 11725 ast_log(LOG_ERROR, "No sig_pvt?\n"); 11726 11727 if (!p->owner && !p->subs[SUB_REAL].owner) { 11728 /* This needs to be watched, as it lacks an owner */ 11729 pfds[count].fd = i->subs[SUB_REAL].dfd; 11730 pfds[count].events = POLLPRI; 11731 pfds[count].revents = 0; 11732 /* Message waiting or r2 channels also get watched for reading */ 11733 if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk || 11734 (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) { 11735 pfds[count].events |= POLLIN; 11736 } 11737 count++; 11738 } 11739 } else { 11740 if (!i->owner && !i->subs[SUB_REAL].owner && !i->mwimonitoractive ) { 11741 /* This needs to be watched, as it lacks an owner */ 11742 pfds[count].fd = i->subs[SUB_REAL].dfd; 11743 pfds[count].events = POLLPRI; 11744 pfds[count].revents = 0; 11745 /* If we are monitoring for VMWI or sending CID, we need to 11746 read from the channel as well */ 11747 if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk || 11748 (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) { 11749 pfds[count].events |= POLLIN; 11750 } 11751 count++; 11752 } 11753 } 11754 } 11755 ast_mutex_unlock(&i->lock); 11756 } 11757 /* Okay, now that we know what to do, release the interface lock */ 11758 ast_mutex_unlock(&iflock); 11759 11760 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 11761 pthread_testcancel(); 11762 /* Wait at least a second for something to happen */ 11763 res = poll(pfds, count, 1000); 11764 pthread_testcancel(); 11765 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 11766 11767 /* Okay, poll has finished. Let's see what happened. */ 11768 if (res < 0) { 11769 if ((errno != EAGAIN) && (errno != EINTR)) 11770 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno)); 11771 continue; 11772 } 11773 /* Alright, lock the interface list again, and let's look and see what has 11774 happened */ 11775 ast_mutex_lock(&iflock); 11776 found = 0; 11777 spoint = 0; 11778 lastpass = thispass; 11779 thispass = time(NULL); 11780 doomed = NULL; 11781 for (i = iflist;; i = i->next) { 11782 if (doomed) { 11783 int res; 11784 res = dahdi_destroy_channel_bynum(doomed->channel); 11785 if (res != RESULT_SUCCESS) { 11786 ast_log(LOG_WARNING, "Couldn't find channel to destroy, hopefully another destroy operation just happened.\n"); 11787 } 11788 doomed = NULL; 11789 } 11790 if (!i) { 11791 break; 11792 } 11793 11794 if (thispass != lastpass) { 11795 if (!found && ((i == last) || ((i == iflist) && !last))) { 11796 last = i; 11797 if (last) { 11798 struct analog_pvt *analog_p = last->sig_pvt; 11799 /* Only allow MWI to be initiated on a quiescent fxs port */ 11800 if (analog_p 11801 && !last->mwisendactive 11802 && (last->sig & __DAHDI_SIG_FXO) 11803 && !analog_p->fxsoffhookstate 11804 && !last->owner 11805 && !ast_strlen_zero(last->mailbox) 11806 && (thispass - analog_p->onhooktime > 3)) { 11807 res = has_voicemail(last); 11808 if (analog_p->msgstate != res) { 11809 /* Set driver resources for signalling VMWI */ 11810 res2 = ioctl(last->subs[SUB_REAL].dfd, DAHDI_VMWI, &res); 11811 if (res2) { 11812 /* TODO: This message will ALWAYS be generated on some cards; any way to restrict it to those cards where it is interesting? */ 11813 ast_debug(3, "Unable to control message waiting led on channel %d: %s\n", last->channel, strerror(errno)); 11814 } 11815 /* If enabled for FSK spill then initiate it */ 11816 if (mwi_send_init(last)) { 11817 ast_log(LOG_WARNING, "Unable to initiate mwi send sequence on channel %d\n", last->channel); 11818 } 11819 analog_p->msgstate = res; 11820 found ++; 11821 } 11822 } 11823 last = last->next; 11824 } 11825 } 11826 } 11827 if ((i->subs[SUB_REAL].dfd > -1) && i->sig) { 11828 if (i->radio && !i->owner) 11829 { 11830 res = dahdi_get_event(i->subs[SUB_REAL].dfd); 11831 if (res) 11832 { 11833 ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel); 11834 /* Don't hold iflock while handling init events */ 11835 ast_mutex_unlock(&iflock); 11836 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) 11837 doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res)); 11838 else 11839 doomed = handle_init_event(i, res); 11840 ast_mutex_lock(&iflock); 11841 } 11842 continue; 11843 } 11844 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].dfd, count, &spoint); 11845 if (pollres & POLLIN) { 11846 if (i->owner || i->subs[SUB_REAL].owner) { 11847 #ifdef HAVE_PRI 11848 if (!i->pri) 11849 #endif 11850 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd); 11851 continue; 11852 } 11853 if (!i->mwimonitor_fsk && !i->mwisendactive && i->cid_start != CID_START_DTMF_NOALERT) { 11854 ast_log(LOG_WARNING, "Whoa.... I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd); 11855 continue; 11856 } 11857 res = read(i->subs[SUB_REAL].dfd, buf, sizeof(buf)); 11858 if (res > 0) { 11859 if (i->mwimonitor_fsk) { 11860 if (calc_energy((unsigned char *) buf, res, AST_LAW(i)) > mwilevel) { 11861 pthread_attr_t attr; 11862 pthread_t threadid; 11863 struct mwi_thread_data *mtd; 11864 11865 pthread_attr_init(&attr); 11866 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 11867 11868 ast_debug(1, "Maybe some MWI on port %d!\n", i->channel); 11869 if ((mtd = ast_calloc(1, sizeof(*mtd)))) { 11870 mtd->pvt = i; 11871 memcpy(mtd->buf, buf, res); 11872 mtd->len = res; 11873 if (ast_pthread_create_background(&threadid, &attr, mwi_thread, mtd)) { 11874 ast_log(LOG_WARNING, "Unable to start mwi thread on channel %d\n", i->channel); 11875 ast_free(mtd); 11876 } 11877 i->mwimonitoractive = 1; 11878 } 11879 } 11880 /* If configured to check for a DTMF CID spill that comes without alert (e.g no polarity reversal) */ 11881 } else if (i->cid_start == CID_START_DTMF_NOALERT) { 11882 int energy; 11883 struct timeval now; 11884 /* State machine dtmfcid_holdoff_state allows for the line to settle 11885 * before checking agin for dtmf energy. Presently waits for 500 mS before checking again 11886 */ 11887 if (1 == i->dtmfcid_holdoff_state) { 11888 gettimeofday(&i->dtmfcid_delay, NULL); 11889 i->dtmfcid_holdoff_state = 2; 11890 } else if (2 == i->dtmfcid_holdoff_state) { 11891 gettimeofday(&now, NULL); 11892 if ((int)(now.tv_sec - i->dtmfcid_delay.tv_sec) * 1000000 + (int)now.tv_usec - (int)i->dtmfcid_delay.tv_usec > 500000) { 11893 i->dtmfcid_holdoff_state = 0; 11894 } 11895 } else { 11896 energy = calc_energy((unsigned char *) buf, res, AST_LAW(i)); 11897 if (!i->mwisendactive && energy > dtmfcid_level) { 11898 pthread_t threadid; 11899 struct ast_channel *chan; 11900 ast_mutex_unlock(&iflock); 11901 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) { 11902 /* just in case this event changes or somehow destroys a channel, set doomed here too */ 11903 doomed = analog_handle_init_event(i->sig_pvt, ANALOG_EVENT_DTMFCID); 11904 i->dtmfcid_holdoff_state = 1; 11905 } else { 11906 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11907 if (!chan) { 11908 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11909 } else { 11910 res = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan); 11911 if (res) { 11912 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11913 } else { 11914 i->dtmfcid_holdoff_state = 1; 11915 } 11916 } 11917 } 11918 ast_mutex_lock(&iflock); 11919 } 11920 } 11921 } 11922 if (i->mwisendactive) { 11923 mwi_send_process_buffer(i, res); 11924 } 11925 } else { 11926 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno)); 11927 } 11928 } 11929 if (pollres & POLLPRI) { 11930 if (i->owner || i->subs[SUB_REAL].owner) { 11931 #ifdef HAVE_PRI 11932 if (!i->pri) 11933 #endif 11934 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].dfd); 11935 continue; 11936 } 11937 res = dahdi_get_event(i->subs[SUB_REAL].dfd); 11938 ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel); 11939 /* Don't hold iflock while handling init events */ 11940 ast_mutex_unlock(&iflock); 11941 if (0 == i->mwisendactive || 0 == mwi_send_process_event(i, res)) { 11942 if (analog_lib_handles(i->sig, i->radio, i->oprmode)) 11943 doomed = (struct dahdi_pvt *) analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(res)); 11944 else 11945 doomed = handle_init_event(i, res); 11946 } 11947 ast_mutex_lock(&iflock); 11948 } 11949 } 11950 } 11951 ast_mutex_unlock(&iflock); 11952 } 11953 /* Never reached */ 11954 return NULL; 11955 11956 }
| static int drc_sample | ( | int | sample, | |
| float | drc | |||
| ) | [static] |
Definition at line 4977 of file chan_dahdi.c.
Referenced by fill_rxgain(), and fill_txgain().
04978 { 04979 float neg; 04980 float shallow, steep; 04981 float max = SHRT_MAX; 04982 04983 neg = (sample < 0 ? -1 : 1); 04984 steep = drc*sample; 04985 shallow = neg*(max-max/drc)+(float)sample/drc; 04986 if (abs(steep) < abs(shallow)) { 04987 sample = steep; 04988 } 04989 else { 04990 sample = shallow; 04991 } 04992 04993 return sample; 04994 }
Definition at line 13430 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().
13431 { 13432 struct dahdi_pvt *p; 13433 struct dahdi_bufferinfo bi; 13434 int res; 13435 13436 p = ast_malloc(sizeof(*p)); 13437 if (!p) { 13438 return NULL; 13439 } 13440 *p = *src; 13441 13442 /* Must deep copy the cc_params. */ 13443 p->cc_params = ast_cc_config_params_init(); 13444 if (!p->cc_params) { 13445 ast_free(p); 13446 return NULL; 13447 } 13448 ast_cc_copy_config_params(p->cc_params, src->cc_params); 13449 13450 p->which_iflist = DAHDI_IFLIST_NONE; 13451 p->next = NULL; 13452 p->prev = NULL; 13453 ast_mutex_init(&p->lock); 13454 p->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo"); 13455 if (p->subs[SUB_REAL].dfd < 0) { 13456 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno)); 13457 destroy_dahdi_pvt(p); 13458 return NULL; 13459 } 13460 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi); 13461 if (!res) { 13462 bi.txbufpolicy = src->buf_policy; 13463 bi.rxbufpolicy = src->buf_policy; 13464 bi.numbufs = src->buf_no; 13465 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi); 13466 if (res < 0) { 13467 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel: %s\n", strerror(errno)); 13468 } 13469 } else 13470 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel: %s\n", strerror(errno)); 13471 p->destroy = 1; 13472 dahdi_iflist_insert(p); 13473 return p; 13474 }
| static void enable_dtmf_detect | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 6669 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().
06670 { 06671 int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE; 06672 06673 if (p->channel == CHAN_PSEUDO) 06674 return; 06675 06676 p->ignoredtmf = 0; 06677 06678 ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val); 06679 06680 if (!p->hardwaredtmf && p->dsp) { 06681 p->dsp_features |= DSP_FEATURE_DIGIT_DETECT; 06682 ast_dsp_set_features(p->dsp, p->dsp_features); 06683 } 06684 }
| static const char * event2str | ( | int | event | ) | [static] |
Definition at line 4590 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().
04591 { 04592 static char buf[256]; 04593 if ((event < (ARRAY_LEN(events))) && (event > -1)) 04594 return events[event]; 04595 sprintf(buf, "Event %d", event); /* safe */ 04596 return buf; 04597 }
| static void fill_rxgain | ( | struct dahdi_gains * | g, | |
| float | gain, | |||
| float | drc, | |||
| int | law | |||
| ) | [static] |
Definition at line 5041 of file chan_dahdi.c.
References ARRAY_LEN, AST_ALAW, AST_LIN2A, AST_LIN2MU, AST_MULAW, and drc_sample().
Referenced by set_actual_rxgain().
05042 { 05043 int j; 05044 int k; 05045 float linear_gain = pow(10.0, gain / 20.0); 05046 05047 switch (law) { 05048 case DAHDI_LAW_ALAW: 05049 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) { 05050 if (gain || drc) { 05051 k = AST_ALAW(j); 05052 if (drc) { 05053 k = drc_sample(k, drc); 05054 } 05055 k = (float)k*linear_gain; 05056 if (k > 32767) k = 32767; 05057 if (k < -32767) k = -32767; 05058 g->rxgain[j] = AST_LIN2A(k); 05059 } else { 05060 g->rxgain[j] = j; 05061 } 05062 } 05063 break; 05064 case DAHDI_LAW_MULAW: 05065 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) { 05066 if (gain || drc) { 05067 k = AST_MULAW(j); 05068 if (drc) { 05069 k = drc_sample(k, drc); 05070 } 05071 k = (float)k*linear_gain; 05072 if (k > 32767) k = 32767; 05073 if (k < -32767) k = -32767; 05074 g->rxgain[j] = AST_LIN2MU(k); 05075 } else { 05076 g->rxgain[j] = j; 05077 } 05078 } 05079 break; 05080 } 05081 }
| static void fill_txgain | ( | struct dahdi_gains * | g, | |
| float | gain, | |||
| float | drc, | |||
| int | law | |||
| ) | [static] |
Definition at line 4997 of file chan_dahdi.c.
References ARRAY_LEN, AST_ALAW, AST_LIN2A, AST_LIN2MU, AST_MULAW, and drc_sample().
Referenced by set_actual_txgain().
04998 { 04999 int j; 05000 int k; 05001 05002 float linear_gain = pow(10.0, gain / 20.0); 05003 05004 switch (law) { 05005 case DAHDI_LAW_ALAW: 05006 for (j = 0; j < ARRAY_LEN(g->txgain); j++) { 05007 if (gain || drc) { 05008 k = AST_ALAW(j); 05009 if (drc) { 05010 k = drc_sample(k, drc); 05011 } 05012 k = (float)k*linear_gain; 05013 if (k > 32767) k = 32767; 05014 if (k < -32767) k = -32767; 05015 g->txgain[j] = AST_LIN2A(k); 05016 } else { 05017 g->txgain[j] = j; 05018 } 05019 } 05020 break; 05021 case DAHDI_LAW_MULAW: 05022 for (j = 0; j < ARRAY_LEN(g->txgain); j++) { 05023 if (gain || drc) { 05024 k = AST_MULAW(j); 05025 if (drc) { 05026 k = drc_sample(k, drc); 05027 } 05028 k = (float)k*linear_gain; 05029 if (k > 32767) k = 32767; 05030 if (k < -32767) k = -32767; 05031 g->txgain[j] = AST_LIN2MU(k); 05032 05033 } else { 05034 g->txgain[j] = j; 05035 } 05036 } 05037 break; 05038 } 05039 }
| static struct dahdi_pvt* find_channel | ( | int | channel | ) | [static, read] |
Definition at line 15899 of file chan_dahdi.c.
References ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, iflock, and dahdi_pvt::next.
Referenced by find_channel_from_str().
15900 { 15901 struct dahdi_pvt *p; 15902 15903 ast_mutex_lock(&iflock); 15904 for (p = iflist; p; p = p->next) { 15905 if (p->channel == channel) { 15906 break; 15907 } 15908 } 15909 ast_mutex_unlock(&iflock); 15910 return p; 15911 }
| static struct dahdi_pvt* find_channel_from_str | ( | const char * | channel | ) | [static, read] |
Definition at line 15922 of file chan_dahdi.c.
References find_channel().
Referenced by action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_transfer(), and action_transferhangup().
15923 { 15924 int chan_num; 15925 15926 if (sscanf(channel, "%30d", &chan_num) != 1) { 15927 /* Not numeric string. */ 15928 return NULL; 15929 } 15930 15931 return find_channel(chan_num); 15932 }
Definition at line 5753 of file chan_dahdi.c.
References dahdi_pvt::next, dahdi_pvt::prev, and dahdi_pvt::span.
Referenced by destroy_dahdi_pvt().
05754 { 05755 if (cur->next && cur->next->span == cur->span) { 05756 return cur->next; 05757 } else if (cur->prev && cur->prev->span == cur->span) { 05758 return cur->prev; 05759 } 05760 05761 return NULL; 05762 }
| static int get_alarms | ( | struct dahdi_pvt * | p | ) | [static] |
Checks channel for alarms
| p | a channel to check for alarms. |
Definition at line 7755 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().
07756 { 07757 int res; 07758 struct dahdi_spaninfo zi; 07759 struct dahdi_params params; 07760 07761 memset(&zi, 0, sizeof(zi)); 07762 zi.spanno = p->span; 07763 07764 if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SPANSTAT, &zi)) >= 0) { 07765 if (zi.alarms != DAHDI_ALARM_NONE) 07766 return zi.alarms; 07767 } else { 07768 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d: %s\n", p->channel, strerror(errno)); 07769 return 0; 07770 } 07771 07772 /* No alarms on the span. Check for channel alarms. */ 07773 memset(¶ms, 0, sizeof(params)); 07774 if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, ¶ms)) >= 0) 07775 return params.chan_alarms; 07776 07777 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel); 07778 07779 return DAHDI_ALARM_NONE; 07780 }
| static void handle_alarms | ( | struct dahdi_pvt * | p, | |
| int | alms | |||
| ) | [static] |
Definition at line 7880 of file chan_dahdi.c.
References alarm2str(), ast_log(), dahdi_pvt::channel, EVENT_FLAG_SYSTEM, LOG_WARNING, manager_event, dahdi_pvt::manages_span_alarms, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, and dahdi_pvt::span.
Referenced by dahdi_handle_event(), handle_init_event(), mkintf(), mwi_thread(), and my_get_and_handle_alarms().
07881 { 07882 const char *alarm_str = alarm2str(alms); 07883 07884 if (report_alarms & REPORT_CHANNEL_ALARMS) { 07885 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str); 07886 manager_event(EVENT_FLAG_SYSTEM, "Alarm", 07887 "Alarm: %s\r\n" 07888 "Channel: %d\r\n", 07889 alarm_str, p->channel); 07890 } 07891 07892 if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) { 07893 ast_log(LOG_WARNING, "Detected alarm on span %d: %s\n", p->span, alarm_str); 07894 manager_event(EVENT_FLAG_SYSTEM, "SpanAlarm", 07895 "Alarm: %s\r\n" 07896 "Span: %d\r\n", 07897 alarm_str, p->span); 07898 } 07899 }
| static void handle_clear_alarms | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 3813 of file chan_dahdi.c.
References ast_log(), dahdi_pvt::channel, EVENT_FLAG_SYSTEM, LOG_NOTICE, manager_event, dahdi_pvt::manages_span_alarms, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, and dahdi_pvt::span.
Referenced by dahdi_handle_event(), handle_init_event(), and mwi_thread().
03814 { 03815 if (report_alarms & REPORT_CHANNEL_ALARMS) { 03816 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); 03817 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel); 03818 } 03819 if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) { 03820 ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", p->span); 03821 manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear", "Span: %d\r\n", p->span); 03822 } 03823 }
| static char* handle_dahdi_show_cadences | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 15517 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.
15518 { 15519 int i, j; 15520 switch (cmd) { 15521 case CLI_INIT: 15522 e->command = "dahdi show cadences"; 15523 e->usage = 15524 "Usage: dahdi show cadences\n" 15525 " Shows all cadences currently defined\n"; 15526 return NULL; 15527 case CLI_GENERATE: 15528 return NULL; 15529 } 15530 for (i = 0; i < num_cadence; i++) { 15531 char output[1024]; 15532 char tmp[16], tmp2[64]; 15533 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1); 15534 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output)); 15535 15536 for (j = 0; j < 16; j++) { 15537 if (cadences[i].ringcadence[j] == 0) 15538 break; 15539 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]); 15540 if (cidrings[i] * 2 - 1 == j) 15541 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1); 15542 else 15543 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1); 15544 if (j != 0) 15545 strncat(output, ",", sizeof(output) - strlen(output) - 1); 15546 strncat(output, tmp2, sizeof(output) - strlen(output) - 1); 15547 } 15548 ast_cli(a->fd,"%s\n",output); 15549 } 15550 return CLI_SUCCESS; 15551 }
Definition at line 11430 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().
11431 { 11432 int res; 11433 pthread_t threadid; 11434 struct ast_channel *chan; 11435 11436 /* Handle an event on a given channel for the monitor thread. */ 11437 11438 switch (event) { 11439 case DAHDI_EVENT_NONE: 11440 case DAHDI_EVENT_BITSCHANGED: 11441 break; 11442 case DAHDI_EVENT_WINKFLASH: 11443 case DAHDI_EVENT_RINGOFFHOOK: 11444 if (i->inalarm) break; 11445 if (i->radio) break; 11446 /* Got a ring/answer. What kind of channel are we? */ 11447 switch (i->sig) { 11448 case SIG_FXOLS: 11449 case SIG_FXOGS: 11450 case SIG_FXOKS: 11451 res = dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 11452 if (res && (errno == EBUSY)) 11453 break; 11454 11455 /* Cancel VMWI spill */ 11456 ast_free(i->cidspill); 11457 i->cidspill = NULL; 11458 restore_conference(i); 11459 11460 if (i->immediate) { 11461 dahdi_enable_ec(i); 11462 /* The channel is immediately up. Start right away */ 11463 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE); 11464 chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, NULL); 11465 if (!chan) { 11466 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); 11467 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11468 if (res < 0) 11469 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11470 } 11471 } else { 11472 /* Check for callerid, digits, etc */ 11473 chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, NULL); 11474 if (chan) { 11475 if (has_voicemail(i)) 11476 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER); 11477 else 11478 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE); 11479 if (res < 0) 11480 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel); 11481 if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11482 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11483 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11484 if (res < 0) 11485 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11486 ast_hangup(chan); 11487 } 11488 } else 11489 ast_log(LOG_WARNING, "Unable to create channel\n"); 11490 } 11491 break; 11492 case SIG_FXSLS: 11493 case SIG_FXSGS: 11494 case SIG_FXSKS: 11495 i->ringt = i->ringt_base; 11496 /* Fall through */ 11497 case SIG_EMWINK: 11498 case SIG_FEATD: 11499 case SIG_FEATDMF: 11500 case SIG_FEATDMF_TA: 11501 case SIG_E911: 11502 case SIG_FGC_CAMA: 11503 case SIG_FGC_CAMAMF: 11504 case SIG_FEATB: 11505 case SIG_EM: 11506 case SIG_EM_E1: 11507 case SIG_SFWINK: 11508 case SIG_SF_FEATD: 11509 case SIG_SF_FEATDMF: 11510 case SIG_SF_FEATB: 11511 case SIG_SF: 11512 /* Check for callerid, digits, etc */ 11513 if (i->cid_start == CID_START_POLARITY_IN) { 11514 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11515 } else { 11516 chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, NULL); 11517 } 11518 11519 if (!chan) { 11520 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11521 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11522 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11523 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11524 if (res < 0) { 11525 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11526 } 11527 ast_hangup(chan); 11528 } 11529 break; 11530 default: 11531 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 11532 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11533 if (res < 0) 11534 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel); 11535 return NULL; 11536 } 11537 break; 11538 case DAHDI_EVENT_NOALARM: 11539 switch (i->sig) { 11540 #if defined(HAVE_PRI) 11541 case SIG_PRI_LIB_HANDLE_CASES: 11542 ast_mutex_lock(&i->lock); 11543 sig_pri_chan_alarm_notify(i->sig_pvt, 1); 11544 ast_mutex_unlock(&i->lock); 11545 break; 11546 #endif /* defined(HAVE_PRI) */ 11547 #if defined(HAVE_SS7) 11548 case SIG_SS7: 11549 sig_ss7_set_alarm(i->sig_pvt, 0); 11550 break; 11551 #endif /* defined(HAVE_SS7) */ 11552 default: 11553 i->inalarm = 0; 11554 break; 11555 } 11556 handle_clear_alarms(i); 11557 break; 11558 case DAHDI_EVENT_ALARM: 11559 switch (i->sig) { 11560 #if defined(HAVE_PRI) 11561 case SIG_PRI_LIB_HANDLE_CASES: 11562 ast_mutex_lock(&i->lock); 11563 sig_pri_chan_alarm_notify(i->sig_pvt, 0); 11564 ast_mutex_unlock(&i->lock); 11565 break; 11566 #endif /* defined(HAVE_PRI) */ 11567 #if defined(HAVE_SS7) 11568 case SIG_SS7: 11569 sig_ss7_set_alarm(i->sig_pvt, 1); 11570 break; 11571 #endif /* defined(HAVE_SS7) */ 11572 default: 11573 i->inalarm = 1; 11574 break; 11575 } 11576 res = get_alarms(i); 11577 handle_alarms(i, res); 11578 /* fall thru intentionally */ 11579 case DAHDI_EVENT_ONHOOK: 11580 if (i->radio) 11581 break; 11582 /* Back on hook. Hang up. */ 11583 switch (i->sig) { 11584 case SIG_FXOLS: 11585 case SIG_FXOGS: 11586 case SIG_FEATD: 11587 case SIG_FEATDMF: 11588 case SIG_FEATDMF_TA: 11589 case SIG_E911: 11590 case SIG_FGC_CAMA: 11591 case SIG_FGC_CAMAMF: 11592 case SIG_FEATB: 11593 case SIG_EM: 11594 case SIG_EM_E1: 11595 case SIG_EMWINK: 11596 case SIG_SF_FEATD: 11597 case SIG_SF_FEATDMF: 11598 case SIG_SF_FEATB: 11599 case SIG_SF: 11600 case SIG_SFWINK: 11601 case SIG_FXSLS: 11602 case SIG_FXSGS: 11603 case SIG_FXSKS: 11604 case SIG_FXOKS: 11605 dahdi_disable_ec(i); 11606 /* Diddle the battery for the zhone */ 11607 #ifdef ZHONE_HACK 11608 dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 11609 usleep(1); 11610 #endif 11611 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11612 dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 11613 break; 11614 case SIG_SS7: 11615 case SIG_PRI_LIB_HANDLE_CASES: 11616 dahdi_disable_ec(i); 11617 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11618 break; 11619 default: 11620 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel); 11621 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1); 11622 return NULL; 11623 } 11624 break; 11625 case DAHDI_EVENT_POLARITY: 11626 switch (i->sig) { 11627 case SIG_FXSLS: 11628 case SIG_FXSKS: 11629 case SIG_FXSGS: 11630 /* We have already got a PR before the channel was 11631 created, but it wasn't handled. We need polarity 11632 to be REV for remote hangup detection to work. 11633 At least in Spain */ 11634 if (i->hanguponpolarityswitch) 11635 i->polarity = POLARITY_REV; 11636 if (i->cid_start == CID_START_POLARITY || i->cid_start == CID_START_POLARITY_IN) { 11637 i->polarity = POLARITY_REV; 11638 ast_verb(2, "Starting post polarity " 11639 "CID detection on channel %d\n", 11640 i->channel); 11641 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL); 11642 if (!chan) { 11643 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); 11644 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) { 11645 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); 11646 } 11647 } 11648 break; 11649 default: 11650 ast_log(LOG_WARNING, "handle_init_event detected " 11651 "polarity reversal on non-FXO (SIG_FXS) " 11652 "interface %d\n", i->channel); 11653 } 11654 break; 11655 case DAHDI_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */ 11656 ast_log(LOG_NOTICE, 11657 "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n", 11658 i->channel); 11659 return i; 11660 case DAHDI_EVENT_NEONMWI_ACTIVE: 11661 if (i->mwimonitor_neon) { 11662 notify_message(i->mailbox, 1); 11663 ast_log(LOG_NOTICE, "NEON MWI set for channel %d, mailbox %s \n", i->channel, i->mailbox); 11664 } 11665 break; 11666 case DAHDI_EVENT_NEONMWI_INACTIVE: 11667 if (i->mwimonitor_neon) { 11668 notify_message(i->mailbox, 0); 11669 ast_log(LOG_NOTICE, "NEON MWI cleared for channel %d, mailbox %s\n", i->channel, i->mailbox); 11670 } 11671 break; 11672 } 11673 return NULL; 11674 }
| static int has_voicemail | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5262 of file chan_dahdi.c.
References ast_app_has_voicemail(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_strdupa, ast_strlen_zero(), context, dahdi_pvt::mailbox, mailbox, and strsep().
05263 { 05264 int new_msgs; 05265 struct ast_event *event; 05266 char *mailbox, *context; 05267 05268 mailbox = context = ast_strdupa(p->mailbox); 05269 strsep(&context, "@"); 05270 if (ast_strlen_zero(context)) 05271 context = "default"; 05272 05273 event = ast_event_get_cached(AST_EVENT_MWI, 05274 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 05275 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 05276 AST_EVENT_IE_END); 05277 05278 if (event) { 05279 new_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 05280 ast_event_destroy(event); 05281 } else 05282 new_msgs = ast_app_has_voicemail(p->mailbox, NULL); 05283 05284 return new_msgs; 05285 }
| 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 13189 of file chan_dahdi.c.
References dahdi_pvt::channel, dahdi_pvt::group, and dahdi_pvt::span.
Referenced by dahdi_cc_callback(), and dahdi_request().
13190 { 13191 #if defined(HAVE_PRI) 13192 if (0 < span) { 13193 /* The channel must be on the specified PRI span. */ 13194 if (!p->pri || p->pri->span != span) { 13195 return 0; 13196 } 13197 if (!groupmatch && channelmatch == -1) { 13198 /* Match any group since it only needs to be on the PRI span. */ 13199 *groupmatched = 1; 13200 return 1; 13201 } 13202 } 13203 #endif /* defined(HAVE_PRI) */ 13204 /* check group matching */ 13205 if (groupmatch) { 13206 if ((p->group & groupmatch) != groupmatch) 13207 /* Doesn't match the specified group, try the next one */ 13208 return 0; 13209 *groupmatched = 1; 13210 } 13211 /* Check to see if we have a channel match */ 13212 if (channelmatch != -1) { 13213 if (p->channel != channelmatch) 13214 /* Doesn't match the specified channel, try the next one */ 13215 return 0; 13216 *channelmatched = 1; 13217 } 13218 13219 return 1; 13220 }
| static int isourconf | ( | struct dahdi_pvt * | p, | |
| struct dahdi_subchannel * | c | |||
| ) | [static] |
Definition at line 4742 of file chan_dahdi.c.
References dahdi_pvt::channel, dahdi_pvt::confno, and dahdi_subchannel::curconf.
Referenced by conf_del().
04743 { 04744 /* If they're listening to our channel, they're ours */ 04745 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON)) 04746 return 1; 04747 /* If they're a talker on our (allocated) conference, they're ours */ 04748 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER)) 04749 return 1; 04750 return 0; 04751 }
Definition at line 4772 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().
04773 { 04774 int x; 04775 int useslavenative; 04776 struct dahdi_pvt *slave = NULL; 04777 /* Start out optimistic */ 04778 useslavenative = 1; 04779 /* Update conference state in a stateless fashion */ 04780 for (x = 0; x < 3; x++) { 04781 /* Any three-way calling makes slave native mode *definitely* out 04782 of the question */ 04783 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) 04784 useslavenative = 0; 04785 } 04786 /* If we don't have any 3-way calls, check to see if we have 04787 precisely one slave */ 04788 if (useslavenative) { 04789 for (x = 0; x < MAX_SLAVES; x++) { 04790 if (p->slaves[x]) { 04791 if (slave) { 04792 /* Whoops already have a slave! No 04793 slave native and stop right away */ 04794 slave = NULL; 04795 useslavenative = 0; 04796 break; 04797 } else { 04798 /* We have one slave so far */ 04799 slave = p->slaves[x]; 04800 } 04801 } 04802 } 04803 } 04804 /* If no slave, slave native definitely out */ 04805 if (!slave) 04806 useslavenative = 0; 04807 else if (slave->law != p->law) { 04808 useslavenative = 0; 04809 slave = NULL; 04810 } 04811 if (out) 04812 *out = slave; 04813 return useslavenative; 04814 }
| static int load_module | ( | void | ) | [static] |
Definition at line 18796 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_FORMAT_ALAW, ast_format_cap_add(), ast_format_cap_alloc(), ast_format_set(), AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, ast_register_application_xml, ast_channel_tech::capabilities, LOG_ERROR, setup_dahdi(), sig_pri_init_pri(), sig_pri_load(), and sig_ss7_init_linkset().
18797 { 18798 int res; 18799 struct ast_format tmpfmt; 18800 #if defined(HAVE_PRI) || defined(HAVE_SS7) 18801 int y; 18802 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 18803 18804 if (!(dahdi_tech.capabilities = ast_format_cap_alloc())) { 18805 return AST_MODULE_LOAD_FAILURE; 18806 } 18807 ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0)); 18808 ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0)); 18809 ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0)); 18810 18811 #ifdef HAVE_PRI 18812 memset(pris, 0, sizeof(pris)); 18813 for (y = 0; y < NUM_SPANS; y++) { 18814 sig_pri_init_pri(&pris[y].pri); 18815 } 18816 pri_set_error(dahdi_pri_error); 18817 pri_set_message(dahdi_pri_message); 18818 ast_register_application_xml(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec); 18819 #ifdef HAVE_PRI_PROG_W_CAUSE 18820 ast_register_application_xml(dahdi_send_callrerouting_facility_app, dahdi_send_callrerouting_facility_exec); 18821 #endif 18822 #if defined(HAVE_PRI_CCSS) 18823 if (ast_cc_agent_register(&dahdi_pri_cc_agent_callbacks) 18824 || ast_cc_monitor_register(&dahdi_pri_cc_monitor_callbacks)) { 18825 __unload_module(); 18826 return AST_MODULE_LOAD_FAILURE; 18827 } 18828 #endif /* defined(HAVE_PRI_CCSS) */ 18829 if (sig_pri_load( 18830 #if defined(HAVE_PRI_CCSS) 18831 dahdi_pri_cc_type 18832 #else 18833 NULL 18834 #endif /* defined(HAVE_PRI_CCSS) */ 18835 )) { 18836 __unload_module(); 18837 return AST_MODULE_LOAD_FAILURE; 18838 } 18839 #endif 18840 #if defined(HAVE_SS7) 18841 memset(linksets, 0, sizeof(linksets)); 18842 for (y = 0; y < NUM_SPANS; y++) { 18843 sig_ss7_init_linkset(&linksets[y].ss7); 18844 } 18845 ss7_set_error(dahdi_ss7_error); 18846 ss7_set_message(dahdi_ss7_message); 18847 #endif /* defined(HAVE_SS7) */ 18848 res = setup_dahdi(0); 18849 /* Make sure we can register our DAHDI channel type */ 18850 if (res) 18851 return AST_MODULE_LOAD_DECLINE; 18852 if (ast_channel_register(&dahdi_tech)) { 18853 ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n"); 18854 __unload_module(); 18855 return AST_MODULE_LOAD_FAILURE; 18856 } 18857 #ifdef HAVE_PRI 18858 ast_cli_register_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli)); 18859 #endif 18860 #if defined(HAVE_SS7) 18861 ast_cli_register_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli)); 18862 #endif /* defined(HAVE_SS7) */ 18863 #ifdef HAVE_OPENR2 18864 ast_cli_register_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli)); 18865 ast_register_application_xml(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec); 18866 #endif 18867 18868 ast_cli_register_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli)); 18869 /* register all the data providers */ 18870 ast_data_register_multiple(dahdi_data_providers, ARRAY_LEN(dahdi_data_providers)); 18871 memset(round_robin, 0, sizeof(round_robin)); 18872 ast_manager_register_xml("DAHDITransfer", 0, action_transfer); 18873 ast_manager_register_xml("DAHDIHangup", 0, action_transferhangup); 18874 ast_manager_register_xml("DAHDIDialOffhook", 0, action_dahdidialoffhook); 18875 ast_manager_register_xml("DAHDIDNDon", 0, action_dahdidndon); 18876 ast_manager_register_xml("DAHDIDNDoff", 0, action_dahdidndoff); 18877 ast_manager_register_xml("DAHDIShowChannels", 0, action_dahdishowchannels); 18878 ast_manager_register_xml("DAHDIRestart", 0, action_dahdirestart); 18879 #if defined(HAVE_PRI) 18880 ast_manager_register_xml("PRIShowSpans", 0, action_prishowspans); 18881 #endif /* defined(HAVE_PRI) */ 18882 18883 ast_cond_init(&ss_thread_complete, NULL); 18884 18885 return res; 18886 }
| 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 12293 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_cadence, 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::chan_tech, 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::description, 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_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, strsep(), 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().
12294 { 12295 /* Make a dahdi_pvt structure for this interface */ 12296 struct dahdi_pvt *tmp;/*!< Current channel structure initializing */ 12297 char fn[80]; 12298 struct dahdi_bufferinfo bi; 12299 12300 int res; 12301 #if defined(HAVE_PRI) 12302 int span = 0; 12303 #endif /* defined(HAVE_PRI) */ 12304 int here = 0;/*!< TRUE if the channel interface already exists. */ 12305 int x; 12306 struct analog_pvt *analog_p = NULL; 12307 struct dahdi_params p; 12308 #if defined(HAVE_PRI) 12309 struct dahdi_spaninfo si; 12310 struct sig_pri_chan *pri_chan = NULL; 12311 #endif /* defined(HAVE_PRI) */ 12312 #if defined(HAVE_SS7) 12313 struct sig_ss7_chan *ss7_chan = NULL; 12314 #endif /* defined(HAVE_SS7) */ 12315 12316 /* Search channel interface list to see if it already exists. */ 12317 for (tmp = iflist; tmp; tmp = tmp->next) { 12318 if (!tmp->destroy) { 12319 if (tmp->channel == channel) { 12320 /* The channel interface already exists. */ 12321 here = 1; 12322 break; 12323 } 12324 if (tmp->channel > channel) { 12325 /* No way it can be in the sorted list. */ 12326 tmp = NULL; 12327 break; 12328 } 12329 } 12330 } 12331 12332 if (!here && reloading != 1) { 12333 tmp = ast_calloc(1, sizeof(*tmp)); 12334 if (!tmp) { 12335 return NULL; 12336 } 12337 tmp->cc_params = ast_cc_config_params_init(); 12338 if (!tmp->cc_params) { 12339 ast_free(tmp); 12340 return NULL; 12341 } 12342 ast_mutex_init(&tmp->lock); 12343 ifcount++; 12344 for (x = 0; x < 3; x++) 12345 tmp->subs[x].dfd = -1; 12346 tmp->channel = channel; 12347 tmp->priindication_oob = conf->chan.priindication_oob; 12348 } 12349 12350 if (tmp) { 12351 int chan_sig = conf->chan.sig; 12352 12353 /* If there are variables in tmp before it is updated to match the new config, clear them */ 12354 if (reloading && tmp->vars) { 12355 ast_variables_destroy(tmp->vars); 12356 tmp->vars = NULL; 12357 } 12358 12359 if (!here) { 12360 /* Can only get here if this is a new channel interface being created. */ 12361 if ((channel != CHAN_PSEUDO)) { 12362 int count = 0; 12363 12364 snprintf(fn, sizeof(fn), "%d", channel); 12365 /* Open non-blocking */ 12366 tmp->subs[SUB_REAL].dfd = dahdi_open(fn); 12367 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 */ 12368 usleep(1); 12369 tmp->subs[SUB_REAL].dfd = dahdi_open(fn); 12370 count++; 12371 } 12372 /* Allocate a DAHDI structure */ 12373 if (tmp->subs[SUB_REAL].dfd < 0) { 12374 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); 12375 destroy_dahdi_pvt(tmp); 12376 return NULL; 12377 } 12378 memset(&p, 0, sizeof(p)); 12379 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 12380 if (res < 0) { 12381 ast_log(LOG_ERROR, "Unable to get parameters: %s\n", strerror(errno)); 12382 destroy_dahdi_pvt(tmp); 12383 return NULL; 12384 } 12385 if (conf->is_sig_auto) 12386 chan_sig = sigtype_to_signalling(p.sigtype); 12387 if (p.sigtype != (chan_sig & 0x3ffff)) { 12388 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)); 12389 destroy_dahdi_pvt(tmp); 12390 return NULL; 12391 } 12392 tmp->law_default = p.curlaw; 12393 tmp->law = p.curlaw; 12394 tmp->span = p.spanno; 12395 #if defined(HAVE_PRI) 12396 span = p.spanno - 1; 12397 #endif /* defined(HAVE_PRI) */ 12398 } else { 12399 chan_sig = 0; 12400 } 12401 tmp->sig = chan_sig; 12402 tmp->outsigmod = conf->chan.outsigmod; 12403 12404 if (analog_lib_handles(chan_sig, tmp->radio, tmp->oprmode)) { 12405 analog_p = analog_new(dahdisig_to_analogsig(chan_sig), &dahdi_analog_callbacks, tmp); 12406 if (!analog_p) { 12407 destroy_dahdi_pvt(tmp); 12408 return NULL; 12409 } 12410 tmp->sig_pvt = analog_p; 12411 } 12412 #if defined(HAVE_SS7) 12413 if (chan_sig == SIG_SS7) { 12414 struct dahdi_ss7 *ss7; 12415 int clear = 0; 12416 12417 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &clear)) { 12418 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 12419 destroy_dahdi_pvt(tmp); 12420 return NULL; 12421 } 12422 12423 ss7 = ss7_resolve_linkset(cur_linkset); 12424 if (!ss7) { 12425 ast_log(LOG_ERROR, "Unable to find linkset %d\n", cur_linkset); 12426 destroy_dahdi_pvt(tmp); 12427 return NULL; 12428 } 12429 ss7->ss7.span = cur_linkset; 12430 if (cur_cicbeginswith < 0) { 12431 ast_log(LOG_ERROR, "Need to set cicbeginswith for the channels!\n"); 12432 destroy_dahdi_pvt(tmp); 12433 return NULL; 12434 } 12435 ss7_chan = sig_ss7_chan_new(tmp, &dahdi_ss7_callbacks, &ss7->ss7); 12436 if (!ss7_chan) { 12437 destroy_dahdi_pvt(tmp); 12438 return NULL; 12439 } 12440 tmp->sig_pvt = ss7_chan; 12441 tmp->ss7 = &ss7->ss7; 12442 12443 ss7_chan->channel = tmp->channel; 12444 ss7_chan->cic = cur_cicbeginswith++; 12445 12446 /* DB: Add CIC's DPC information */ 12447 ss7_chan->dpc = cur_defaultdpc; 12448 12449 ss7->ss7.pvts[ss7->ss7.numchans++] = ss7_chan; 12450 12451 ast_copy_string(ss7->ss7.internationalprefix, conf->ss7.ss7.internationalprefix, sizeof(ss7->ss7.internationalprefix)); 12452 ast_copy_string(ss7->ss7.nationalprefix, conf->ss7.ss7.nationalprefix, sizeof(ss7->ss7.nationalprefix)); 12453 ast_copy_string(ss7->ss7.subscriberprefix, conf->ss7.ss7.subscriberprefix, sizeof(ss7->ss7.subscriberprefix)); 12454 ast_copy_string(ss7->ss7.unknownprefix, conf->ss7.ss7.unknownprefix, sizeof(ss7->ss7.unknownprefix)); 12455 12456 ss7->ss7.called_nai = conf->ss7.ss7.called_nai; 12457 ss7->ss7.calling_nai = conf->ss7.ss7.calling_nai; 12458 } 12459 #endif /* defined(HAVE_SS7) */ 12460 #ifdef HAVE_OPENR2 12461 if (chan_sig == SIG_MFCR2) { 12462 struct dahdi_mfcr2 *r2_link; 12463 r2_link = dahdi_r2_get_link(); 12464 if (!r2_link) { 12465 ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n"); 12466 destroy_dahdi_pvt(tmp); 12467 return NULL; 12468 } 12469 if (!r2_link->protocol_context && dahdi_r2_set_context(r2_link, conf)) { 12470 ast_log(LOG_ERROR, "Cannot create OpenR2 protocol context.\n"); 12471 destroy_dahdi_pvt(tmp); 12472 return NULL; 12473 } 12474 if (r2_link->numchans == ARRAY_LEN(r2_link->pvts)) { 12475 ast_log(LOG_ERROR, "Cannot add more channels to this link!\n"); 12476 destroy_dahdi_pvt(tmp); 12477 return NULL; 12478 } 12479 r2_link->pvts[r2_link->numchans++] = tmp; 12480 tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context, 12481 tmp->subs[SUB_REAL].dfd, 12482 NULL, NULL); 12483 if (!tmp->r2chan) { 12484 openr2_liberr_t err = openr2_context_get_last_error(r2_link->protocol_context); 12485 ast_log(LOG_ERROR, "Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err)); 12486 destroy_dahdi_pvt(tmp); 12487 return NULL; 12488 } 12489 tmp->mfcr2 = r2_link; 12490 if (conf->mfcr2.call_files) { 12491 openr2_chan_enable_call_files(tmp->r2chan); 12492 } 12493 openr2_chan_set_client_data(tmp->r2chan, tmp); 12494 /* cast seems to be needed to get rid of the annoying warning regarding format attribute */ 12495 openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log); 12496 openr2_chan_set_log_level(tmp->r2chan, conf->mfcr2.loglevel); 12497 tmp->mfcr2_category = conf->mfcr2.category; 12498 tmp->mfcr2_charge_calls = conf->mfcr2.charge_calls; 12499 tmp->mfcr2_allow_collect_calls = conf->mfcr2.allow_collect_calls; 12500 tmp->mfcr2_forced_release = conf->mfcr2.forced_release; 12501 tmp->mfcr2_accept_on_offer = conf->mfcr2.accept_on_offer; 12502 tmp->mfcr2call = 0; 12503 tmp->mfcr2_dnis_index = 0; 12504 tmp->mfcr2_ani_index = 0; 12505 r2_link->monitored_count++; 12506 } 12507 #endif 12508 #ifdef HAVE_PRI 12509 if (dahdi_sig_pri_lib_handles(chan_sig)) { 12510 int offset; 12511 int matchesdchan; 12512 int x,y; 12513 int myswitchtype = 0; 12514 12515 offset = 0; 12516 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &offset)) { 12517 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno)); 12518 destroy_dahdi_pvt(tmp); 12519 return NULL; 12520 } 12521 if (span >= NUM_SPANS) { 12522 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span); 12523 destroy_dahdi_pvt(tmp); 12524 return NULL; 12525 } else { 12526 si.spanno = 0; 12527 if (ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SPANSTAT,&si) == -1) { 12528 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno)); 12529 destroy_dahdi_pvt(tmp); 12530 return NULL; 12531 } 12532 /* Store the logical span first based upon the real span */ 12533 tmp->logicalspan = pris[span].prilogicalspan; 12534 pri_resolve_span(&span, channel, (channel - p.chanpos), &si); 12535 if (span < 0) { 12536 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel); 12537 destroy_dahdi_pvt(tmp); 12538 return NULL; 12539 } 12540 myswitchtype = conf->pri.pri.switchtype; 12541 /* Make sure this isn't a d-channel */ 12542 matchesdchan=0; 12543 for (x = 0; x < NUM_SPANS; x++) { 12544 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) { 12545 if (pris[x].dchannels[y] == tmp->channel) { 12546 matchesdchan = 1; 12547 break; 12548 } 12549 } 12550 } 12551 if (!matchesdchan) { 12552 if (pris[span].pri.nodetype && (pris[span].pri.nodetype != conf->pri.pri.nodetype)) { 12553 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].pri.nodetype)); 12554 destroy_dahdi_pvt(tmp); 12555 return NULL; 12556 } 12557 if (pris[span].pri.switchtype && (pris[span].pri.switchtype != myswitchtype)) { 12558 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].pri.switchtype)); 12559 destroy_dahdi_pvt(tmp); 12560 return NULL; 12561 } 12562 if ((pris[span].pri.dialplan) && (pris[span].pri.dialplan != conf->pri.pri.dialplan)) { 12563 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)); 12564 destroy_dahdi_pvt(tmp); 12565 return NULL; 12566 } 12567 if (!ast_strlen_zero(pris[span].pri.idledial) && strcmp(pris[span].pri.idledial, conf->pri.pri.idledial)) { 12568 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.pri.idledial); 12569 destroy_dahdi_pvt(tmp); 12570 return NULL; 12571 } 12572 if (!ast_strlen_zero(pris[span].pri.idleext) && strcmp(pris[span].pri.idleext, conf->pri.pri.idleext)) { 12573 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.pri.idleext); 12574 destroy_dahdi_pvt(tmp); 12575 return NULL; 12576 } 12577 if (pris[span].pri.minunused && (pris[span].pri.minunused != conf->pri.pri.minunused)) { 12578 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.pri.minunused); 12579 destroy_dahdi_pvt(tmp); 12580 return NULL; 12581 } 12582 if (pris[span].pri.minidle && (pris[span].pri.minidle != conf->pri.pri.minidle)) { 12583 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.pri.minidle); 12584 destroy_dahdi_pvt(tmp); 12585 return NULL; 12586 } 12587 if (pris[span].pri.numchans >= ARRAY_LEN(pris[span].pri.pvts)) { 12588 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, 12589 pris[span].pri.trunkgroup); 12590 destroy_dahdi_pvt(tmp); 12591 return NULL; 12592 } 12593 12594 ast_debug(4, "Adding callbacks %p to chan %d\n", &dahdi_pri_callbacks, tmp->channel); 12595 pri_chan = sig_pri_chan_new(tmp, &dahdi_pri_callbacks, &pris[span].pri, tmp->logicalspan, p.chanpos, pris[span].mastertrunkgroup); 12596 if (!pri_chan) { 12597 destroy_dahdi_pvt(tmp); 12598 return NULL; 12599 } 12600 tmp->sig_pvt = pri_chan; 12601 tmp->pri = &pris[span].pri; 12602 12603 tmp->priexclusive = conf->chan.priexclusive; 12604 12605 if (!tmp->pri->cc_params) { 12606 tmp->pri->cc_params = ast_cc_config_params_init(); 12607 if (!tmp->pri->cc_params) { 12608 destroy_dahdi_pvt(tmp); 12609 return NULL; 12610 } 12611 } 12612 ast_cc_copy_config_params(tmp->pri->cc_params, 12613 conf->chan.cc_params); 12614 12615 pris[span].pri.sig = chan_sig; 12616 pris[span].pri.nodetype = conf->pri.pri.nodetype; 12617 pris[span].pri.switchtype = myswitchtype; 12618 pris[span].pri.nsf = conf->pri.pri.nsf; 12619 pris[span].pri.dialplan = conf->pri.pri.dialplan; 12620 pris[span].pri.localdialplan = conf->pri.pri.localdialplan; 12621 pris[span].pri.cpndialplan = conf->pri.pri.cpndialplan; 12622 pris[span].pri.pvts[pris[span].pri.numchans++] = tmp->sig_pvt; 12623 pris[span].pri.minunused = conf->pri.pri.minunused; 12624 pris[span].pri.minidle = conf->pri.pri.minidle; 12625 pris[span].pri.overlapdial = conf->pri.pri.overlapdial; 12626 pris[span].pri.qsigchannelmapping = conf->pri.pri.qsigchannelmapping; 12627 pris[span].pri.discardremoteholdretrieval = conf->pri.pri.discardremoteholdretrieval; 12628 #if defined(HAVE_PRI_SERVICE_MESSAGES) 12629 pris[span].pri.enable_service_message_support = conf->pri.pri.enable_service_message_support; 12630 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 12631 #ifdef HAVE_PRI_INBANDDISCONNECT 12632 pris[span].pri.inbanddisconnect = conf->pri.pri.inbanddisconnect; 12633 #endif 12634 #if defined(HAVE_PRI_CALL_HOLD) 12635 pris[span].pri.hold_disconnect_transfer = 12636 conf->pri.pri.hold_disconnect_transfer; 12637 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 12638 #if defined(HAVE_PRI_CCSS) 12639 pris[span].pri.cc_ptmp_recall_mode = 12640 conf->pri.pri.cc_ptmp_recall_mode; 12641 pris[span].pri.cc_qsig_signaling_link_req = 12642 conf->pri.pri.cc_qsig_signaling_link_req; 12643 pris[span].pri.cc_qsig_signaling_link_rsp = 12644 conf->pri.pri.cc_qsig_signaling_link_rsp; 12645 #endif /* defined(HAVE_PRI_CCSS) */ 12646 #if defined(HAVE_PRI_CALL_WAITING) 12647 pris[span].pri.max_call_waiting_calls = 12648 conf->pri.pri.max_call_waiting_calls; 12649 pris[span].pri.allow_call_waiting_calls = 12650 conf->pri.pri.allow_call_waiting_calls; 12651 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 12652 pris[span].pri.transfer = conf->chan.transfer; 12653 pris[span].pri.facilityenable = conf->pri.pri.facilityenable; 12654 #if defined(HAVE_PRI_L2_PERSISTENCE) 12655 pris[span].pri.l2_persistence = conf->pri.pri.l2_persistence; 12656 #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */ 12657 #if defined(HAVE_PRI_AOC_EVENTS) 12658 pris[span].pri.aoc_passthrough_flag = conf->pri.pri.aoc_passthrough_flag; 12659 pris[span].pri.aoce_delayhangup = conf->pri.pri.aoce_delayhangup; 12660 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 12661 pris[span].pri.append_msn_to_user_tag = conf->pri.pri.append_msn_to_user_tag; 12662 ast_copy_string(pris[span].pri.initial_user_tag, conf->chan.cid_tag, sizeof(pris[span].pri.initial_user_tag)); 12663 ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list)); 12664 #if defined(HAVE_PRI_MWI) 12665 ast_copy_string(pris[span].pri.mwi_mailboxes, 12666 conf->pri.pri.mwi_mailboxes, 12667 sizeof(pris[span].pri.mwi_mailboxes)); 12668 ast_copy_string(pris[span].pri.mwi_vm_numbers, 12669 conf->pri.pri.mwi_vm_numbers, 12670 sizeof(pris[span].pri.mwi_vm_numbers)); 12671 #endif /* defined(HAVE_PRI_MWI) */ 12672 ast_copy_string(pris[span].pri.idledial, conf->pri.pri.idledial, sizeof(pris[span].pri.idledial)); 12673 ast_copy_string(pris[span].pri.idleext, conf->pri.pri.idleext, sizeof(pris[span].pri.idleext)); 12674 ast_copy_string(pris[span].pri.internationalprefix, conf->pri.pri.internationalprefix, sizeof(pris[span].pri.internationalprefix)); 12675 ast_copy_string(pris[span].pri.nationalprefix, conf->pri.pri.nationalprefix, sizeof(pris[span].pri.nationalprefix)); 12676 ast_copy_string(pris[span].pri.localprefix, conf->pri.pri.localprefix, sizeof(pris[span].pri.localprefix)); 12677 ast_copy_string(pris[span].pri.privateprefix, conf->pri.pri.privateprefix, sizeof(pris[span].pri.privateprefix)); 12678 ast_copy_string(pris[span].pri.unknownprefix, conf->pri.pri.unknownprefix, sizeof(pris[span].pri.unknownprefix)); 12679 pris[span].pri.moh_signaling = conf->pri.pri.moh_signaling; 12680 pris[span].pri.resetinterval = conf->pri.pri.resetinterval; 12681 #if defined(HAVE_PRI_DISPLAY_TEXT) 12682 pris[span].pri.display_flags_send = conf->pri.pri.display_flags_send; 12683 pris[span].pri.display_flags_receive = conf->pri.pri.display_flags_receive; 12684 #endif /* defined(HAVE_PRI_DISPLAY_TEXT) */ 12685 #if defined(HAVE_PRI_MCID) 12686 pris[span].pri.mcid_send = conf->pri.pri.mcid_send; 12687 #endif /* defined(HAVE_PRI_MCID) */ 12688 #if defined(HAVE_PRI_DATETIME_SEND) 12689 pris[span].pri.datetime_send = conf->pri.pri.datetime_send; 12690 #endif /* defined(HAVE_PRI_DATETIME_SEND) */ 12691 12692 for (x = 0; x < PRI_MAX_TIMERS; x++) { 12693 pris[span].pri.pritimers[x] = conf->pri.pri.pritimers[x]; 12694 } 12695 12696 #if defined(HAVE_PRI_CALL_WAITING) 12697 /* Channel initial config parameters. */ 12698 pris[span].pri.ch_cfg.stripmsd = conf->chan.stripmsd; 12699 pris[span].pri.ch_cfg.hidecallerid = conf->chan.hidecallerid; 12700 pris[span].pri.ch_cfg.hidecalleridname = conf->chan.hidecalleridname; 12701 pris[span].pri.ch_cfg.immediate = conf->chan.immediate; 12702 pris[span].pri.ch_cfg.priexclusive = conf->chan.priexclusive; 12703 pris[span].pri.ch_cfg.priindication_oob = conf->chan.priindication_oob; 12704 pris[span].pri.ch_cfg.use_callerid = conf->chan.use_callerid; 12705 pris[span].pri.ch_cfg.use_callingpres = conf->chan.use_callingpres; 12706 ast_copy_string(pris[span].pri.ch_cfg.context, conf->chan.context, sizeof(pris[span].pri.ch_cfg.context)); 12707 ast_copy_string(pris[span].pri.ch_cfg.mohinterpret, conf->chan.mohinterpret, sizeof(pris[span].pri.ch_cfg.mohinterpret)); 12708 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 12709 } else { 12710 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", p.chanpos); 12711 destroy_dahdi_pvt(tmp); 12712 return NULL; 12713 } 12714 } 12715 } 12716 #endif 12717 } else { 12718 /* already exists in interface list */ 12719 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)); 12720 chan_sig = tmp->sig; 12721 if (tmp->subs[SUB_REAL].dfd > -1) { 12722 memset(&p, 0, sizeof(p)); 12723 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 12724 } 12725 } 12726 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */ 12727 switch (chan_sig) { 12728 case SIG_FXSKS: 12729 case SIG_FXSLS: 12730 case SIG_EM: 12731 case SIG_EM_E1: 12732 case SIG_EMWINK: 12733 case SIG_FEATD: 12734 case SIG_FEATDMF: 12735 case SIG_FEATDMF_TA: 12736 case SIG_FEATB: 12737 case SIG_E911: 12738 case SIG_SF: 12739 case SIG_SFWINK: 12740 case SIG_FGC_CAMA: 12741 case SIG_FGC_CAMAMF: 12742 case SIG_SF_FEATD: 12743 case SIG_SF_FEATDMF: 12744 case SIG_SF_FEATB: 12745 p.starttime = 250; 12746 break; 12747 } 12748 12749 if (tmp->radio) { 12750 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */ 12751 p.channo = channel; 12752 p.rxwinktime = 1; 12753 p.rxflashtime = 1; 12754 p.starttime = 1; 12755 p.debouncetime = 5; 12756 } else { 12757 p.channo = channel; 12758 /* Override timing settings based on config file */ 12759 if (conf->timing.prewinktime >= 0) 12760 p.prewinktime = conf->timing.prewinktime; 12761 if (conf->timing.preflashtime >= 0) 12762 p.preflashtime = conf->timing.preflashtime; 12763 if (conf->timing.winktime >= 0) 12764 p.winktime = conf->timing.winktime; 12765 if (conf->timing.flashtime >= 0) 12766 p.flashtime = conf->timing.flashtime; 12767 if (conf->timing.starttime >= 0) 12768 p.starttime = conf->timing.starttime; 12769 if (conf->timing.rxwinktime >= 0) 12770 p.rxwinktime = conf->timing.rxwinktime; 12771 if (conf->timing.rxflashtime >= 0) 12772 p.rxflashtime = conf->timing.rxflashtime; 12773 if (conf->timing.debouncetime >= 0) 12774 p.debouncetime = conf->timing.debouncetime; 12775 } 12776 12777 /* don't set parms on a pseudo-channel */ 12778 if (tmp->subs[SUB_REAL].dfd >= 0) 12779 { 12780 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_PARAMS, &p); 12781 if (res < 0) { 12782 ast_log(LOG_ERROR, "Unable to set parameters: %s\n", strerror(errno)); 12783 destroy_dahdi_pvt(tmp); 12784 return NULL; 12785 } 12786 } 12787 #if 1 12788 if (!here && (tmp->subs[SUB_REAL].dfd > -1)) { 12789 memset(&bi, 0, sizeof(bi)); 12790 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi); 12791 if (!res) { 12792 bi.txbufpolicy = conf->chan.buf_policy; 12793 bi.rxbufpolicy = conf->chan.buf_policy; 12794 bi.numbufs = conf->chan.buf_no; 12795 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi); 12796 if (res < 0) { 12797 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", channel, strerror(errno)); 12798 } 12799 } else { 12800 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", channel, strerror(errno)); 12801 } 12802 tmp->buf_policy = conf->chan.buf_policy; 12803 tmp->buf_no = conf->chan.buf_no; 12804 tmp->usefaxbuffers = conf->chan.usefaxbuffers; 12805 tmp->faxbuf_policy = conf->chan.faxbuf_policy; 12806 tmp->faxbuf_no = conf->chan.faxbuf_no; 12807 /* This is not as gnarly as it may first appear. If the ioctl above failed, we'd be setting 12808 * tmp->bufsize to zero which would cause subsequent faxbuffer-related ioctl calls to fail. 12809 * The reason the ioctl call above failed should to be determined before worrying about the 12810 * faxbuffer-related ioctl calls */ 12811 tmp->bufsize = bi.bufsize; 12812 } 12813 #endif 12814 tmp->immediate = conf->chan.immediate; 12815 tmp->transfertobusy = conf->chan.transfertobusy; 12816 if (chan_sig & __DAHDI_SIG_FXS) { 12817 tmp->mwimonitor_fsk = conf->chan.mwimonitor_fsk; 12818 tmp->mwimonitor_neon = conf->chan.mwimonitor_neon; 12819 tmp->mwimonitor_rpas = conf->chan.mwimonitor_rpas; 12820 } 12821 tmp->ringt_base = ringt_base; 12822 tmp->firstradio = 0; 12823 if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS)) 12824 tmp->permcallwaiting = conf->chan.callwaiting; 12825 else 12826 tmp->permcallwaiting = 0; 12827 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */ 12828 tmp->destroy = 0; 12829 tmp->drings = conf->chan.drings; 12830 12831 /* 10 is a nice default. */ 12832 if (tmp->drings.ringnum[0].range == 0) 12833 tmp->drings.ringnum[0].range = 10; 12834 if (tmp->drings.ringnum[1].range == 0) 12835 tmp->drings.ringnum[1].range = 10; 12836 if (tmp->drings.ringnum[2].range == 0) 12837 tmp->drings.ringnum[2].range = 10; 12838 12839 tmp->usedistinctiveringdetection = usedistinctiveringdetection; 12840 tmp->callwaitingcallerid = conf->chan.callwaitingcallerid; 12841 tmp->threewaycalling = conf->chan.threewaycalling; 12842 tmp->adsi = conf->chan.adsi; 12843 tmp->use_smdi = conf->chan.use_smdi; 12844 tmp->permhidecallerid = conf->chan.hidecallerid; 12845 tmp->hidecalleridname = conf->chan.hidecalleridname; 12846 tmp->callreturn = conf->chan.callreturn; 12847 tmp->echocancel = conf->chan.echocancel; 12848 tmp->echotraining = conf->chan.echotraining; 12849 tmp->pulse = conf->chan.pulse; 12850 if (tmp->echocancel.head.tap_length) { 12851 tmp->echocanbridged = conf->chan.echocanbridged; 12852 } else { 12853 if (conf->chan.echocanbridged) 12854 ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n"); 12855 tmp->echocanbridged = 0; 12856 } 12857 tmp->busydetect = conf->chan.busydetect; 12858 tmp->busycount = conf->chan.busycount; 12859 tmp->busy_cadence = conf->chan.busy_cadence; 12860 tmp->callprogress = conf->chan.callprogress; 12861 tmp->waitfordialtone = conf->chan.waitfordialtone; 12862 tmp->cancallforward = conf->chan.cancallforward; 12863 tmp->dtmfrelax = conf->chan.dtmfrelax; 12864 tmp->callwaiting = tmp->permcallwaiting; 12865 tmp->hidecallerid = tmp->permhidecallerid; 12866 tmp->channel = channel; 12867 tmp->stripmsd = conf->chan.stripmsd; 12868 tmp->use_callerid = conf->chan.use_callerid; 12869 tmp->cid_signalling = conf->chan.cid_signalling; 12870 tmp->cid_start = conf->chan.cid_start; 12871 tmp->dahditrcallerid = conf->chan.dahditrcallerid; 12872 tmp->restrictcid = conf->chan.restrictcid; 12873 tmp->use_callingpres = conf->chan.use_callingpres; 12874 if (tmp->usedistinctiveringdetection) { 12875 if (!tmp->use_callerid) { 12876 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n"); 12877 tmp->use_callerid = 1; 12878 } 12879 } 12880 12881 if (tmp->cid_signalling == CID_SIG_SMDI) { 12882 if (!tmp->use_smdi) { 12883 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n"); 12884 tmp->use_smdi = 1; 12885 } 12886 } 12887 if (tmp->use_smdi) { 12888 tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port); 12889 if (!(tmp->smdi_iface)) { 12890 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n"); 12891 tmp->use_smdi = 0; 12892 } 12893 } 12894 12895 ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode)); 12896 tmp->amaflags = conf->chan.amaflags; 12897 if (!here) { 12898 tmp->confno = -1; 12899 tmp->propconfno = -1; 12900 } 12901 tmp->canpark = conf->chan.canpark; 12902 tmp->transfer = conf->chan.transfer; 12903 ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext)); 12904 ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language)); 12905 ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret)); 12906 ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest)); 12907 ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context)); 12908 ast_copy_string(tmp->description, conf->chan.description, sizeof(tmp->description)); 12909 ast_copy_string(tmp->parkinglot, conf->chan.parkinglot, sizeof(tmp->parkinglot)); 12910 tmp->cid_ton = 0; 12911 if (analog_lib_handles(tmp->sig, tmp->radio, tmp->oprmode)) { 12912 ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num)); 12913 ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name)); 12914 } else { 12915 tmp->cid_num[0] = '\0'; 12916 tmp->cid_name[0] = '\0'; 12917 } 12918 #if defined(HAVE_PRI) 12919 if (dahdi_sig_pri_lib_handles(tmp->sig)) { 12920 tmp->cid_tag[0] = '\0'; 12921 } else 12922 #endif /* defined(HAVE_PRI) */ 12923 { 12924 ast_copy_string(tmp->cid_tag, conf->chan.cid_tag, sizeof(tmp->cid_tag)); 12925 } 12926 tmp->cid_subaddr[0] = '\0'; 12927 ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox)); 12928 if (channel != CHAN_PSEUDO && !ast_strlen_zero(tmp->mailbox)) { 12929 char *mailbox, *context; 12930 mailbox = context = ast_strdupa(tmp->mailbox); 12931 strsep(&context, "@"); 12932 if (ast_strlen_zero(context)) 12933 context = "default"; 12934 tmp->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "Dahdi MWI subscription", NULL, 12935 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12936 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12937 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS, 12938 AST_EVENT_IE_END); 12939 } 12940 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 12941 tmp->mwisend_setting = conf->chan.mwisend_setting; 12942 tmp->mwisend_fsk = conf->chan.mwisend_fsk; 12943 tmp->mwisend_rpas = conf->chan.mwisend_rpas; 12944 #endif 12945 12946 tmp->group = conf->chan.group; 12947 tmp->callgroup = conf->chan.callgroup; 12948 tmp->pickupgroup= conf->chan.pickupgroup; 12949 if (conf->chan.vars) { 12950 struct ast_variable *v, *tmpvar; 12951 for (v = conf->chan.vars ; v ; v = v->next) { 12952 if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 12953 tmpvar->next = tmp->vars; 12954 tmp->vars = tmpvar; 12955 } 12956 } 12957 } 12958 tmp->cid_rxgain = conf->chan.cid_rxgain; 12959 tmp->rxgain = conf->chan.rxgain; 12960 tmp->txgain = conf->chan.txgain; 12961 tmp->txdrc = conf->chan.txdrc; 12962 tmp->rxdrc = conf->chan.rxdrc; 12963 tmp->tonezone = conf->chan.tonezone; 12964 if (tmp->subs[SUB_REAL].dfd > -1) { 12965 set_actual_gain(tmp->subs[SUB_REAL].dfd, tmp->rxgain, tmp->txgain, tmp->rxdrc, tmp->txdrc, tmp->law); 12966 if (tmp->dsp) 12967 ast_dsp_set_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); 12968 update_conf(tmp); 12969 if (!here) { 12970 switch (chan_sig) { 12971 case SIG_PRI_LIB_HANDLE_CASES: 12972 case SIG_SS7: 12973 case SIG_MFCR2: 12974 break; 12975 default: 12976 /* Hang it up to be sure it's good */ 12977 dahdi_set_hook(tmp->subs[SUB_REAL].dfd, DAHDI_ONHOOK); 12978 break; 12979 } 12980 } 12981 ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SETTONEZONE,&tmp->tonezone); 12982 if ((res = get_alarms(tmp)) != DAHDI_ALARM_NONE) { 12983 /* the dchannel is down so put the channel in alarm */ 12984 switch (tmp->sig) { 12985 #ifdef HAVE_PRI 12986 case SIG_PRI_LIB_HANDLE_CASES: 12987 sig_pri_set_alarm(tmp->sig_pvt, 1); 12988 break; 12989 #endif 12990 #if defined(HAVE_SS7) 12991 case SIG_SS7: 12992 sig_ss7_set_alarm(tmp->sig_pvt, 1); 12993 break; 12994 #endif /* defined(HAVE_SS7) */ 12995 default: 12996 /* The only sig submodule left should be sig_analog. */ 12997 analog_p = tmp->sig_pvt; 12998 if (analog_p) { 12999 analog_p->inalarm = 1; 13000 } 13001 tmp->inalarm = 1; 13002 break; 13003 } 13004 handle_alarms(tmp, res); 13005 } 13006 } 13007 13008 tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay; 13009 tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch; 13010 tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch; 13011 tmp->sendcalleridafter = conf->chan.sendcalleridafter; 13012 ast_cc_copy_config_params(tmp->cc_params, conf->chan.cc_params); 13013 13014 if (!here) { 13015 tmp->locallyblocked = 0; 13016 tmp->remotelyblocked = 0; 13017 switch (tmp->sig) { 13018 #if defined(HAVE_PRI) 13019 case SIG_PRI_LIB_HANDLE_CASES: 13020 tmp->inservice = 1;/* Inservice until actually implemented. */ 13021 #if defined(HAVE_PRI_SERVICE_MESSAGES) 13022 ((struct sig_pri_chan *) tmp->sig_pvt)->service_status = 0; 13023 if (chan_sig == SIG_PRI) { 13024 char db_chan_name[20]; 13025 char db_answer[5]; 13026 13027 /* 13028 * Initialize the active out-of-service status 13029 * and delete any record if the feature is not enabled. 13030 */ 13031 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, tmp->span, tmp->channel); 13032 if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) { 13033 unsigned *why; 13034 13035 why = &((struct sig_pri_chan *) tmp->sig_pvt)->service_status; 13036 if (tmp->pri->enable_service_message_support) { 13037 char state; 13038 13039 sscanf(db_answer, "%1c:%30u", &state, why); 13040 13041 /* Ensure that only the implemented bits could be set.*/ 13042 *why &= (SRVST_NEAREND | SRVST_FAREND); 13043 } 13044 if (!*why) { 13045 ast_db_del(db_chan_name, SRVST_DBKEY); 13046 } 13047 } 13048 } 13049 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 13050 break; 13051 #endif /* defined(HAVE_PRI) */ 13052 #if defined(HAVE_SS7) 13053 case SIG_SS7: 13054 tmp->inservice = 0; 13055 break; 13056 #endif /* defined(HAVE_SS7) */ 13057 default: 13058 /* We default to in service on protocols that don't have a reset */ 13059 tmp->inservice = 1; 13060 break; 13061 } 13062 } 13063 13064 switch (tmp->sig) { 13065 #if defined(HAVE_PRI) 13066 case SIG_PRI_LIB_HANDLE_CASES: 13067 if (pri_chan) { 13068 pri_chan->channel = tmp->channel; 13069 pri_chan->hidecallerid = tmp->hidecallerid; 13070 pri_chan->hidecalleridname = tmp->hidecalleridname; 13071 pri_chan->immediate = tmp->immediate; 13072 pri_chan->inalarm = tmp->inalarm; 13073 pri_chan->priexclusive = tmp->priexclusive; 13074 pri_chan->priindication_oob = tmp->priindication_oob; 13075 pri_chan->use_callerid = tmp->use_callerid; 13076 pri_chan->use_callingpres = tmp->use_callingpres; 13077 ast_copy_string(pri_chan->context, tmp->context, 13078 sizeof(pri_chan->context)); 13079 ast_copy_string(pri_chan->mohinterpret, tmp->mohinterpret, 13080 sizeof(pri_chan->mohinterpret)); 13081 pri_chan->stripmsd = tmp->stripmsd; 13082 } 13083 break; 13084 #endif /* defined(HAVE_PRI) */ 13085 #if defined(HAVE_SS7) 13086 case SIG_SS7: 13087 if (ss7_chan) { 13088 ss7_chan->inalarm = tmp->inalarm; 13089 13090 ss7_chan->stripmsd = tmp->stripmsd; 13091 ss7_chan->hidecallerid = tmp->hidecallerid; 13092 ss7_chan->use_callerid = tmp->use_callerid; 13093 ss7_chan->use_callingpres = tmp->use_callingpres; 13094 ss7_chan->immediate = tmp->immediate; 13095 ss7_chan->locallyblocked = tmp->locallyblocked; 13096 ss7_chan->remotelyblocked = tmp->remotelyblocked; 13097 ast_copy_string(ss7_chan->context, tmp->context, 13098 sizeof(ss7_chan->context)); 13099 ast_copy_string(ss7_chan->mohinterpret, tmp->mohinterpret, 13100 sizeof(ss7_chan->mohinterpret)); 13101 } 13102 break; 13103 #endif /* defined(HAVE_SS7) */ 13104 default: 13105 /* The only sig submodule left should be sig_analog. */ 13106 analog_p = tmp->sig_pvt; 13107 if (analog_p) { 13108 analog_p->channel = tmp->channel; 13109 analog_p->polarityonanswerdelay = conf->chan.polarityonanswerdelay; 13110 analog_p->answeronpolarityswitch = conf->chan.answeronpolarityswitch; 13111 analog_p->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch; 13112 analog_p->permcallwaiting = conf->chan.callwaiting; /* permcallwaiting possibly modified in analog_config_complete */ 13113 analog_p->callreturn = conf->chan.callreturn; 13114 analog_p->cancallforward = conf->chan.cancallforward; 13115 analog_p->canpark = conf->chan.canpark; 13116 analog_p->dahditrcallerid = conf->chan.dahditrcallerid; 13117 analog_p->immediate = conf->chan.immediate; 13118 analog_p->permhidecallerid = conf->chan.permhidecallerid; 13119 analog_p->pulse = conf->chan.pulse; 13120 analog_p->threewaycalling = conf->chan.threewaycalling; 13121 analog_p->transfer = conf->chan.transfer; 13122 analog_p->transfertobusy = conf->chan.transfertobusy; 13123 analog_p->use_callerid = tmp->use_callerid; 13124 analog_p->use_smdi = tmp->use_smdi; 13125 analog_p->smdi_iface = tmp->smdi_iface; 13126 analog_p->outsigmod = ANALOG_SIG_NONE; 13127 analog_p->echotraining = conf->chan.echotraining; 13128 analog_p->cid_signalling = conf->chan.cid_signalling; 13129 analog_p->stripmsd = conf->chan.stripmsd; 13130 switch (conf->chan.cid_start) { 13131 case CID_START_POLARITY: 13132 analog_p->cid_start = ANALOG_CID_START_POLARITY; 13133 break; 13134 case CID_START_POLARITY_IN: 13135 analog_p->cid_start = ANALOG_CID_START_POLARITY_IN; 13136 break; 13137 case CID_START_DTMF_NOALERT: 13138 analog_p->cid_start = ANALOG_CID_START_DTMF_NOALERT; 13139 break; 13140 default: 13141 analog_p->cid_start = ANALOG_CID_START_RING; 13142 break; 13143 } 13144 analog_p->callwaitingcallerid = conf->chan.callwaitingcallerid; 13145 analog_p->ringt = conf->chan.ringt; 13146 analog_p->ringt_base = ringt_base; 13147 analog_p->chan_tech = &dahdi_tech; 13148 analog_p->onhooktime = time(NULL); 13149 if (chan_sig & __DAHDI_SIG_FXO) { 13150 memset(&p, 0, sizeof(p)); 13151 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p); 13152 if (!res) { 13153 analog_p->fxsoffhookstate = p.rxisoffhook; 13154 } 13155 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 13156 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting); 13157 #endif 13158 } 13159 analog_p->msgstate = -1; 13160 13161 ast_copy_string(analog_p->mohsuggest, conf->chan.mohsuggest, sizeof(analog_p->mohsuggest)); 13162 ast_copy_string(analog_p->cid_num, conf->chan.cid_num, sizeof(analog_p->cid_num)); 13163 ast_copy_string(analog_p->cid_name, conf->chan.cid_name, sizeof(analog_p->cid_name)); 13164 13165 analog_config_complete(analog_p); 13166 } 13167 break; 13168 } 13169 #if defined(HAVE_PRI) 13170 if (tmp->channel == CHAN_PSEUDO) { 13171 /* 13172 * Save off pseudo channel buffer policy values for dynamic creation of 13173 * no B channel interfaces. 13174 */ 13175 dahdi_pseudo_parms.buf_no = tmp->buf_no; 13176 dahdi_pseudo_parms.buf_policy = tmp->buf_policy; 13177 dahdi_pseudo_parms.faxbuf_no = tmp->faxbuf_no; 13178 dahdi_pseudo_parms.faxbuf_policy = tmp->faxbuf_policy; 13179 } 13180 #endif /* defined(HAVE_PRI) */ 13181 } 13182 if (tmp && !here) { 13183 /* Add the new channel interface to the sorted channel interface list. */ 13184 dahdi_iflist_insert(tmp); 13185 } 13186 return tmp; 13187 }
| static void mwi_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 494 of file chan_dahdi.c.
Referenced by add_peer_mwi_subs(), build_gateway(), build_peer(), config_line(), mkintf(), and skinny_register().
00495 { 00496 /* This module does not handle MWI in an event-based manner. However, it 00497 * subscribes to MWI for each mailbox that is configured so that the core 00498 * knows that we care about it. Then, chan_dahdi will get the MWI from the 00499 * event cache instead of checking the mailbox directly. */ 00500 }
| static int mwi_send_init | ( | struct dahdi_pvt * | pvt | ) | [static] |
Definition at line 11223 of file chan_dahdi.c.
References ast_callerid_vmwi_generate(), ast_calloc, ast_format_set(), 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().
11224 { 11225 int x; 11226 struct ast_format tmpfmt; 11227 11228 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11229 /* Determine how this spill is to be sent */ 11230 if (pvt->mwisend_rpas) { 11231 pvt->mwisend_data.mwisend_current = MWI_SEND_SA; 11232 pvt->mwisendactive = 1; 11233 } else if (pvt->mwisend_fsk) { 11234 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 11235 pvt->mwisendactive = 1; 11236 } else { 11237 pvt->mwisendactive = 0; 11238 return 0; 11239 } 11240 #else 11241 if (mwisend_rpas) { 11242 pvt->mwisend_data.mwisend_current = MWI_SEND_SA; 11243 } else { 11244 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 11245 } 11246 pvt->mwisendactive = 1; 11247 #endif 11248 11249 if (pvt->cidspill) { 11250 ast_log(LOG_WARNING, "cidspill already exists when trying to send FSK MWI\n"); 11251 ast_free(pvt->cidspill); 11252 pvt->cidspill = NULL; 11253 pvt->cidpos = 0; 11254 pvt->cidlen = 0; 11255 } 11256 pvt->cidspill = ast_calloc(1, MAX_CALLERID_SIZE); 11257 if (!pvt->cidspill) { 11258 pvt->mwisendactive = 0; 11259 return -1; 11260 } 11261 x = DAHDI_FLUSH_BOTH; 11262 ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x); 11263 x = 3000; 11264 ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_ONHOOKTRANSFER, &x); 11265 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11266 if (pvt->mwisend_fsk) { 11267 #endif 11268 pvt->cidlen = ast_callerid_vmwi_generate(pvt->cidspill, has_voicemail(pvt), CID_MWI_TYPE_MDMF_FULL, 11269 ast_format_set(&tmpfmt, AST_LAW(pvt), 0), pvt->cid_name, pvt->cid_num, 0); 11270 pvt->cidpos = 0; 11271 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11272 } 11273 #endif 11274 return 0; 11275 }
| static int mwi_send_process_buffer | ( | struct dahdi_pvt * | pvt, | |
| int | num_read | |||
| ) | [static] |
Definition at line 11277 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().
11278 { 11279 struct timeval now; 11280 int res; 11281 11282 /* sanity check to catch if this had been interrupted previously 11283 * i.e. state says there is more to do but there is no spill allocated 11284 */ 11285 if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current && !pvt->cidspill) { 11286 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11287 } else if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) { 11288 /* Normal processing -- Perform mwi send action */ 11289 switch ( pvt->mwisend_data.mwisend_current) { 11290 case MWI_SEND_SA: 11291 /* Send the Ring Pulse Signal Alert */ 11292 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &AS_RP_cadence); 11293 if (res) { 11294 ast_log(LOG_WARNING, "Unable to set RP-AS ring cadence: %s\n", strerror(errno)); 11295 goto quit; 11296 } 11297 res = dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RING); 11298 pvt->mwisend_data.mwisend_current = MWI_SEND_SA_WAIT; 11299 break; 11300 case MWI_SEND_SA_WAIT: /* do nothing until I get RINGEROFF event */ 11301 break; 11302 case MWI_SEND_PAUSE: /* Wait between alert and spill - min of 500 mS*/ 11303 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11304 if (pvt->mwisend_fsk) { 11305 #endif 11306 gettimeofday(&now, NULL); 11307 if ((int)(now.tv_sec - pvt->mwisend_data.pause.tv_sec) * 1000000 + (int)now.tv_usec - (int)pvt->mwisend_data.pause.tv_usec > 500000) { 11308 pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL; 11309 } 11310 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI 11311 } else { /* support for mwisendtype=nofsk */ 11312 pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP; 11313 } 11314 #endif 11315 break; 11316 case MWI_SEND_SPILL: 11317 /* We read some number of bytes. Write an equal amount of data */ 11318 if(0 < num_read) { 11319 if (num_read > pvt->cidlen - pvt->cidpos) 11320 num_read = pvt->cidlen - pvt->cidpos; 11321 res = write(pvt->subs[SUB_REAL].dfd, pvt->cidspill + pvt->cidpos, num_read); 11322 if (res > 0) { 11323 pvt->cidpos += res; 11324 if (pvt->cidpos >= pvt->cidlen) { 11325 pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP; 11326 } 11327 } else { 11328 ast_log(LOG_WARNING, "MWI FSK Send Write failed: %s\n", strerror(errno)); 11329 goto quit; 11330 } 11331 } 11332 break; 11333 case MWI_SEND_CLEANUP: 11334 /* For now, do nothing */ 11335 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11336 break; 11337 default: 11338 /* Should not get here, punt*/ 11339 goto quit; 11340 } 11341 } 11342 11343 if (MWI_SEND_DONE == pvt->mwisend_data.mwisend_current) { 11344 if (pvt->cidspill) { 11345 ast_free(pvt->cidspill); 11346 pvt->cidspill = NULL; 11347 pvt->cidpos = 0; 11348 pvt->cidlen = 0; 11349 } 11350 pvt->mwisendactive = 0; 11351 } 11352 return 0; 11353 quit: 11354 if (pvt->cidspill) { 11355 ast_free(pvt->cidspill); 11356 pvt->cidspill = NULL; 11357 pvt->cidpos = 0; 11358 pvt->cidlen = 0; 11359 } 11360 pvt->mwisendactive = 0; 11361 return -1; 11362 }
| static int mwi_send_process_event | ( | struct dahdi_pvt * | pvt, | |
| int | event | |||
| ) | [static] |
Definition at line 11364 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().
11365 { 11366 int handled = 0; 11367 11368 if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) { 11369 switch (event) { 11370 case DAHDI_EVENT_RINGEROFF: 11371 if(pvt->mwisend_data.mwisend_current == MWI_SEND_SA_WAIT) { 11372 handled = 1; 11373 11374 if (dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RINGOFF) ) { 11375 ast_log(LOG_WARNING, "Unable to finish RP-AS: %s mwi send aborted\n", strerror(errno)); 11376 ast_free(pvt->cidspill); 11377 pvt->cidspill = NULL; 11378 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11379 pvt->mwisendactive = 0; 11380 } else { 11381 pvt->mwisend_data.mwisend_current = MWI_SEND_PAUSE; 11382 gettimeofday(&pvt->mwisend_data.pause, NULL); 11383 } 11384 } 11385 break; 11386 /* Going off hook, I need to punt this spill */ 11387 case DAHDI_EVENT_RINGOFFHOOK: 11388 if (pvt->cidspill) { 11389 ast_free(pvt->cidspill); 11390 pvt->cidspill = NULL; 11391 pvt->cidpos = 0; 11392 pvt->cidlen = 0; 11393 } 11394 pvt->mwisend_data.mwisend_current = MWI_SEND_DONE; 11395 pvt->mwisendactive = 0; 11396 break; 11397 case DAHDI_EVENT_RINGERON: 11398 case DAHDI_EVENT_HOOKCOMPLETE: 11399 break; 11400 default: 11401 break; 11402 } 11403 } 11404 return handled; 11405 }
| static void* mwi_thread | ( | void * | data | ) | [static] |
Definition at line 11066 of file chan_dahdi.c.
References analog_lib_handles(), analog_ss_thread(), analog_ss_thread_start(), ast_format_set(), 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().
11067 { 11068 struct mwi_thread_data *mtd = data; 11069 struct callerid_state *cs; 11070 pthread_t threadid; 11071 int samples = 0; 11072 char *name, *number; 11073 int flags; 11074 int i, res; 11075 unsigned int spill_done = 0; 11076 int spill_result = -1; 11077 struct ast_format tmpfmt; 11078 11079 if (!(cs = callerid_new(mtd->pvt->cid_signalling))) { 11080 mtd->pvt->mwimonitoractive = 0; 11081 11082 return NULL; 11083 } 11084 11085 callerid_feed(cs, mtd->buf, mtd->len, ast_format_set(&tmpfmt, AST_LAW(mtd->pvt), 0)); 11086 11087 bump_gains(mtd->pvt); 11088 11089 for (;;) { 11090 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 11091 if ((res = ioctl(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_IOMUX, &i))) { 11092 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 11093 goto quit; 11094 } 11095 11096 if (i & DAHDI_IOMUX_SIGEVENT) { 11097 struct ast_channel *chan; 11098 11099 /* If we get an event, screen out events that we do not act on. 11100 * Otherwise, cancel and go to the simple switch to let it deal with it. 11101 */ 11102 res = dahdi_get_event(mtd->pvt->subs[SUB_REAL].dfd); 11103 11104 switch (res) { 11105 case DAHDI_EVENT_NEONMWI_ACTIVE: 11106 case DAHDI_EVENT_NEONMWI_INACTIVE: 11107 case DAHDI_EVENT_NONE: 11108 case DAHDI_EVENT_BITSCHANGED: 11109 break; 11110 case DAHDI_EVENT_NOALARM: 11111 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 11112 struct analog_pvt *analog_p = mtd->pvt->sig_pvt; 11113 11114 analog_p->inalarm = 0; 11115 } 11116 mtd->pvt->inalarm = 0; 11117 handle_clear_alarms(mtd->pvt); 11118 break; 11119 case DAHDI_EVENT_ALARM: 11120 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 11121 struct analog_pvt *analog_p = mtd->pvt->sig_pvt; 11122 11123 analog_p->inalarm = 1; 11124 } 11125 mtd->pvt->inalarm = 1; 11126 res = get_alarms(mtd->pvt); 11127 handle_alarms(mtd->pvt, res); 11128 break; /* What to do on channel alarm ???? -- fall thru intentionally?? */ 11129 default: 11130 ast_log(LOG_NOTICE, "Got event %d (%s)... Passing along to analog_ss_thread\n", res, event2str(res)); 11131 callerid_free(cs); 11132 11133 restore_gains(mtd->pvt); 11134 mtd->pvt->ringt = mtd->pvt->ringt_base; 11135 11136 if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, NULL))) { 11137 int result; 11138 if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) { 11139 result = analog_ss_thread_start(mtd->pvt->sig_pvt, chan); 11140 } else { 11141 result = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan); 11142 } 11143 if (result) { 11144 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", mtd->pvt->channel); 11145 res = tone_zone_play_tone(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION); 11146 if (res < 0) 11147 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", mtd->pvt->channel); 11148 ast_hangup(chan); 11149 goto quit; 11150 } 11151 goto quit_no_clean; 11152 11153 } else { 11154 ast_log(LOG_WARNING, "Could not create channel to handle call\n"); 11155 } 11156 } 11157 } else if (i & DAHDI_IOMUX_READ) { 11158 if ((res = read(mtd->pvt->subs[SUB_REAL].dfd, mtd->buf, sizeof(mtd->buf))) < 0) { 11159 if (errno != ELAST) { 11160 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 11161 goto quit; 11162 } 11163 break; 11164 } 11165 samples += res; 11166 if (!spill_done) { 11167 if ((spill_result = callerid_feed(cs, mtd->buf, res, ast_format_set(&tmpfmt, AST_LAW(mtd->pvt), 0))) < 0) { 11168 /* 11169 * The previous diagnostic message output likely 11170 * explains why it failed. 11171 */ 11172 ast_log(LOG_WARNING, "Failed to decode CallerID\n"); 11173 break; 11174 } else if (spill_result) { 11175 spill_done = 1; 11176 } 11177 } else { 11178 /* keep reading data until the energy level drops below the threshold 11179 so we don't get another 'trigger' on the remaining carrier signal 11180 */ 11181 if (calc_energy(mtd->buf, res, AST_LAW(mtd->pvt)) <= mwilevel) 11182 break; 11183 } 11184 if (samples > (8000 * 4)) /*Termination case - time to give up*/ 11185 break; 11186 } 11187 } 11188 11189 if (spill_result == 1) { 11190 callerid_get(cs, &name, &number, &flags); 11191 if (flags & CID_MSGWAITING) { 11192 ast_log(LOG_NOTICE, "mwi: Have Messages on channel %d\n", mtd->pvt->channel); 11193 notify_message(mtd->pvt->mailbox, 1); 11194 } else if (flags & CID_NOMSGWAITING) { 11195 ast_log(LOG_NOTICE, "mwi: No Messages on channel %d\n", mtd->pvt->channel); 11196 notify_message(mtd->pvt->mailbox, 0); 11197 } else { 11198 ast_log(LOG_NOTICE, "mwi: Status unknown on channel %d\n", mtd->pvt->channel); 11199 } 11200 } 11201 11202 11203 quit: 11204 callerid_free(cs); 11205 11206 restore_gains(mtd->pvt); 11207 11208 quit_no_clean: 11209 mtd->pvt->mwimonitoractive = 0; 11210 11211 ast_free(mtd); 11212 11213 return NULL; 11214 }
| static void my_all_subchannels_hungup | ( | void * | pvt | ) | [static] |
Definition at line 2417 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.
02418 { 02419 struct dahdi_pvt *p = pvt; 02420 int res, law; 02421 02422 p->faxhandled = 0; 02423 p->didtdd = 0; 02424 02425 if (p->dsp) { 02426 ast_dsp_free(p->dsp); 02427 p->dsp = NULL; 02428 } 02429 02430 p->law = p->law_default; 02431 law = p->law_default; 02432 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); 02433 if (res < 0) 02434 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno)); 02435 02436 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 02437 02438 #if 1 02439 { 02440 int i; 02441 p->owner = NULL; 02442 /* Cleanup owners here */ 02443 for (i = 0; i < 3; i++) { 02444 p->subs[i].owner = NULL; 02445 } 02446 } 02447 #endif 02448 02449 reset_conf(p); 02450 if (num_restart_pending == 0) { 02451 restart_monitor(); 02452 } 02453 }
| static int my_allocate_sub | ( | void * | pvt, | |
| enum analog_sub | analogsub | |||
| ) | [static] |
Definition at line 2728 of file chan_dahdi.c.
References alloc_sub(), and analogsub_to_dahdisub().
02729 { 02730 struct dahdi_pvt *p = pvt; 02731 02732 return alloc_sub(p, analogsub_to_dahdisub(analogsub)); 02733 }
| static void my_answer_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2966 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, and my_set_polarity().
02967 { 02968 struct dahdi_pvt *p = pvt; 02969 02970 if (!p->answeronpolarityswitch) { 02971 return; 02972 } 02973 02974 my_set_polarity(pvt, 1); 02975 }
| static int my_callwait | ( | void * | pvt | ) | [static] |
Definition at line 1919 of file chan_dahdi.c.
References ast_format_set(), 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().
01920 { 01921 struct dahdi_pvt *p = pvt; 01922 struct ast_format tmpfmt; 01923 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES; 01924 if (p->cidspill) { 01925 ast_log(LOG_WARNING, "Spill already exists?!?\n"); 01926 ast_free(p->cidspill); 01927 } 01928 01929 /* 01930 * SAS: Subscriber Alert Signal, 440Hz for 300ms 01931 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves 01932 */ 01933 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4))) 01934 return -1; 01935 save_conference(p); 01936 /* Silence */ 01937 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4); 01938 if (!p->callwaitrings && p->callwaitingcallerid) { 01939 ast_gen_cas(p->cidspill, 1, 2400 + 680, ast_format_set(&tmpfmt, AST_LAW(p), 0)); 01940 p->callwaitcas = 1; 01941 p->cidlen = 2400 + 680 + READ_SIZE * 4; 01942 } else { 01943 ast_gen_cas(p->cidspill, 1, 2400, ast_format_set(&tmpfmt, AST_LAW(p), 0)); 01944 p->callwaitcas = 0; 01945 p->cidlen = 2400 + READ_SIZE * 4; 01946 } 01947 p->cidpos = 0; 01948 send_callerid(p); 01949 01950 return 0; 01951 }
| static void my_cancel_cidspill | ( | void * | pvt | ) | [static] |
Definition at line 2367 of file chan_dahdi.c.
References ast_free, dahdi_pvt::cidspill, and restore_conference().
02368 { 02369 struct dahdi_pvt *p = pvt; 02370 02371 ast_free(p->cidspill); 02372 p->cidspill = NULL; 02373 restore_conference(p); 02374 }
| static int my_check_confirmanswer | ( | void * | pvt | ) | [static] |
Definition at line 2350 of file chan_dahdi.c.
References dahdi_pvt::confirmanswer.
02351 { 02352 struct dahdi_pvt *p = pvt; 02353 if (p->confirmanswer) { 02354 return 1; 02355 } 02356 02357 return 0; 02358 }
| static int my_check_for_conference | ( | void * | pvt | ) | [static] |
Definition at line 2527 of file chan_dahdi.c.
References check_for_conference().
02528 { 02529 struct dahdi_pvt *p = pvt; 02530 return check_for_conference(p); 02531 }
| static int my_check_waitingfordt | ( | void * | pvt | ) | [static] |
Definition at line 2333 of file chan_dahdi.c.
References dahdi_pvt::waitingfordt.
02334 { 02335 struct dahdi_pvt *p = pvt; 02336 02337 if (p->waitingfordt.tv_usec) { 02338 return 1; 02339 } 02340 02341 return 0; 02342 }
| static int my_complete_conference_update | ( | void * | pvt, | |
| int | needconference | |||
| ) | [static] |
Definition at line 2477 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.
02478 { 02479 struct dahdi_pvt *p = pvt; 02480 int needconf = needconference; 02481 int x; 02482 int useslavenative; 02483 struct dahdi_pvt *slave = NULL; 02484 02485 useslavenative = isslavenative(p, &slave); 02486 02487 /* If we have a slave, add him to our conference now. or DAX 02488 if this is slave native */ 02489 for (x = 0; x < MAX_SLAVES; x++) { 02490 if (p->slaves[x]) { 02491 if (useslavenative) 02492 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 02493 else { 02494 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 02495 needconf++; 02496 } 02497 } 02498 } 02499 /* If we're supposed to be in there, do so now */ 02500 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 02501 if (useslavenative) 02502 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 02503 else { 02504 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 02505 needconf++; 02506 } 02507 } 02508 /* If we have a master, add ourselves to his conference */ 02509 if (p->master) { 02510 if (isslavenative(p->master, NULL)) { 02511 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 02512 } else { 02513 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 02514 } 02515 } 02516 if (!needconf) { 02517 /* Nobody is left (or should be left) in our conference. 02518 Kill it. */ 02519 p->confno = -1; 02520 } 02521 02522 return 0; 02523 }
| static int my_conf_add | ( | void * | pvt, | |
| enum analog_sub | sub | |||
| ) | [static] |
Definition at line 2467 of file chan_dahdi.c.
References analogsub_to_dahdisub(), conf_add(), and dahdi_pvt::subs.
02468 { 02469 struct dahdi_pvt *p = pvt; 02470 int x = analogsub_to_dahdisub(sub); 02471 02472 return conf_add(p, &p->subs[x], x, 0); 02473 }
| static int my_conf_del | ( | void * | pvt, | |
| enum analog_sub | sub | |||
| ) | [static] |
Definition at line 2457 of file chan_dahdi.c.
References analogsub_to_dahdisub(), conf_del(), and dahdi_pvt::subs.
02458 { 02459 struct dahdi_pvt *p = pvt; 02460 int x = analogsub_to_dahdisub(sub); 02461 02462 return conf_del(p, &p->subs[x], x); 02463 }
| static int my_confmute | ( | void * | pvt, | |
| int | mute | |||
| ) | [static] |
Definition at line 2376 of file chan_dahdi.c.
References dahdi_confmute().
02377 { 02378 struct dahdi_pvt *p = pvt; 02379 return dahdi_confmute(p, mute); 02380 }
| static int my_dahdi_write | ( | struct dahdi_pvt * | p, | |
| unsigned char * | buf, | |||
| int | len, | |||
| int | idx, | |||
| int | linear | |||
| ) | [static] |
Definition at line 9344 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().
09345 { 09346 int sent=0; 09347 int size; 09348 int res; 09349 int fd; 09350 fd = p->subs[idx].dfd; 09351 while (len) { 09352 size = len; 09353 if (size > (linear ? READ_SIZE * 2 : READ_SIZE)) 09354 size = (linear ? READ_SIZE * 2 : READ_SIZE); 09355 res = write(fd, buf, size); 09356 if (res != size) { 09357 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel); 09358 return sent; 09359 } 09360 len -= size; 09361 buf += size; 09362 } 09363 return sent; 09364 }
| static void my_deadlock_avoidance_private | ( | void * | pvt | ) | [static] |
Definition at line 2139 of file chan_dahdi.c.
References DEADLOCK_AVOIDANCE, and dahdi_pvt::lock.
02140 { 02141 struct dahdi_pvt *p = pvt; 02142 02143 DEADLOCK_AVOIDANCE(&p->lock); 02144 }
| static void my_decrease_ss_count | ( | void | ) | [static] |
Definition at line 2409 of file chan_dahdi.c.
References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, and ss_thread_lock.
02410 { 02411 ast_mutex_lock(&ss_thread_lock); 02412 ss_thread_count--; 02413 ast_cond_signal(&ss_thread_complete); 02414 ast_mutex_unlock(&ss_thread_lock); 02415 }
| static int my_dial_digits | ( | void * | pvt, | |
| enum analog_sub | sub, | |||
| struct analog_dialoperation * | dop | |||
| ) | [static] |
Definition at line 3000 of file chan_dahdi.c.
References ANALOG_DIAL_OP_REPLACE, ANALOG_SUB_REAL, analogsub_to_dahdisub(), ast_channel_name(), 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.
03001 { 03002 int index = analogsub_to_dahdisub(sub); 03003 int res; 03004 struct dahdi_pvt *p = pvt; 03005 struct dahdi_dialoperation ddop; 03006 03007 if (dop->op != ANALOG_DIAL_OP_REPLACE) { 03008 ast_log(LOG_ERROR, "Fix the dial_digits callback!\n"); 03009 return -1; 03010 } 03011 03012 if (sub != ANALOG_SUB_REAL) { 03013 ast_log(LOG_ERROR, "Trying to dial_digits '%s' on channel %d subchannel %d\n", 03014 dop->dialstr, p->channel, sub); 03015 return -1; 03016 } 03017 03018 ddop.op = DAHDI_DIAL_OP_REPLACE; 03019 ast_copy_string(ddop.dialstr, dop->dialstr, sizeof(ddop.dialstr)); 03020 03021 ast_debug(1, "Channel %d: Sending '%s' to DAHDI_DIAL.\n", p->channel, ddop.dialstr); 03022 03023 res = ioctl(p->subs[index].dfd, DAHDI_DIAL, &ddop); 03024 if (res == -1) { 03025 ast_debug(1, "DAHDI_DIAL ioctl failed on %s: %s\n", ast_channel_name(p->owner), strerror(errno)); 03026 } 03027 03028 return res; 03029 }
| static int my_distinctive_ring | ( | struct ast_channel * | chan, | |
| void * | pvt, | |||
| int | idx, | |||
| int * | ringdata | |||
| ) | [static] |
Definition at line 1783 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.
01784 { 01785 unsigned char buf[256]; 01786 int distMatches; 01787 int curRingData[RING_PATTERNS]; 01788 int receivedRingT; 01789 int counter1; 01790 int counter; 01791 int i; 01792 int res; 01793 int checkaftercid = 0; 01794 01795 struct dahdi_pvt *p = pvt; 01796 struct analog_pvt *analog_p = p->sig_pvt; 01797 01798 if (ringdata == NULL) { 01799 ringdata = curRingData; 01800 } else { 01801 checkaftercid = 1; 01802 } 01803 01804 /* We must have a ring by now, so, if configured, lets try to listen for 01805 * distinctive ringing */ 01806 if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) { 01807 /* Clear the current ring data array so we don't have old data in it. */ 01808 for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++) 01809 ringdata[receivedRingT] = 0; 01810 receivedRingT = 0; 01811 if (checkaftercid && distinctiveringaftercid) 01812 ast_verb(3, "Detecting post-CID distinctive ring\n"); 01813 /* Check to see if context is what it should be, if not set to be. */ 01814 else if (strcmp(p->context,p->defcontext) != 0) { 01815 ast_copy_string(p->context, p->defcontext, sizeof(p->context)); 01816 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context)); 01817 } 01818 01819 for (;;) { 01820 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT; 01821 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) { 01822 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno)); 01823 ast_hangup(chan); 01824 return 1; 01825 } 01826 if (i & DAHDI_IOMUX_SIGEVENT) { 01827 res = dahdi_get_event(p->subs[idx].dfd); 01828 if (res == DAHDI_EVENT_NOALARM) { 01829 p->inalarm = 0; 01830 analog_p->inalarm = 0; 01831 } 01832 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res)); 01833 res = 0; 01834 /* Let us detect distinctive ring */ 01835 01836 ringdata[receivedRingT] = analog_p->ringt; 01837 01838 if (analog_p->ringt < analog_p->ringt_base/2) 01839 break; 01840 /* Increment the ringT counter so we can match it against 01841 values in chan_dahdi.conf for distinctive ring */ 01842 if (++receivedRingT == RING_PATTERNS) 01843 break; 01844 } else if (i & DAHDI_IOMUX_READ) { 01845 res = read(p->subs[idx].dfd, buf, sizeof(buf)); 01846 if (res < 0) { 01847 if (errno != ELAST) { 01848 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 01849 ast_hangup(chan); 01850 return 1; 01851 } 01852 break; 01853 } 01854 if (analog_p->ringt > 0) { 01855 if (!(--analog_p->ringt)) { 01856 res = -1; 01857 break; 01858 } 01859 } 01860 } 01861 } 01862 } 01863 if ((checkaftercid && usedistinctiveringdetection) || !checkaftercid) { 01864 /* this only shows up if you have n of the dring patterns filled in */ 01865 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",ringdata[0],ringdata[1],ringdata[2]); 01866 for (counter = 0; counter < 3; counter++) { 01867 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */ 01868 distMatches = 0; 01869 /* this only shows up if you have n of the dring patterns filled in */ 01870 ast_verb(3, "Checking %d,%d,%d\n", 01871 p->drings.ringnum[counter].ring[0], 01872 p->drings.ringnum[counter].ring[1], 01873 p->drings.ringnum[counter].ring[2]); 01874 for (counter1 = 0; counter1 < 3; counter1++) { 01875 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range); 01876 if (p->drings.ringnum[counter].ring[counter1] == -1) { 01877 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n", 01878 ringdata[counter1]); 01879 distMatches++; 01880 } else if (ringdata[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) && 01881 ringdata[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) { 01882 ast_verb(3, "Ring pattern matched in range: %d to %d\n", 01883 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range), 01884 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range)); 01885 distMatches++; 01886 } 01887 } 01888 01889 if (distMatches == 3) { 01890 /* The ring matches, set the context to whatever is for distinctive ring.. */ 01891 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context)); 01892 ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context)); 01893 ast_verb(3, "Distinctive Ring matched context %s\n",p->context); 01894 break; 01895 } 01896 } 01897 } 01898 /* Restore linear mode (if appropriate) for Caller*ID processing */ 01899 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear); 01900 restore_gains(p); 01901 01902 return 0; 01903 }
| static int my_dsp_reset_and_flush_digits | ( | void * | pvt | ) | [static] |
Definition at line 1989 of file chan_dahdi.c.
References ast_dsp_digitreset(), and dahdi_pvt::dsp.
01990 { 01991 struct dahdi_pvt *p = pvt; 01992 if (p->dsp) 01993 ast_dsp_digitreset(p->dsp); 01994 01995 return 0; 01996 }
| static int my_dsp_set_digitmode | ( | void * | pvt, | |
| enum analog_dsp_digitmode | mode | |||
| ) | [static] |
Definition at line 1998 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.
01999 { 02000 struct dahdi_pvt *p = pvt; 02001 02002 if (p->channel == CHAN_PSEUDO) 02003 ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n"); 02004 02005 if (mode == ANALOG_DIGITMODE_DTMF) { 02006 /* If we do hardware dtmf, no need for a DSP */ 02007 if (p->hardwaredtmf) { 02008 if (p->dsp) { 02009 ast_dsp_free(p->dsp); 02010 p->dsp = NULL; 02011 } 02012 return 0; 02013 } 02014 02015 if (!p->dsp) { 02016 p->dsp = ast_dsp_new(); 02017 if (!p->dsp) { 02018 ast_log(LOG_ERROR, "Unable to allocate DSP\n"); 02019 return -1; 02020 } 02021 } 02022 02023 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); 02024 } else if (mode == ANALOG_DIGITMODE_MF) { 02025 if (!p->dsp) { 02026 p->dsp = ast_dsp_new(); 02027 if (!p->dsp) { 02028 ast_log(LOG_ERROR, "Unable to allocate DSP\n"); 02029 return -1; 02030 } 02031 } 02032 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax); 02033 } 02034 return 0; 02035 }
| static int my_flash | ( | void * | pvt | ) | [static] |
Definition at line 2925 of file chan_dahdi.c.
References dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.
02926 { 02927 struct dahdi_pvt *p = pvt; 02928 int func = DAHDI_FLASH; 02929 return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func); 02930 }
| static void my_get_and_handle_alarms | ( | void * | pvt | ) | [static] |
Definition at line 2225 of file chan_dahdi.c.
References get_alarms(), and handle_alarms().
02226 { 02227 int res; 02228 struct dahdi_pvt *p = pvt; 02229 02230 res = get_alarms(p); 02231 handle_alarms(p, res); 02232 }
| static int my_get_callerid | ( | void * | pvt, | |
| char * | namebuf, | |||
| char * | numbuf, | |||
| enum analog_event * | ev, | |||
| size_t | timeout | |||
| ) | [static] |
Definition at line 1705 of file chan_dahdi.c.
References ANALOG_EVENT_NONE, ANALOG_MAX_CID, ast_copy_string(), ast_debug, ast_format_set(), AST_LAW, ast_log(), callerid_feed(), callerid_feed_jp(), callerid_free(), callerid_get(), CID_SIG_V23_JP, dahdi_pvt::cid_signalling, dahdi_pvt::cs, dahdi_get_event(), dahdievent_to_analogevent(), dahdi_subchannel::dfd, errno, LOG_WARNING, name, analog_pvt::ringt, dahdi_pvt::sig_pvt, SUB_REAL, and dahdi_pvt::subs.
01706 { 01707 struct dahdi_pvt *p = pvt; 01708 struct analog_pvt *analog_p = p->sig_pvt; 01709 struct pollfd poller; 01710 char *name, *num; 01711 int index = SUB_REAL; 01712 int res; 01713 unsigned char buf[256]; 01714 int flags; 01715 struct ast_format tmpfmt; 01716 01717 poller.fd = p->subs[SUB_REAL].dfd; 01718 poller.events = POLLPRI | POLLIN; 01719 poller.revents = 0; 01720 01721 res = poll(&poller, 1, timeout); 01722 01723 if (poller.revents & POLLPRI) { 01724 *ev = dahdievent_to_analogevent(dahdi_get_event(p->subs[SUB_REAL].dfd)); 01725 return 1; 01726 } 01727 01728 if (poller.revents & POLLIN) { 01729 /*** NOTES ***/ 01730 /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function 01731 * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until 01732 * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be 01733 * a failure and die, and returning 2 means no event was received. */ 01734 res = read(p->subs[index].dfd, buf, sizeof(buf)); 01735 if (res < 0) { 01736 if (errno != ELAST) { 01737 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno)); 01738 callerid_free(p->cs); 01739 return -1; 01740 } 01741 } 01742 01743 if (analog_p->ringt > 0) { 01744 if (!(--analog_p->ringt)) { 01745 /* only return if we timeout from a ring event */ 01746 return -1; 01747 } 01748 } 01749 01750 if (p->cid_signalling == CID_SIG_V23_JP) { 01751 res = callerid_feed_jp(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0)); 01752 } else { 01753 res = callerid_feed(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0)); 01754 } 01755 if (res < 0) { 01756 /* 01757 * The previous diagnostic message output likely 01758 * explains why it failed. 01759 */ 01760 ast_log(LOG_WARNING, "Failed to decode CallerID\n"); 01761 return -1; 01762 } 01763 01764 if (res == 1) { 01765 callerid_get(p->cs, &name, &num, &flags); 01766 if (name) 01767 ast_copy_string(namebuf, name, ANALOG_MAX_CID); 01768 if (num) 01769 ast_copy_string(numbuf, num, ANALOG_MAX_CID); 01770 01771 ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags); 01772 return 0; 01773 } 01774 } 01775 01776 *ev = ANALOG_EVENT_NONE; 01777 return 2; 01778 }
| static int my_get_event | ( | void * | pvt | ) | [static] |
Definition at line 2858 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.
02859 { 02860 struct dahdi_pvt *p = pvt; 02861 int res; 02862 02863 if (p->fake_event) { 02864 res = p->fake_event; 02865 p->fake_event = 0; 02866 } else 02867 res = dahdi_get_event(p->subs[SUB_REAL].dfd); 02868 02869 return dahdievent_to_analogevent(res); 02870 }
| static const char* my_get_orig_dialstring | ( | void * | pvt | ) | [static] |
Definition at line 2395 of file chan_dahdi.c.
References dahdi_pvt::dialstring.
02396 { 02397 struct dahdi_pvt *p = pvt; 02398 02399 return p->dialstring; 02400 }
| static void* my_get_sigpvt_bridged_channel | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 2234 of file chan_dahdi.c.
References ast_bridged_channel(), dahdi_pvt::sig_pvt, and ast_channel::tech_pvt.
02235 { 02236 struct dahdi_pvt *p = ast_bridged_channel(chan)->tech_pvt; 02237 if (p) 02238 return p->sig_pvt; 02239 else 02240 return NULL; 02241 }
| static int my_get_sub_fd | ( | void * | pvt, | |
| enum analog_sub | sub | |||
| ) | [static] |
Definition at line 2243 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
02244 { 02245 struct dahdi_pvt *p = pvt; 02246 int dahdi_sub = analogsub_to_dahdisub(sub); 02247 return p->subs[dahdi_sub].dfd; 02248 }
| static int my_getsigstr | ( | struct ast_channel * | chan, | |
| char * | str, | |||
| const char * | term, | |||
| int | ms | |||
| ) | [static] |
Definition at line 9821 of file chan_dahdi.c.
References ast_waitfordigit().
Referenced by analog_ss_thread().
09822 { 09823 char c; 09824 09825 *str = 0; /* start with empty output buffer */ 09826 for (;;) 09827 { 09828 /* Wait for the first digit (up to specified ms). */ 09829 c = ast_waitfordigit(chan, ms); 09830 /* if timeout, hangup or error, return as such */ 09831 if (c < 1) 09832 return c; 09833 *str++ = c; 09834 *str = 0; 09835 if (strchr(term, c)) 09836 return 1; 09837 } 09838 }
| static void my_handle_dtmf | ( | void * | pvt, | |
| struct ast_channel * | ast, | |||
| enum analog_sub | analog_index, | |||
| struct ast_frame ** | dest | |||
| ) | [static] |
Definition at line 2055 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_async_goto(), ast_channel_lock, ast_channel_name(), 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.
02056 { 02057 struct ast_frame *f = *dest; 02058 struct dahdi_pvt *p = pvt; 02059 int idx = analogsub_to_dahdisub(analog_index); 02060 02061 ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n", 02062 f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End", 02063 f->subclass.integer, f->subclass.integer, ast_channel_name(ast)); 02064 02065 if (f->subclass.integer == 'f') { 02066 if (f->frametype == AST_FRAME_DTMF_END) { 02067 /* Fax tone -- Handle and return NULL */ 02068 if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) { 02069 /* If faxbuffers are configured, use them for the fax transmission */ 02070 if (p->usefaxbuffers && !p->bufferoverrideinuse) { 02071 struct dahdi_bufferinfo bi = { 02072 .txbufpolicy = p->faxbuf_policy, 02073 .bufsize = p->bufsize, 02074 .numbufs = p->faxbuf_no 02075 }; 02076 int res; 02077 02078 if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 02079 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno)); 02080 } else { 02081 p->bufferoverrideinuse = 1; 02082 } 02083 } 02084 p->faxhandled = 1; 02085 if (p->dsp) { 02086 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT; 02087 ast_dsp_set_features(p->dsp, p->dsp_features); 02088 ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast)); 02089 } 02090 if (strcmp(ast->exten, "fax")) { 02091 const char *target_context = S_OR(ast->macrocontext, ast->context); 02092 02093 /* We need to unlock 'ast' here because ast_exists_extension has the 02094 * potential to start autoservice on the channel. Such action is prone 02095 * to deadlock. 02096 */ 02097 ast_mutex_unlock(&p->lock); 02098 ast_channel_unlock(ast); 02099 if (ast_exists_extension(ast, target_context, "fax", 1, 02100 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 02101 ast_channel_lock(ast); 02102 ast_mutex_lock(&p->lock); 02103 ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast)); 02104 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 02105 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten); 02106 if (ast_async_goto(ast, target_context, "fax", 1)) 02107 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context); 02108 } else { 02109 ast_channel_lock(ast); 02110 ast_mutex_lock(&p->lock); 02111 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 02112 } 02113 } else { 02114 ast_debug(1, "Already in a fax extension, not redirecting\n"); 02115 } 02116 } else { 02117 ast_debug(1, "Fax already handled\n"); 02118 } 02119 dahdi_confmute(p, 0); 02120 } 02121 p->subs[idx].f.frametype = AST_FRAME_NULL; 02122 p->subs[idx].f.subclass.integer = 0; 02123 *dest = &p->subs[idx].f; 02124 } 02125 }
| static void my_handle_notify_message | ( | struct ast_channel * | chan, | |
| void * | pvt, | |||
| int | cid_flags, | |||
| int | neon_mwievent | |||
| ) | [static] |
Definition at line 3630 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().
03631 { 03632 struct dahdi_pvt *p = pvt; 03633 03634 if (neon_mwievent > -1 && !p->mwimonitor_neon) 03635 return; 03636 03637 if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) { 03638 ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox); 03639 notify_message(p->mailbox, 1); 03640 } else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) { 03641 ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox); 03642 notify_message(p->mailbox, 0); 03643 } 03644 /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */ 03645 /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */ 03646 if (neon_mwievent == -1 && p->mwimonitor_rpas) { 03647 ast_hangup(chan); 03648 return; 03649 } 03650 }
| static void my_hangup_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2977 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, dahdi_pvt::hanguponpolarityswitch, and my_set_polarity().
02978 { 02979 struct dahdi_pvt *p = pvt; 02980 02981 if (!p->hanguponpolarityswitch) { 02982 return; 02983 } 02984 02985 if (p->answeronpolarityswitch) { 02986 my_set_polarity(pvt, 0); 02987 } else { 02988 my_set_polarity(pvt, 1); 02989 } 02990 }
| static int my_has_voicemail | ( | void * | pvt | ) | [static] |
Definition at line 2737 of file chan_dahdi.c.
References has_voicemail().
02738 { 02739 struct dahdi_pvt *p = pvt; 02740 02741 return has_voicemail(p); 02742 }
| static int my_have_progressdetect | ( | void * | pvt | ) | [static] |
Definition at line 3652 of file chan_dahdi.c.
References dahdi_pvt::callprogress, CALLPROGRESS_PROGRESS, CANPROGRESSDETECT, dahdi_pvt::dsp, and dahdi_pvt::outgoing.
03653 { 03654 struct dahdi_pvt *p = pvt; 03655 03656 if ((p->callprogress & CALLPROGRESS_PROGRESS) 03657 && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) { 03658 return 1; 03659 } else { 03660 /* Don't have progress detection. */ 03661 return 0; 03662 } 03663 }
| static void my_increase_ss_count | ( | void | ) | [static] |
Definition at line 2402 of file chan_dahdi.c.
References ast_mutex_lock, ast_mutex_unlock, and ss_thread_lock.
02403 { 02404 ast_mutex_lock(&ss_thread_lock); 02405 ss_thread_count++; 02406 ast_mutex_unlock(&ss_thread_lock); 02407 }
| static int my_is_dialing | ( | void * | pvt, | |
| enum analog_sub | sub | |||
| ) | [static] |
Definition at line 3042 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_debug, dahdi_subchannel::dfd, and dahdi_pvt::subs.
03043 { 03044 struct dahdi_pvt *p = pvt; 03045 int index; 03046 int x; 03047 03048 index = analogsub_to_dahdisub(sub); 03049 03050 if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) { 03051 ast_debug(1, "DAHDI_DIALING ioctl failed!\n"); 03052 return -1; 03053 } 03054 03055 return x; 03056 }
| static int my_is_off_hook | ( | void * | pvt | ) | [static] |
Definition at line 2872 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.
02873 { 02874 struct dahdi_pvt *p = pvt; 02875 int res; 02876 struct dahdi_params par; 02877 02878 memset(&par, 0, sizeof(par)); 02879 02880 if (p->subs[SUB_REAL].dfd > -1) 02881 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par); 02882 else { 02883 /* Assume not off hook on CVRS */ 02884 res = 0; 02885 par.rxisoffhook = 0; 02886 } 02887 if (res) { 02888 ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno)); 02889 } 02890 02891 if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) { 02892 /* When "onhook" that means no battery on the line, and thus 02893 it is out of service..., if it's on a TDM card... If it's a channel 02894 bank, there is no telling... */ 02895 return (par.rxbits > -1) || par.rxisoffhook; 02896 } 02897 02898 return par.rxisoffhook; 02899 }
| static void my_lock_private | ( | void * | pvt | ) | [static] |
Definition at line 2127 of file chan_dahdi.c.
References ast_mutex_lock, and dahdi_pvt::lock.
02128 { 02129 struct dahdi_pvt *p = pvt; 02130 ast_mutex_lock(&p->lock); 02131 }
| 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 2567 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_channel_linkedid(), and dahdi_new().
02568 { 02569 struct dahdi_pvt *p = pvt; 02570 int dsub = analogsub_to_dahdisub(sub); 02571 02572 return dahdi_new(p, state, startpbx, dsub, 0, requestor ? ast_channel_linkedid(requestor) : ""); 02573 }
| static int my_off_hook | ( | void * | pvt | ) | [static] |
Definition at line 2934 of file chan_dahdi.c.
References dahdi_set_hook(), dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.
02935 { 02936 struct dahdi_pvt *p = pvt; 02937 return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK); 02938 }
| static int my_on_hook | ( | void * | pvt | ) | [static] |
Definition at line 3058 of file chan_dahdi.c.
References ANALOG_SUB_REAL, dahdi_set_hook(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
03059 { 03060 struct dahdi_pvt *p = pvt; 03061 return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK); 03062 }
| static int my_play_tone | ( | void * | pvt, | |
| enum analog_sub | sub, | |||
| enum analog_tone | tone | |||
| ) | [static] |
Definition at line 2744 of file chan_dahdi.c.
References analog_tone_to_dahditone(), analogsub_to_dahdisub(), dahdi_subchannel::dfd, and dahdi_pvt::subs.
02745 { 02746 struct dahdi_pvt *p = pvt; 02747 int index; 02748 02749 index = analogsub_to_dahdisub(sub); 02750 02751 return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone)); 02752 }
| static int my_ring | ( | void * | pvt | ) | [static] |
Definition at line 2918 of file chan_dahdi.c.
References dahdi_ring_phone().
02919 { 02920 struct dahdi_pvt *p = pvt; 02921 02922 return dahdi_ring_phone(p); 02923 }
| static int my_send_callerid | ( | void * | pvt, | |
| int | cwcid, | |||
| struct ast_party_caller * | caller | |||
| ) | [static] |
Definition at line 1953 of file chan_dahdi.c.
References ast_callerid_callwaiting_generate(), ast_callerid_generate(), ast_debug, ast_format_set(), 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.
01954 { 01955 struct dahdi_pvt *p = pvt; 01956 struct ast_format tmpfmt; 01957 01958 ast_debug(2, "Starting cid spill\n"); 01959 01960 if (p->cidspill) { 01961 ast_log(LOG_WARNING, "cidspill already exists??\n"); 01962 ast_free(p->cidspill); 01963 } 01964 01965 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) { 01966 if (cwcid == 0) { 01967 p->cidlen = ast_callerid_generate(p->cidspill, 01968 caller->id.name.str, 01969 caller->id.number.str, 01970 ast_format_set(&tmpfmt, AST_LAW(p), 0)); 01971 } else { 01972 ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", 01973 caller->id.name.str, caller->id.number.str); 01974 p->callwaitcas = 0; 01975 p->cidcwexpire = 0; 01976 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, 01977 caller->id.name.str, 01978 caller->id.number.str, 01979 ast_format_set(&tmpfmt, AST_LAW(p), 0)); 01980 p->cidlen += READ_SIZE * 4; 01981 } 01982 p->cidpos = 0; 01983 p->cid_suppress_expire = 0; 01984 send_callerid(p); 01985 } 01986 return 0; 01987 }
| static void my_set_alarm | ( | void * | pvt, | |
| int | in_alarm | |||
| ) | [static] |
| static void my_set_cadence | ( | void * | pvt, | |
| int * | cidrings, | |||
| struct ast_channel * | ast | |||
| ) | [static] |
Definition at line 2250 of file chan_dahdi.c.
References ast_channel_name(), ast_log(), dahdi_subchannel::dfd, dahdi_pvt::distinctivering, errno, LOG_WARNING, dahdi_pvt::sendcalleridafter, SUB_REAL, and dahdi_pvt::subs.
02251 { 02252 struct dahdi_pvt *p = pvt; 02253 02254 /* Choose proper cadence */ 02255 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) { 02256 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1])) 02257 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast_channel_name(ast), strerror(errno)); 02258 *cidrings = cidrings[p->distinctivering - 1]; 02259 } else { 02260 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL)) 02261 ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast_channel_name(ast), strerror(errno)); 02262 *cidrings = p->sendcalleridafter; 02263 } 02264 }
| static void my_set_callwaiting | ( | void * | pvt, | |
| int | callwaiting_enable | |||
| ) | [static] |
Definition at line 2360 of file chan_dahdi.c.
References dahdi_pvt::callwaiting.
02361 { 02362 struct dahdi_pvt *p = pvt; 02363 02364 p->callwaiting = callwaiting_enable; 02365 }
| static void my_set_confirmanswer | ( | void * | pvt, | |
| int | flag | |||
| ) | [static] |
Definition at line 2344 of file chan_dahdi.c.
References dahdi_pvt::confirmanswer.
02345 { 02346 struct dahdi_pvt *p = pvt; 02347 p->confirmanswer = flag; 02348 }
| static void my_set_dialing | ( | void * | pvt, | |
| int | is_dialing | |||
| ) | [static] |
| static int my_set_echocanceller | ( | void * | pvt, | |
| int | enable | |||
| ) | [static] |
Definition at line 2904 of file chan_dahdi.c.
References dahdi_disable_ec(), and dahdi_enable_ec().
02905 { 02906 struct dahdi_pvt *p = pvt; 02907 02908 if (enable) 02909 dahdi_enable_ec(p); 02910 else 02911 dahdi_disable_ec(p); 02912 02913 return 0; 02914 }
| static void my_set_inthreeway | ( | void * | pvt, | |
| enum analog_sub | sub, | |||
| int | inthreeway | |||
| ) | [static] |
Definition at line 2215 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_subchannel::inthreeway, and dahdi_pvt::subs.
02216 { 02217 struct dahdi_pvt *p = pvt; 02218 int idx = analogsub_to_dahdisub(sub); 02219 02220 p->subs[idx].inthreeway = inthreeway; 02221 }
| static int my_set_linear_mode | ( | void * | pvt, | |
| enum analog_sub | sub, | |||
| int | linear_mode | |||
| ) | [static] |
Definition at line 2203 of file chan_dahdi.c.
References analogsub_to_dahdisub(), dahdi_setlinear(), dahdi_subchannel::dfd, dahdi_subchannel::linear, and dahdi_pvt::subs.
02204 { 02205 struct dahdi_pvt *p = pvt; 02206 int oldval; 02207 int idx = analogsub_to_dahdisub(sub); 02208 02209 dahdi_setlinear(p->subs[idx].dfd, linear_mode); 02210 oldval = p->subs[idx].linear; 02211 p->subs[idx].linear = linear_mode ? 1 : 0; 02212 return oldval; 02213 }
| static void my_set_needringing | ( | void * | pvt, | |
| int | value | |||
| ) | [static] |
Definition at line 2940 of file chan_dahdi.c.
References dahdi_subchannel::needringing, SUB_REAL, and dahdi_pvt::subs.
02941 { 02942 struct dahdi_pvt *p = pvt; 02943 p->subs[SUB_REAL].needringing = value; 02944 }
| static void my_set_new_owner | ( | void * | pvt, | |
| struct ast_channel * | new_owner | |||
| ) | [static] |
| static void my_set_polarity | ( | void * | pvt, | |
| int | value | |||
| ) | [static] |
Definition at line 2946 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().
02947 { 02948 struct dahdi_pvt *p = pvt; 02949 02950 if (p->channel == CHAN_PSEUDO) { 02951 return; 02952 } 02953 p->polarity = value; 02954 ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETPOLARITY, &value); 02955 }
| static void my_set_pulsedial | ( | void * | pvt, | |
| int | flag | |||
| ) | [static] |
| static void my_set_ringtimeout | ( | void * | pvt, | |
| int | ringt | |||
| ) | [static] |
| static void my_set_waitingfordt | ( | void * | pvt, | |
| struct ast_channel * | ast | |||
| ) | [static] |
Definition at line 2322 of file chan_dahdi.c.
References ast_debug, ast_setstate(), AST_STATE_OFFHOOK, CANPROGRESSDETECT, dahdi_pvt::dsp, dahdi_pvt::waitfordialtone, and dahdi_pvt::waitingfordt.
02323 { 02324 struct dahdi_pvt *p = pvt; 02325 02326 if (p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp) { 02327 ast_debug(1, "Defer dialing for %dms or dialtone\n", p->waitfordialtone); 02328 gettimeofday(&p->waitingfordt, NULL); 02329 ast_setstate(ast, AST_STATE_OFFHOOK); 02330 } 02331 }
| static int my_start | ( | void * | pvt | ) | [static] |
Definition at line 2992 of file chan_dahdi.c.
References dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.
02993 { 02994 struct dahdi_pvt *p = pvt; 02995 int x = DAHDI_START; 02996 02997 return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); 02998 }
| static int my_start_cid_detect | ( | void * | pvt, | |
| int | cid_signalling | |||
| ) | [static] |
Definition at line 1680 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.
01681 { 01682 struct dahdi_pvt *p = pvt; 01683 int index = SUB_REAL; 01684 p->cs = callerid_new(cid_signalling); 01685 if (!p->cs) { 01686 ast_log(LOG_ERROR, "Unable to alloc callerid\n"); 01687 return -1; 01688 } 01689 bump_gains(p); 01690 dahdi_setlinear(p->subs[index].dfd, 0); 01691 01692 return 0; 01693 }
| static void my_start_polarityswitch | ( | void * | pvt | ) | [static] |
Definition at line 2957 of file chan_dahdi.c.
References dahdi_pvt::answeronpolarityswitch, dahdi_pvt::hanguponpolarityswitch, and my_set_polarity().
02958 { 02959 struct dahdi_pvt *p = pvt; 02960 02961 if (p->answeronpolarityswitch || p->hanguponpolarityswitch) { 02962 my_set_polarity(pvt, 0); 02963 } 02964 }
| static int my_stop_callwait | ( | void * | pvt | ) | [static] |
Definition at line 1905 of file chan_dahdi.c.
References dahdi_pvt::callwaitingrepeat, dahdi_pvt::cid_suppress_expire, and dahdi_pvt::cidcwexpire.
01906 { 01907 struct dahdi_pvt *p = pvt; 01908 p->callwaitingrepeat = 0; 01909 p->cidcwexpire = 0; 01910 p->cid_suppress_expire = 0; 01911 01912 return 0; 01913 }
| static int my_stop_cid_detect | ( | void * | pvt | ) | [static] |
Definition at line 1695 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.
01696 { 01697 struct dahdi_pvt *p = pvt; 01698 int index = SUB_REAL; 01699 if (p->cs) 01700 callerid_free(p->cs); 01701 dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear); 01702 return 0; 01703 }
| 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 2533 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().
02534 { 02535 struct dahdi_pvt *p = pvt; 02536 int da, db; 02537 int tchan; 02538 int tinthreeway; 02539 02540 da = analogsub_to_dahdisub(a); 02541 db = analogsub_to_dahdisub(b); 02542 02543 tchan = p->subs[da].chan; 02544 p->subs[da].chan = p->subs[db].chan; 02545 p->subs[db].chan = tchan; 02546 02547 tinthreeway = p->subs[da].inthreeway; 02548 p->subs[da].inthreeway = p->subs[db].inthreeway; 02549 p->subs[db].inthreeway = tinthreeway; 02550 02551 p->subs[da].owner = ast_a; 02552 p->subs[db].owner = ast_b; 02553 02554 if (ast_a) 02555 ast_channel_set_fd(ast_a, 0, p->subs[da].dfd); 02556 if (ast_b) 02557 ast_channel_set_fd(ast_b, 0, p->subs[db].dfd); 02558 02559 wakeup_sub(p, a); 02560 wakeup_sub(p, b); 02561 02562 return; 02563 }
| static int my_train_echocanceller | ( | void * | pvt | ) | [static] |
Definition at line 3033 of file chan_dahdi.c.
References dahdi_train_ec().
03034 { 03035 struct dahdi_pvt *p = pvt; 03036 03037 dahdi_train_ec(p); 03038 03039 return 0; 03040 }
| static int my_unallocate_sub | ( | void * | pvt, | |
| enum analog_sub | analogsub | |||
| ) | [static] |
Definition at line 2719 of file chan_dahdi.c.
References analogsub_to_dahdisub(), and unalloc_sub().
02720 { 02721 struct dahdi_pvt *p = pvt; 02722 02723 return unalloc_sub(p, analogsub_to_dahdisub(analogsub)); 02724 }
| static void my_unlock_private | ( | void * | pvt | ) | [static] |
Definition at line 2133 of file chan_dahdi.c.
References ast_mutex_unlock, and dahdi_pvt::lock.
02134 { 02135 struct dahdi_pvt *p = pvt; 02136 ast_mutex_unlock(&p->lock); 02137 }
| static int my_wait_event | ( | void * | pvt | ) | [static] |
Definition at line 2851 of file chan_dahdi.c.
References dahdi_wait_event(), dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.
02852 { 02853 struct dahdi_pvt *p = pvt; 02854 02855 return dahdi_wait_event(p->subs[SUB_REAL].dfd); 02856 }
| static int my_wink | ( | void * | pvt, | |
| enum analog_sub | sub | |||
| ) | [static] |
Definition at line 2039 of file chan_dahdi.c.
References analogsub_to_dahdisub(), ast_log(), dahdi_wink(), LOG_ERROR, and SUB_REAL.
02040 { 02041 struct dahdi_pvt *p = pvt; 02042 int index = analogsub_to_dahdisub(sub); 02043 if (index != SUB_REAL) { 02044 ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n"); 02045 } 02046 return dahdi_wink(p, index); 02047 }
| static void notify_message | ( | char * | mailbox_full, | |
| int | thereornot | |||
| ) | [static] |
Send MWI state change.
1) It generates an internal Asterisk event notifying any other module that cares about MWI that the state of a mailbox has changed.
2) It runs the script specified by the mwimonitornotify option to allow some custom handling of the state change.
Definition at line 3601 of file chan_dahdi.c.
References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_safe_system(), ast_strdupa, ast_strlen_zero(), context, mailbox, and strsep().
Referenced by handle_init_event(), mwi_thread(), and my_handle_notify_message().
03602 { 03603 char s[sizeof(mwimonitornotify) + 80]; 03604 struct ast_event *event; 03605 char *mailbox, *context; 03606 03607 /* Strip off @default */ 03608 context = mailbox = ast_strdupa(mailbox_full); 03609 strsep(&context, "@"); 03610 if (ast_strlen_zero(context)) 03611 context = "default"; 03612 03613 if (!(event = ast_event_new(AST_EVENT_MWI, 03614 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 03615 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 03616 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot, 03617 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot, 03618 AST_EVENT_IE_END))) { 03619 return; 03620 } 03621 03622 ast_event_queue_and_cache(event); 03623 03624 if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) { 03625 snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot); 03626 ast_safe_system(s); 03627 } 03628 }
| static int parse_buffers_policy | ( | const char * | parse, | |
| int * | num_buffers, | |||
| int * | policy | |||
| ) | [static] |
Definition at line 7056 of file chan_dahdi.c.
References ast_log(), and LOG_WARNING.
Referenced by dahdi_func_write(), and process_dahdi().
07057 { 07058 int res; 07059 char policy_str[21] = ""; 07060 07061 if ((res = sscanf(parse, "%30d,%20s", num_buffers, policy_str)) != 2) { 07062 ast_log(LOG_WARNING, "Parsing buffer string '%s' failed.\n", parse); 07063 return 1; 07064 } 07065 if (*num_buffers < 0) { 07066 ast_log(LOG_WARNING, "Invalid buffer count given '%d'.\n", *num_buffers); 07067 return -1; 07068 } 07069 if (!strcasecmp(policy_str, "full")) { 07070 *policy = DAHDI_POLICY_WHEN_FULL; 07071 } else if (!strcasecmp(policy_str, "immediate")) { 07072 *policy = DAHDI_POLICY_IMMEDIATE; 07073 #if defined(HAVE_DAHDI_HALF_FULL) 07074 } else if (!strcasecmp(policy_str, "half")) { 07075 *policy = DAHDI_POLICY_HALF_FULL; 07076 #endif 07077 } else { 07078 ast_log(LOG_WARNING, "Invalid policy name given '%s'.\n", policy_str); 07079 return -1; 07080 } 07081 07082 return 0; 07083 }
| static void parse_busy_pattern | ( | struct ast_variable * | v, | |
| struct ast_dsp_busy_pattern * | busy_cadence | |||
| ) | [static] |
Definition at line 17105 of file chan_dahdi.c.
References ast_log(), ast_dsp_busy_pattern::length, ast_variable::lineno, LOG_ERROR, ast_dsp_busy_pattern::pattern, and ast_variable::value.
Referenced by process_dahdi().
17106 { 17107 int count_pattern = 0; 17108 int norval = 0; 17109 char *temp = NULL; 17110 17111 for (; ;) { 17112 /* Scans the string for the next value in the pattern. If none, it checks to see if any have been entered so far. */ 17113 if(!sscanf(v->value, "%30d", &norval) && count_pattern == 0) { 17114 ast_log(LOG_ERROR, "busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->lineno); 17115 break; 17116 } 17117 17118 busy_cadence->pattern[count_pattern] = norval; 17119 17120 count_pattern++; 17121 if (count_pattern == 4) { 17122 break; 17123 } 17124 17125 temp = strchr(v->value, ','); 17126 if (temp == NULL) { 17127 break; 17128 } 17129 v->value = temp + 1; 17130 } 17131 busy_cadence->length = count_pattern; 17132 17133 if (count_pattern % 2 != 0) { 17134 /* The pattern length must be divisible by two */ 17135 ast_log(LOG_ERROR, "busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->lineno); 17136 } 17137 17138 }
| static char* parse_spanchan | ( | char * | chanstr, | |
| char ** | subdir | |||
| ) | [static] |
Definition at line 16881 of file chan_dahdi.c.
References string_replace().
Referenced by build_channels().
16882 { 16883 char *p; 16884 16885 if ((p = strrchr(chanstr, '!')) == NULL) { 16886 *subdir = NULL; 16887 return chanstr; 16888 } 16889 *p++ = '\0'; 16890 string_replace(chanstr, '!', '/'); 16891 *subdir = chanstr; 16892 return p; 16893 }
| static int process_dahdi | ( | struct dahdi_chan_conf * | confp, | |
| const char * | cat, | |||
| struct ast_variable * | v, | |||
| int | reload, | |||
| int | options | |||
| ) | [static] |
Definition at line 17140 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_debug, 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_cadence, 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::description, 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_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(), parse_busy_pattern(), 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_PRI_MOH_SIGNALING_MOH, SIG_PRI_MOH_SIGNALING_NOTIFY, SIG_SF, SIG_SF_FEATB, SIG_SFWINK, SIG_SS7, dahdi_chan_conf::smdi_port, dahdi_pvt::span, SS7_NAI_DYNAMIC, strcasestr(), dahdi_pvt::stripmsd, strsep(), 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().
17141 { 17142 struct dahdi_pvt *tmp; 17143 int y; 17144 int found_pseudo = 0; 17145 struct ast_variable *dahdichan = NULL; 17146 17147 for (; v; v = v->next) { 17148 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 17149 continue; 17150 17151 /* Create the interface list */ 17152 if (!strcasecmp(v->name, "channel") || !strcasecmp(v->name, "channels")) { 17153 if (options & PROC_DAHDI_OPT_NOCHAN) { 17154 ast_log(LOG_WARNING, "Channel '%s' ignored.\n", v->value); 17155 continue; 17156 } 17157 if (build_channels(confp, v->value, reload, v->lineno, &found_pseudo)) { 17158 if (confp->ignore_failed_channels) { 17159 ast_log(LOG_WARNING, "Channel '%s' failure ignored: ignore_failed_channels.\n", v->value); 17160 continue; 17161 } else { 17162 return -1; 17163 } 17164 } 17165 ast_debug(1, "Channel '%s' configured.\n", v->value); 17166 } else if (!strcasecmp(v->name, "ignore_failed_channels")) { 17167 confp->ignore_failed_channels = ast_true(v->value); 17168 } else if (!strcasecmp(v->name, "buffers")) { 17169 if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) { 17170 ast_log(LOG_WARNING, "Using default buffer policy.\n"); 17171 confp->chan.buf_no = numbufs; 17172 confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE; 17173 } 17174 } else if (!strcasecmp(v->name, "faxbuffers")) { 17175 if (!parse_buffers_policy(v->value, &confp->chan.faxbuf_no, &confp->chan.faxbuf_policy)) { 17176 confp->chan.usefaxbuffers = 1; 17177 } 17178 } else if (!strcasecmp(v->name, "dahdichan")) { 17179 /* Only process the last dahdichan value. */ 17180 dahdichan = v; 17181 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { 17182 usedistinctiveringdetection = ast_true(v->value); 17183 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) { 17184 distinctiveringaftercid = ast_true(v->value); 17185 } else if (!strcasecmp(v->name, "dring1context")) { 17186 ast_copy_string(confp->chan.drings.ringContext[0].contextData,v->value,sizeof(confp->chan.drings.ringContext[0].contextData)); 17187 } else if (!strcasecmp(v->name, "dring2context")) { 17188 ast_copy_string(confp->chan.drings.ringContext[1].contextData,v->value,sizeof(confp->chan.drings.ringContext[1].contextData)); 17189 } else if (!strcasecmp(v->name, "dring3context")) { 17190 ast_copy_string(confp->chan.drings.ringContext[2].contextData,v->value,sizeof(confp->chan.drings.ringContext[2].contextData)); 17191 } else if (!strcasecmp(v->name, "dring1range")) { 17192 confp->chan.drings.ringnum[0].range = atoi(v->value); 17193 } else if (!strcasecmp(v->name, "dring2range")) { 17194 confp->chan.drings.ringnum[1].range = atoi(v->value); 17195 } else if (!strcasecmp(v->name, "dring3range")) { 17196 confp->chan.drings.ringnum[2].range = atoi(v->value); 17197 } else if (!strcasecmp(v->name, "dring1")) { 17198 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]); 17199 } else if (!strcasecmp(v->name, "dring2")) { 17200 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]); 17201 } else if (!strcasecmp(v->name, "dring3")) { 17202 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]); 17203 } else if (!strcasecmp(v->name, "usecallerid")) { 17204 confp->chan.use_callerid = ast_true(v->value); 17205 } else if (!strcasecmp(v->name, "cidsignalling")) { 17206 if (!strcasecmp(v->value, "bell")) 17207 confp->chan.cid_signalling = CID_SIG_BELL; 17208 else if (!strcasecmp(v->value, "v23")) 17209 confp->chan.cid_signalling = CID_SIG_V23; 17210 else if (!strcasecmp(v->value, "dtmf")) 17211 confp->chan.cid_signalling = CID_SIG_DTMF; 17212 else if (!strcasecmp(v->value, "smdi")) 17213 confp->chan.cid_signalling = CID_SIG_SMDI; 17214 else if (!strcasecmp(v->value, "v23_jp")) 17215 confp->chan.cid_signalling = CID_SIG_V23_JP; 17216 else if (ast_true(v->value)) 17217 confp->chan.cid_signalling = CID_SIG_BELL; 17218 } else if (!strcasecmp(v->name, "cidstart")) { 17219 if (!strcasecmp(v->value, "ring")) 17220 confp->chan.cid_start = CID_START_RING; 17221 else if (!strcasecmp(v->value, "polarity_in")) 17222 confp->chan.cid_start = CID_START_POLARITY_IN; 17223 else if (!strcasecmp(v->value, "polarity")) 17224 confp->chan.cid_start = CID_START_POLARITY; 17225 else if (!strcasecmp(v->value, "dtmf")) 17226 confp->chan.cid_start = CID_START_DTMF_NOALERT; 17227 else if (ast_true(v->value)) 17228 confp->chan.cid_start = CID_START_RING; 17229 } else if (!strcasecmp(v->name, "threewaycalling")) { 17230 confp->chan.threewaycalling = ast_true(v->value); 17231 } else if (!strcasecmp(v->name, "cancallforward")) { 17232 confp->chan.cancallforward = ast_true(v->value); 17233 } else if (!strcasecmp(v->name, "relaxdtmf")) { 17234 if (ast_true(v->value)) 17235 confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF; 17236 else 17237 confp->chan.dtmfrelax = 0; 17238 } else if (!strcasecmp(v->name, "mailbox")) { 17239 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox)); 17240 } else if (!strcasecmp(v->name, "description")) { 17241 ast_copy_string(confp->chan.description, v->value, sizeof(confp->chan.description)); 17242 } else if (!strcasecmp(v->name, "hasvoicemail")) { 17243 if (ast_true(v->value) && ast_strlen_zero(confp->chan.mailbox)) { 17244 ast_copy_string(confp->chan.mailbox, cat, sizeof(confp->chan.mailbox)); 17245 } 17246 } else if (!strcasecmp(v->name, "adsi")) { 17247 confp->chan.adsi = ast_true(v->value); 17248 } else if (!strcasecmp(v->name, "usesmdi")) { 17249 confp->chan.use_smdi = ast_true(v->value); 17250 } else if (!strcasecmp(v->name, "smdiport")) { 17251 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port)); 17252 } else if (!strcasecmp(v->name, "transfer")) { 17253 confp->chan.transfer = ast_true(v->value); 17254 } else if (!strcasecmp(v->name, "canpark")) { 17255 confp->chan.canpark = ast_true(v->value); 17256 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { 17257 confp->chan.echocanbridged = ast_true(v->value); 17258 } else if (!strcasecmp(v->name, "busydetect")) { 17259 confp->chan.busydetect = ast_true(v->value); 17260 } else if (!strcasecmp(v->name, "busycount")) { 17261 confp->chan.busycount = atoi(v->value); 17262 } else if (!strcasecmp(v->name, "busypattern")) { 17263 parse_busy_pattern(v, &confp->chan.busy_cadence); 17264 } else if (!strcasecmp(v->name, "callprogress")) { 17265 confp->chan.callprogress &= ~CALLPROGRESS_PROGRESS; 17266 if (ast_true(v->value)) 17267 confp->chan.callprogress |= CALLPROGRESS_PROGRESS; 17268 } else if (!strcasecmp(v->name, "waitfordialtone")) { 17269 confp->chan.waitfordialtone = atoi(v->value); 17270 } else if (!strcasecmp(v->name, "faxdetect")) { 17271 confp->chan.callprogress &= ~CALLPROGRESS_FAX; 17272 if (!strcasecmp(v->value, "incoming")) { 17273 confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING; 17274 } else if (!strcasecmp(v->value, "outgoing")) { 17275 confp->chan.callprogress |= CALLPROGRESS_FAX_OUTGOING; 17276 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) 17277 confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING; 17278 } else if (!strcasecmp(v->name, "echocancel")) { 17279 process_echocancel(confp, v->value, v->lineno); 17280 } else if (!strcasecmp(v->name, "echotraining")) { 17281 if (sscanf(v->value, "%30d", &y) == 1) { 17282 if ((y < 10) || (y > 4000)) { 17283 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d.\n", v->lineno); 17284 } else { 17285 confp->chan.echotraining = y; 17286 } 17287 } else if (ast_true(v->value)) { 17288 confp->chan.echotraining = 400; 17289 } else 17290 confp->chan.echotraining = 0; 17291 } else if (!strcasecmp(v->name, "hidecallerid")) { 17292 confp->chan.hidecallerid = ast_true(v->value); 17293 } else if (!strcasecmp(v->name, "hidecalleridname")) { 17294 confp->chan.hidecalleridname = ast_true(v->value); 17295 } else if (!strcasecmp(v->name, "pulsedial")) { 17296 confp->chan.pulse = ast_true(v->value); 17297 } else if (!strcasecmp(v->name, "callreturn")) { 17298 confp->chan.callreturn = ast_true(v->value); 17299 } else if (!strcasecmp(v->name, "callwaiting")) { 17300 confp->chan.callwaiting = ast_true(v->value); 17301 } else if (!strcasecmp(v->name, "callwaitingcallerid")) { 17302 confp->chan.callwaitingcallerid = ast_true(v->value); 17303 } else if (!strcasecmp(v->name, "context")) { 17304 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context)); 17305 } else if (!strcasecmp(v->name, "language")) { 17306 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language)); 17307 } else if (!strcasecmp(v->name, "progzone")) { 17308 ast_copy_string(progzone, v->value, sizeof(progzone)); 17309 } else if (!strcasecmp(v->name, "mohinterpret") 17310 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) { 17311 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret)); 17312 } else if (!strcasecmp(v->name, "mohsuggest")) { 17313 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest)); 17314 } else if (!strcasecmp(v->name, "parkinglot")) { 17315 ast_copy_string(confp->chan.parkinglot, v->value, sizeof(confp->chan.parkinglot)); 17316 } else if (!strcasecmp(v->name, "stripmsd")) { 17317 ast_log(LOG_NOTICE, "Configuration option \"%s\" has been deprecated. Please use dialplan instead\n", v->name); 17318 confp->chan.stripmsd = atoi(v->value); 17319 } else if (!strcasecmp(v->name, "jitterbuffers")) { 17320 numbufs = atoi(v->value); 17321 } else if (!strcasecmp(v->name, "group")) { 17322 confp->chan.group = ast_get_group(v->value); 17323 } else if (!strcasecmp(v->name, "callgroup")) { 17324 if (!strcasecmp(v->value, "none")) 17325 confp->chan.callgroup = 0; 17326 else 17327 confp->chan.callgroup = ast_get_group(v->value); 17328 } else if (!strcasecmp(v->name, "pickupgroup")) { 17329 if (!strcasecmp(v->value, "none")) 17330 confp->chan.pickupgroup = 0; 17331 else 17332 confp->chan.pickupgroup = ast_get_group(v->value); 17333 } else if (!strcasecmp(v->name, "setvar")) { 17334 char *varname = ast_strdupa(v->value), *varval = NULL; 17335 struct ast_variable *tmpvar; 17336 if (varname && (varval = strchr(varname, '='))) { 17337 *varval++ = '\0'; 17338 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 17339 tmpvar->next = confp->chan.vars; 17340 confp->chan.vars = tmpvar; 17341 } 17342 } 17343 } else if (!strcasecmp(v->name, "immediate")) { 17344 confp->chan.immediate = ast_true(v->value); 17345 } else if (!strcasecmp(v->name, "transfertobusy")) { 17346 confp->chan.transfertobusy = ast_true(v->value); 17347 } else if (!strcasecmp(v->name, "mwimonitor")) { 17348 confp->chan.mwimonitor_neon = 0; 17349 confp->chan.mwimonitor_fsk = 0; 17350 confp->chan.mwimonitor_rpas = 0; 17351 if (strcasestr(v->value, "fsk")) { 17352 confp->chan.mwimonitor_fsk = 1; 17353 } 17354 if (strcasestr(v->value, "rpas")) { 17355 confp->chan.mwimonitor_rpas = 1; 17356 } 17357 if (strcasestr(v->value, "neon")) { 17358 confp->chan.mwimonitor_neon = 1; 17359 } 17360 /* If set to true or yes, assume that simple fsk is desired */ 17361 if (ast_true(v->value)) { 17362 confp->chan.mwimonitor_fsk = 1; 17363 } 17364 } else if (!strcasecmp(v->name, "cid_rxgain")) { 17365 if (sscanf(v->value, "%30f", &confp->chan.cid_rxgain) != 1) { 17366 ast_log(LOG_WARNING, "Invalid cid_rxgain: %s at line %d.\n", v->value, v->lineno); 17367 } 17368 } else if (!strcasecmp(v->name, "rxgain")) { 17369 if (sscanf(v->value, "%30f", &confp->chan.rxgain) != 1) { 17370 ast_log(LOG_WARNING, "Invalid rxgain: %s at line %d.\n", v->value, v->lineno); 17371 } 17372 } else if (!strcasecmp(v->name, "txgain")) { 17373 if (sscanf(v->value, "%30f", &confp->chan.txgain) != 1) { 17374 ast_log(LOG_WARNING, "Invalid txgain: %s at line %d.\n", v->value, v->lineno); 17375 } 17376 } else if (!strcasecmp(v->name, "txdrc")) { 17377 if (sscanf(v->value, "%f", &confp->chan.txdrc) != 1) { 17378 ast_log(LOG_WARNING, "Invalid txdrc: %s\n", v->value); 17379 } 17380 } else if (!strcasecmp(v->name, "rxdrc")) { 17381 if (sscanf(v->value, "%f", &confp->chan.rxdrc) != 1) { 17382 ast_log(LOG_WARNING, "Invalid rxdrc: %s\n", v->value); 17383 } 17384 } else if (!strcasecmp(v->name, "tonezone")) { 17385 if (sscanf(v->value, "%30d", &confp->chan.tonezone) != 1) { 17386 ast_log(LOG_WARNING, "Invalid tonezone: %s at line %d.\n", v->value, v->lineno); 17387 } 17388 } else if (!strcasecmp(v->name, "callerid")) { 17389 if (!strcasecmp(v->value, "asreceived")) { 17390 confp->chan.cid_num[0] = '\0'; 17391 confp->chan.cid_name[0] = '\0'; 17392 } else { 17393 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num)); 17394 } 17395 } else if (!strcasecmp(v->name, "fullname")) { 17396 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name)); 17397 } else if (!strcasecmp(v->name, "cid_number")) { 17398 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num)); 17399 } else if (!strcasecmp(v->name, "cid_tag")) { 17400 ast_copy_string(confp->chan.cid_tag, v->value, sizeof(confp->chan.cid_tag)); 17401 } else if (!strcasecmp(v->name, "useincomingcalleridondahditransfer")) { 17402 confp->chan.dahditrcallerid = ast_true(v->value); 17403 } else if (!strcasecmp(v->name, "restrictcid")) { 17404 confp->chan.restrictcid = ast_true(v->value); 17405 } else if (!strcasecmp(v->name, "usecallingpres")) { 17406 confp->chan.use_callingpres = ast_true(v->value); 17407 } else if (!strcasecmp(v->name, "accountcode")) { 17408 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode)); 17409 } else if (!strcasecmp(v->name, "amaflags")) { 17410 y = ast_cdr_amaflags2int(v->value); 17411 if (y < 0) 17412 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d.\n", v->value, v->lineno); 17413 else 17414 confp->chan.amaflags = y; 17415 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) { 17416 confp->chan.polarityonanswerdelay = atoi(v->value); 17417 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) { 17418 confp->chan.answeronpolarityswitch = ast_true(v->value); 17419 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) { 17420 confp->chan.hanguponpolarityswitch = ast_true(v->value); 17421 } else if (!strcasecmp(v->name, "sendcalleridafter")) { 17422 confp->chan.sendcalleridafter = atoi(v->value); 17423 } else if (!strcasecmp(v->name, "mwimonitornotify")) { 17424 ast_copy_string(mwimonitornotify, v->value, sizeof(mwimonitornotify)); 17425 } else if (ast_cc_is_config_param(v->name)) { 17426 ast_cc_set_param(confp->chan.cc_params, v->name, v->value); 17427 } else if (!strcasecmp(v->name, "mwisendtype")) { 17428 #ifndef HAVE_DAHDI_LINEREVERSE_VMWI /* backward compatibility for older dahdi VMWI implementation */ 17429 if (!strcasecmp(v->value, "rpas")) { /* Ring Pulse Alert Signal */ 17430 mwisend_rpas = 1; 17431 } else { 17432 mwisend_rpas = 0; 17433 } 17434 #else 17435 /* Default is fsk, to turn it off you must specify nofsk */ 17436 memset(&confp->chan.mwisend_setting, 0, sizeof(confp->chan.mwisend_setting)); 17437 if (strcasestr(v->value, "nofsk")) { /* NoFSK */ 17438 confp->chan.mwisend_fsk = 0; 17439 } else { /* Default FSK */ 17440 confp->chan.mwisend_fsk = 1; 17441 } 17442 if (strcasestr(v->value, "rpas")) { /* Ring Pulse Alert Signal, normally followed by FSK */ 17443 confp->chan.mwisend_rpas = 1; 17444 } else { 17445 confp->chan.mwisend_rpas = 0; 17446 } 17447 if (strcasestr(v->value, "lrev")) { /* Line Reversal */ 17448 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV; 17449 } 17450 if (strcasestr(v->value, "hvdc")) { /* HV 90VDC */ 17451 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC; 17452 } 17453 if ( (strcasestr(v->value, "neon")) || (strcasestr(v->value, "hvac")) ){ /* 90V DC pulses */ 17454 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC; 17455 } 17456 #endif 17457 } else if (reload != 1) { 17458 if (!strcasecmp(v->name, "signalling") || !strcasecmp(v->name, "signaling")) { 17459 int orig_radio = confp->chan.radio; 17460 int orig_outsigmod = confp->chan.outsigmod; 17461 int orig_auto = confp->is_sig_auto; 17462 17463 confp->chan.radio = 0; 17464 confp->chan.outsigmod = -1; 17465 confp->is_sig_auto = 0; 17466 if (!strcasecmp(v->value, "em")) { 17467 confp->chan.sig = SIG_EM; 17468 } else if (!strcasecmp(v->value, "em_e1")) { 17469 confp->chan.sig = SIG_EM_E1; 17470 } else if (!strcasecmp(v->value, "em_w")) { 17471 confp->chan.sig = SIG_EMWINK; 17472 } else if (!strcasecmp(v->value, "fxs_ls")) { 17473 confp->chan.sig = SIG_FXSLS; 17474 } else if (!strcasecmp(v->value, "fxs_gs")) { 17475 confp->chan.sig = SIG_FXSGS; 17476 } else if (!strcasecmp(v->value, "fxs_ks")) { 17477 confp->chan.sig = SIG_FXSKS; 17478 } else if (!strcasecmp(v->value, "fxo_ls")) { 17479 confp->chan.sig = SIG_FXOLS; 17480 } else if (!strcasecmp(v->value, "fxo_gs")) { 17481 confp->chan.sig = SIG_FXOGS; 17482 } else if (!strcasecmp(v->value, "fxo_ks")) { 17483 confp->chan.sig = SIG_FXOKS; 17484 } else if (!strcasecmp(v->value, "fxs_rx")) { 17485 confp->chan.sig = SIG_FXSKS; 17486 confp->chan.radio = 1; 17487 } else if (!strcasecmp(v->value, "fxo_rx")) { 17488 confp->chan.sig = SIG_FXOLS; 17489 confp->chan.radio = 1; 17490 } else if (!strcasecmp(v->value, "fxs_tx")) { 17491 confp->chan.sig = SIG_FXSLS; 17492 confp->chan.radio = 1; 17493 } else if (!strcasecmp(v->value, "fxo_tx")) { 17494 confp->chan.sig = SIG_FXOGS; 17495 confp->chan.radio = 1; 17496 } else if (!strcasecmp(v->value, "em_rx")) { 17497 confp->chan.sig = SIG_EM; 17498 confp->chan.radio = 1; 17499 } else if (!strcasecmp(v->value, "em_tx")) { 17500 confp->chan.sig = SIG_EM; 17501 confp->chan.radio = 1; 17502 } else if (!strcasecmp(v->value, "em_rxtx")) { 17503 confp->chan.sig = SIG_EM; 17504 confp->chan.radio = 2; 17505 } else if (!strcasecmp(v->value, "em_txrx")) { 17506 confp->chan.sig = SIG_EM; 17507 confp->chan.radio = 2; 17508 } else if (!strcasecmp(v->value, "sf")) { 17509 confp->chan.sig = SIG_SF; 17510 } else if (!strcasecmp(v->value, "sf_w")) { 17511 confp->chan.sig = SIG_SFWINK; 17512 } else if (!strcasecmp(v->value, "sf_featd")) { 17513 confp->chan.sig = SIG_FEATD; 17514 } else if (!strcasecmp(v->value, "sf_featdmf")) { 17515 confp->chan.sig = SIG_FEATDMF; 17516 } else if (!strcasecmp(v->value, "sf_featb")) { 17517 confp->chan.sig = SIG_SF_FEATB; 17518 } else if (!strcasecmp(v->value, "sf")) { 17519 confp->chan.sig = SIG_SF; 17520 } else if (!strcasecmp(v->value, "sf_rx")) { 17521 confp->chan.sig = SIG_SF; 17522 confp->chan.radio = 1; 17523 } else if (!strcasecmp(v->value, "sf_tx")) { 17524 confp->chan.sig = SIG_SF; 17525 confp->chan.radio = 1; 17526 } else if (!strcasecmp(v->value, "sf_rxtx")) { 17527 confp->chan.sig = SIG_SF; 17528 confp->chan.radio = 2; 17529 } else if (!strcasecmp(v->value, "sf_txrx")) { 17530 confp->chan.sig = SIG_SF; 17531 confp->chan.radio = 2; 17532 } else if (!strcasecmp(v->value, "featd")) { 17533 confp->chan.sig = SIG_FEATD; 17534 } else if (!strcasecmp(v->value, "featdmf")) { 17535 confp->chan.sig = SIG_FEATDMF; 17536 } else if (!strcasecmp(v->value, "featdmf_ta")) { 17537 confp->chan.sig = SIG_FEATDMF_TA; 17538 } else if (!strcasecmp(v->value, "e911")) { 17539 confp->chan.sig = SIG_E911; 17540 } else if (!strcasecmp(v->value, "fgccama")) { 17541 confp->chan.sig = SIG_FGC_CAMA; 17542 } else if (!strcasecmp(v->value, "fgccamamf")) { 17543 confp->chan.sig = SIG_FGC_CAMAMF; 17544 } else if (!strcasecmp(v->value, "featb")) { 17545 confp->chan.sig = SIG_FEATB; 17546 #ifdef HAVE_PRI 17547 } else if (!strcasecmp(v->value, "pri_net")) { 17548 confp->chan.sig = SIG_PRI; 17549 confp->pri.pri.nodetype = PRI_NETWORK; 17550 } else if (!strcasecmp(v->value, "pri_cpe")) { 17551 confp->chan.sig = SIG_PRI; 17552 confp->pri.pri.nodetype = PRI_CPE; 17553 } else if (!strcasecmp(v->value, "bri_cpe")) { 17554 confp->chan.sig = SIG_BRI; 17555 confp->pri.pri.nodetype = PRI_CPE; 17556 } else if (!strcasecmp(v->value, "bri_net")) { 17557 confp->chan.sig = SIG_BRI; 17558 confp->pri.pri.nodetype = PRI_NETWORK; 17559 } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) { 17560 confp->chan.sig = SIG_BRI_PTMP; 17561 confp->pri.pri.nodetype = PRI_CPE; 17562 } else if (!strcasecmp(v->value, "bri_net_ptmp")) { 17563 #if defined(HAVE_PRI_CALL_HOLD) 17564 confp->chan.sig = SIG_BRI_PTMP; 17565 confp->pri.pri.nodetype = PRI_NETWORK; 17566 #else 17567 ast_log(LOG_WARNING, "How cool would it be if someone implemented this mode! For now, sucks for you. (line %d)\n", v->lineno); 17568 #endif /* !defined(HAVE_PRI_CALL_HOLD) */ 17569 #endif 17570 #if defined(HAVE_SS7) 17571 } else if (!strcasecmp(v->value, "ss7")) { 17572 confp->chan.sig = SIG_SS7; 17573 #endif /* defined(HAVE_SS7) */ 17574 #ifdef HAVE_OPENR2 17575 } else if (!strcasecmp(v->value, "mfcr2")) { 17576 confp->chan.sig = SIG_MFCR2; 17577 #endif 17578 } else if (!strcasecmp(v->value, "auto")) { 17579 confp->is_sig_auto = 1; 17580 } else { 17581 confp->chan.outsigmod = orig_outsigmod; 17582 confp->chan.radio = orig_radio; 17583 confp->is_sig_auto = orig_auto; 17584 ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno); 17585 } 17586 } else if (!strcasecmp(v->name, "outsignalling") || !strcasecmp(v->name, "outsignaling")) { 17587 if (!strcasecmp(v->value, "em")) { 17588 confp->chan.outsigmod = SIG_EM; 17589 } else if (!strcasecmp(v->value, "em_e1")) { 17590 confp->chan.outsigmod = SIG_EM_E1; 17591 } else if (!strcasecmp(v->value, "em_w")) { 17592 confp->chan.outsigmod = SIG_EMWINK; 17593 } else if (!strcasecmp(v->value, "sf")) { 17594 confp->chan.outsigmod = SIG_SF; 17595 } else if (!strcasecmp(v->value, "sf_w")) { 17596 confp->chan.outsigmod = SIG_SFWINK; 17597 } else if (!strcasecmp(v->value, "sf_featd")) { 17598 confp->chan.outsigmod = SIG_FEATD; 17599 } else if (!strcasecmp(v->value, "sf_featdmf")) { 17600 confp->chan.outsigmod = SIG_FEATDMF; 17601 } else if (!strcasecmp(v->value, "sf_featb")) { 17602 confp->chan.outsigmod = SIG_SF_FEATB; 17603 } else if (!strcasecmp(v->value, "sf")) { 17604 confp->chan.outsigmod = SIG_SF; 17605 } else if (!strcasecmp(v->value, "featd")) { 17606 confp->chan.outsigmod = SIG_FEATD; 17607 } else if (!strcasecmp(v->value, "featdmf")) { 17608 confp->chan.outsigmod = SIG_FEATDMF; 17609 } else if (!strcasecmp(v->value, "featdmf_ta")) { 17610 confp->chan.outsigmod = SIG_FEATDMF_TA; 17611 } else if (!strcasecmp(v->value, "e911")) { 17612 confp->chan.outsigmod = SIG_E911; 17613 } else if (!strcasecmp(v->value, "fgccama")) { 17614 confp->chan.outsigmod = SIG_FGC_CAMA; 17615 } else if (!strcasecmp(v->value, "fgccamamf")) { 17616 confp->chan.outsigmod = SIG_FGC_CAMAMF; 17617 } else if (!strcasecmp(v->value, "featb")) { 17618 confp->chan.outsigmod = SIG_FEATB; 17619 } else { 17620 ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno); 17621 } 17622 #ifdef HAVE_PRI 17623 } else if (!strcasecmp(v->name, "pridialplan")) { 17624 if (!strcasecmp(v->value, "national")) { 17625 confp->pri.pri.dialplan = PRI_NATIONAL_ISDN + 1; 17626 } else if (!strcasecmp(v->value, "unknown")) { 17627 confp->pri.pri.dialplan = PRI_UNKNOWN + 1; 17628 } else if (!strcasecmp(v->value, "private")) { 17629 confp->pri.pri.dialplan = PRI_PRIVATE + 1; 17630 } else if (!strcasecmp(v->value, "international")) { 17631 confp->pri.pri.dialplan = PRI_INTERNATIONAL_ISDN + 1; 17632 } else if (!strcasecmp(v->value, "local")) { 17633 confp->pri.pri.dialplan = PRI_LOCAL_ISDN + 1; 17634 } else if (!strcasecmp(v->value, "dynamic")) { 17635 confp->pri.pri.dialplan = -1; 17636 } else if (!strcasecmp(v->value, "redundant")) { 17637 confp->pri.pri.dialplan = -2; 17638 } else { 17639 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno); 17640 } 17641 } else if (!strcasecmp(v->name, "prilocaldialplan")) { 17642 if (!strcasecmp(v->value, "national")) { 17643 confp->pri.pri.localdialplan = PRI_NATIONAL_ISDN + 1; 17644 } else if (!strcasecmp(v->value, "unknown")) { 17645 confp->pri.pri.localdialplan = PRI_UNKNOWN + 1; 17646 } else if (!strcasecmp(v->value, "private")) { 17647 confp->pri.pri.localdialplan = PRI_PRIVATE + 1; 17648 } else if (!strcasecmp(v->value, "international")) { 17649 confp->pri.pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1; 17650 } else if (!strcasecmp(v->value, "local")) { 17651 confp->pri.pri.localdialplan = PRI_LOCAL_ISDN + 1; 17652 } else if (!strcasecmp(v->value, "from_channel")) { 17653 confp->pri.pri.localdialplan = 0; 17654 } else if (!strcasecmp(v->value, "dynamic")) { 17655 confp->pri.pri.localdialplan = -1; 17656 } else if (!strcasecmp(v->value, "redundant")) { 17657 confp->pri.pri.localdialplan = -2; 17658 } else { 17659 ast_log(LOG_WARNING, "Unknown PRI localdialplan '%s' at line %d.\n", v->value, v->lineno); 17660 } 17661 } else if (!strcasecmp(v->name, "pricpndialplan")) { 17662 if (!strcasecmp(v->value, "national")) { 17663 confp->pri.pri.cpndialplan = PRI_NATIONAL_ISDN + 1; 17664 } else if (!strcasecmp(v->value, "unknown")) { 17665 confp->pri.pri.cpndialplan = PRI_UNKNOWN + 1; 17666 } else if (!strcasecmp(v->value, "private")) { 17667 confp->pri.pri.cpndialplan = PRI_PRIVATE + 1; 17668 } else if (!strcasecmp(v->value, "international")) { 17669 confp->pri.pri.cpndialplan = PRI_INTERNATIONAL_ISDN + 1; 17670 } else if (!strcasecmp(v->value, "local")) { 17671 confp->pri.pri.cpndialplan = PRI_LOCAL_ISDN + 1; 17672 } else if (!strcasecmp(v->value, "from_channel")) { 17673 confp->pri.pri.cpndialplan = 0; 17674 } else if (!strcasecmp(v->value, "dynamic")) { 17675 confp->pri.pri.cpndialplan = -1; 17676 } else if (!strcasecmp(v->value, "redundant")) { 17677 confp->pri.pri.cpndialplan = -2; 17678 } else { 17679 ast_log(LOG_WARNING, "Unknown PRI cpndialplan '%s' at line %d.\n", v->value, v->lineno); 17680 } 17681 } else if (!strcasecmp(v->name, "switchtype")) { 17682 if (!strcasecmp(v->value, "national")) 17683 confp->pri.pri.switchtype = PRI_SWITCH_NI2; 17684 else if (!strcasecmp(v->value, "ni1")) 17685 confp->pri.pri.switchtype = PRI_SWITCH_NI1; 17686 else if (!strcasecmp(v->value, "dms100")) 17687 confp->pri.pri.switchtype = PRI_SWITCH_DMS100; 17688 else if (!strcasecmp(v->value, "4ess")) 17689 confp->pri.pri.switchtype = PRI_SWITCH_ATT4ESS; 17690 else if (!strcasecmp(v->value, "5ess")) 17691 confp->pri.pri.switchtype = PRI_SWITCH_LUCENT5E; 17692 else if (!strcasecmp(v->value, "euroisdn")) 17693 confp->pri.pri.switchtype = PRI_SWITCH_EUROISDN_E1; 17694 else if (!strcasecmp(v->value, "qsig")) 17695 confp->pri.pri.switchtype = PRI_SWITCH_QSIG; 17696 else { 17697 ast_log(LOG_ERROR, "Unknown switchtype '%s' at line %d.\n", v->value, v->lineno); 17698 return -1; 17699 } 17700 } else if (!strcasecmp(v->name, "msn")) { 17701 ast_copy_string(confp->pri.pri.msn_list, v->value, 17702 sizeof(confp->pri.pri.msn_list)); 17703 } else if (!strcasecmp(v->name, "nsf")) { 17704 if (!strcasecmp(v->value, "sdn")) 17705 confp->pri.pri.nsf = PRI_NSF_SDN; 17706 else if (!strcasecmp(v->value, "megacom")) 17707 confp->pri.pri.nsf = PRI_NSF_MEGACOM; 17708 else if (!strcasecmp(v->value, "tollfreemegacom")) 17709 confp->pri.pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM; 17710 else if (!strcasecmp(v->value, "accunet")) 17711 confp->pri.pri.nsf = PRI_NSF_ACCUNET; 17712 else if (!strcasecmp(v->value, "none")) 17713 confp->pri.pri.nsf = PRI_NSF_NONE; 17714 else { 17715 ast_log(LOG_WARNING, "Unknown network-specific facility '%s' at line %d.\n", v->value, v->lineno); 17716 confp->pri.pri.nsf = PRI_NSF_NONE; 17717 } 17718 } else if (!strcasecmp(v->name, "priindication")) { 17719 if (!strcasecmp(v->value, "outofband")) 17720 confp->chan.priindication_oob = 1; 17721 else if (!strcasecmp(v->value, "inband")) 17722 confp->chan.priindication_oob = 0; 17723 else 17724 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d.\n", 17725 v->value, v->lineno); 17726 } else if (!strcasecmp(v->name, "priexclusive")) { 17727 confp->chan.priexclusive = ast_true(v->value); 17728 } else if (!strcasecmp(v->name, "internationalprefix")) { 17729 ast_copy_string(confp->pri.pri.internationalprefix, v->value, sizeof(confp->pri.pri.internationalprefix)); 17730 } else if (!strcasecmp(v->name, "nationalprefix")) { 17731 ast_copy_string(confp->pri.pri.nationalprefix, v->value, sizeof(confp->pri.pri.nationalprefix)); 17732 } else if (!strcasecmp(v->name, "localprefix")) { 17733 ast_copy_string(confp->pri.pri.localprefix, v->value, sizeof(confp->pri.pri.localprefix)); 17734 } else if (!strcasecmp(v->name, "privateprefix")) { 17735 ast_copy_string(confp->pri.pri.privateprefix, v->value, sizeof(confp->pri.pri.privateprefix)); 17736 } else if (!strcasecmp(v->name, "unknownprefix")) { 17737 ast_copy_string(confp->pri.pri.unknownprefix, v->value, sizeof(confp->pri.pri.unknownprefix)); 17738 } else if (!strcasecmp(v->name, "resetinterval")) { 17739 if (!strcasecmp(v->value, "never")) 17740 confp->pri.pri.resetinterval = -1; 17741 else if (atoi(v->value) >= 60) 17742 confp->pri.pri.resetinterval = atoi(v->value); 17743 else 17744 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n", 17745 v->value, v->lineno); 17746 } else if (!strcasecmp(v->name, "minunused")) { 17747 confp->pri.pri.minunused = atoi(v->value); 17748 } else if (!strcasecmp(v->name, "minidle")) { 17749 confp->pri.pri.minidle = atoi(v->value); 17750 } else if (!strcasecmp(v->name, "idleext")) { 17751 ast_copy_string(confp->pri.pri.idleext, v->value, sizeof(confp->pri.pri.idleext)); 17752 } else if (!strcasecmp(v->name, "idledial")) { 17753 ast_copy_string(confp->pri.pri.idledial, v->value, sizeof(confp->pri.pri.idledial)); 17754 } else if (!strcasecmp(v->name, "overlapdial")) { 17755 if (ast_true(v->value)) { 17756 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH; 17757 } else if (!strcasecmp(v->value, "incoming")) { 17758 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_INCOMING; 17759 } else if (!strcasecmp(v->value, "outgoing")) { 17760 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_OUTGOING; 17761 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) { 17762 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH; 17763 } else { 17764 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_NONE; 17765 } 17766 #ifdef HAVE_PRI_PROG_W_CAUSE 17767 } else if (!strcasecmp(v->name, "qsigchannelmapping")) { 17768 if (!strcasecmp(v->value, "logical")) { 17769 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_LOGICAL; 17770 } else if (!strcasecmp(v->value, "physical")) { 17771 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL; 17772 } else { 17773 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL; 17774 } 17775 #endif 17776 } else if (!strcasecmp(v->name, "discardremoteholdretrieval")) { 17777 confp->pri.pri.discardremoteholdretrieval = ast_true(v->value); 17778 #if defined(HAVE_PRI_SERVICE_MESSAGES) 17779 } else if (!strcasecmp(v->name, "service_message_support")) { 17780 /* assuming switchtype for this channel group has been configured already */ 17781 if ((confp->pri.pri.switchtype == PRI_SWITCH_ATT4ESS 17782 || confp->pri.pri.switchtype == PRI_SWITCH_LUCENT5E 17783 || confp->pri.pri.switchtype == PRI_SWITCH_NI2) && ast_true(v->value)) { 17784 confp->pri.pri.enable_service_message_support = 1; 17785 } else { 17786 confp->pri.pri.enable_service_message_support = 0; 17787 } 17788 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ 17789 #ifdef HAVE_PRI_INBANDDISCONNECT 17790 } else if (!strcasecmp(v->name, "inbanddisconnect")) { 17791 confp->pri.pri.inbanddisconnect = ast_true(v->value); 17792 #endif 17793 } else if (!strcasecmp(v->name, "pritimer")) { 17794 #ifdef PRI_GETSET_TIMERS 17795 char tmp[20]; 17796 char *timerc; 17797 char *c; 17798 int timer; 17799 int timeridx; 17800 17801 ast_copy_string(tmp, v->value, sizeof(tmp)); 17802 c = tmp; 17803 timerc = strsep(&c, ","); 17804 if (!ast_strlen_zero(timerc) && !ast_strlen_zero(c)) { 17805 timeridx = pri_timer2idx(timerc); 17806 timer = atoi(c); 17807 if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) { 17808 ast_log(LOG_WARNING, 17809 "'%s' is not a valid ISDN timer at line %d.\n", timerc, 17810 v->lineno); 17811 } else if (!timer) { 17812 ast_log(LOG_WARNING, 17813 "'%s' is not a valid value for ISDN timer '%s' at line %d.\n", 17814 c, timerc, v->lineno); 17815 } else { 17816 confp->pri.pri.pritimers[timeridx] = timer; 17817 } 17818 } else { 17819 ast_log(LOG_WARNING, 17820 "'%s' is not a valid ISDN timer configuration string at line %d.\n", 17821 v->value, v->lineno); 17822 } 17823 #endif /* PRI_GETSET_TIMERS */ 17824 } else if (!strcasecmp(v->name, "facilityenable")) { 17825 confp->pri.pri.facilityenable = ast_true(v->value); 17826 #if defined(HAVE_PRI_AOC_EVENTS) 17827 } else if (!strcasecmp(v->name, "aoc_enable")) { 17828 confp->pri.pri.aoc_passthrough_flag = 0; 17829 if (strchr(v->value, 's') || strchr(v->value, 'S')) { 17830 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_S; 17831 } 17832 if (strchr(v->value, 'd') || strchr(v->value, 'D')) { 17833 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_D; 17834 } 17835 if (strchr(v->value, 'e') || strchr(v->value, 'E')) { 17836 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_E; 17837 } 17838 } else if (!strcasecmp(v->name, "aoce_delayhangup")) { 17839 confp->pri.pri.aoce_delayhangup = ast_true(v->value); 17840 #endif /* defined(HAVE_PRI_AOC_EVENTS) */ 17841 #if defined(HAVE_PRI_CALL_HOLD) 17842 } else if (!strcasecmp(v->name, "hold_disconnect_transfer")) { 17843 confp->pri.pri.hold_disconnect_transfer = ast_true(v->value); 17844 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 17845 } else if (!strcasecmp(v->name, "moh_signaling") 17846 || !strcasecmp(v->name, "moh_signalling")) { 17847 if (!strcasecmp(v->value, "moh")) { 17848 confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_MOH; 17849 } else if (!strcasecmp(v->value, "notify")) { 17850 confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_NOTIFY; 17851 #if defined(HAVE_PRI_CALL_HOLD) 17852 } else if (!strcasecmp(v->value, "hold")) { 17853 confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_HOLD; 17854 #endif /* defined(HAVE_PRI_CALL_HOLD) */ 17855 } else { 17856 confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_MOH; 17857 } 17858 #if defined(HAVE_PRI_CCSS) 17859 } else if (!strcasecmp(v->name, "cc_ptmp_recall_mode")) { 17860 if (!strcasecmp(v->value, "global")) { 17861 confp->pri.pri.cc_ptmp_recall_mode = 0;/* globalRecall */ 17862 } else if (!strcasecmp(v->value, "specific")) { 17863 confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */ 17864 } else { 17865 confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */ 17866 } 17867 } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_req")) { 17868 if (!strcasecmp(v->value, "release")) { 17869 confp->pri.pri.cc_qsig_signaling_link_req = 0;/* release */ 17870 } else if (!strcasecmp(v->value, "retain")) { 17871 confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */ 17872 } else if (!strcasecmp(v->value, "do_not_care")) { 17873 confp->pri.pri.cc_qsig_signaling_link_req = 2;/* do-not-care */ 17874 } else { 17875 confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */ 17876 } 17877 } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_rsp")) { 17878 if (!strcasecmp(v->value, "release")) { 17879 confp->pri.pri.cc_qsig_signaling_link_rsp = 0;/* release */ 17880 } else if (!strcasecmp(v->value, "retain")) { 17881 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */ 17882 } else { 17883 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */ 17884 } 17885 #endif /* defined(HAVE_PRI_CCSS) */ 17886 #if defined(HAVE_PRI_CALL_WAITING) 17887 } else if (!strcasecmp(v->name, "max_call_waiting_calls")) { 17888 confp->pri.pri.max_call_waiting_calls = atoi(v->value); 17889 if (confp->pri.pri.max_call_waiting_calls < 0) { 17890 /* Negative values are not allowed. */ 17891 confp->pri.pri.max_call_waiting_calls = 0; 17892 } 17893 } else if (!strcasecmp(v->name, "allow_call_waiting_calls")) { 17894 confp->pri.pri.allow_call_waiting_calls = ast_true(v->value); 17895 #endif /* defined(HAVE_PRI_CALL_WAITING) */ 17896 #if defined(HAVE_PRI_MWI) 17897 } else if (!strcasecmp(v->name, "mwi_mailboxes")) { 17898 ast_copy_string(confp->pri.pri.mwi_mailboxes, v->value, 17899 sizeof(confp->pri.pri.mwi_mailboxes)); 17900 } else if (!strcasecmp(v->name, "mwi_vm_numbers")) { 17901 ast_copy_string(confp->pri.pri.mwi_vm_numbers, v->value, 17902 sizeof(confp->pri.pri.mwi_vm_numbers)); 17903 #endif /* defined(HAVE_PRI_MWI) */ 17904 } else if (!strcasecmp(v->name, "append_msn_to_cid_tag")) { 17905 confp->pri.pri.append_msn_to_user_tag = ast_true(v->value); 17906 #if defined(HAVE_PRI_DISPLAY_TEXT) 17907 } else if (!strcasecmp(v->name, "display_send")) { 17908 confp->pri.pri.display_flags_send = dahdi_display_text_option(v->value); 17909 } else if (!strcasecmp(v->name, "display_receive")) { 17910 confp->pri.pri.display_flags_receive = dahdi_display_text_option(v->value); 17911 #endif /* defined(HAVE_PRI_DISPLAY_TEXT) */ 17912 #if defined(HAVE_PRI_MCID) 17913 } else if (!strcasecmp(v->name, "mcid_send")) { 17914 confp->pri.pri.mcid_send = ast_true(v->value); 17915 #endif /* defined(HAVE_PRI_MCID) */ 17916 #if defined(HAVE_PRI_DATETIME_SEND) 17917 } else if (!strcasecmp(v->name, "datetime_send")) { 17918 confp->pri.pri.datetime_send = dahdi_datetime_send_option(v->value); 17919 #endif /* defined(HAVE_PRI_DATETIME_SEND) */ 17920 #if defined(HAVE_PRI_L2_PERSISTENCE) 17921 } else if (!strcasecmp(v->name, "layer2_persistence")) { 17922 if (!strcasecmp(v->value, "keep_up")) { 17923 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_KEEP_UP; 17924 } else if (!strcasecmp(v->value, "leave_down")) { 17925 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_LEAVE_DOWN; 17926 } else { 17927 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_DEFAULT; 17928 } 17929 #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */ 17930 #endif /* HAVE_PRI */ 17931 #if defined(HAVE_SS7) 17932 } else if (!strcasecmp(v->name, "ss7type")) { 17933 if (!strcasecmp(v->value, "itu")) { 17934 cur_ss7type = SS7_ITU; 17935 } else if (!strcasecmp(v->value, "ansi")) { 17936 cur_ss7type = SS7_ANSI; 17937 } else 17938 ast_log(LOG_WARNING, "'%s' is an unknown ss7 switch type at line %d.!\n", v->value, v->lineno); 17939 } else if (!strcasecmp(v->name, "linkset")) { 17940 cur_linkset = atoi(v->value); 17941 } else if (!strcasecmp(v->name, "pointcode")) { 17942 cur_pointcode = parse_pointcode(v->value); 17943 } else if (!strcasecmp(v->name, "adjpointcode")) { 17944 cur_adjpointcode = parse_pointcode(v->value); 17945 } else if (!strcasecmp(v->name, "defaultdpc")) { 17946 cur_defaultdpc = parse_pointcode(v->value); 17947 } else if (!strcasecmp(v->name, "cicbeginswith")) { 17948 cur_cicbeginswith = atoi(v->value); 17949 } else if (!strcasecmp(v->name, "networkindicator")) { 17950 if (!strcasecmp(v->value, "national")) 17951 cur_networkindicator = SS7_NI_NAT; 17952 else if (!strcasecmp(v->value, "national_spare")) 17953 cur_networkindicator = SS7_NI_NAT_SPARE; 17954 else if (!strcasecmp(v->value, "international")) 17955 cur_networkindicator = SS7_NI_INT; 17956 else if (!strcasecmp(v->value, "international_spare")) 17957 cur_networkindicator = SS7_NI_INT_SPARE; 17958 else 17959 cur_networkindicator = -1; 17960 } else if (!strcasecmp(v->name, "ss7_internationalprefix")) { 17961 ast_copy_string(confp->ss7.ss7.internationalprefix, v->value, sizeof(confp->ss7.ss7.internationalprefix)); 17962 } else if (!strcasecmp(v->name, "ss7_nationalprefix")) { 17963 ast_copy_string(confp->ss7.ss7.nationalprefix, v->value, sizeof(confp->ss7.ss7.nationalprefix)); 17964 } else if (!strcasecmp(v->name, "ss7_subscriberprefix")) { 17965 ast_copy_string(confp->ss7.ss7.subscriberprefix, v->value, sizeof(confp->ss7.ss7.subscriberprefix)); 17966 } else if (!strcasecmp(v->name, "ss7_unknownprefix")) { 17967 ast_copy_string(confp->ss7.ss7.unknownprefix, v->value, sizeof(confp->ss7.ss7.unknownprefix)); 17968 } else if (!strcasecmp(v->name, "ss7_called_nai")) { 17969 if (!strcasecmp(v->value, "national")) { 17970 confp->ss7.ss7.called_nai = SS7_NAI_NATIONAL; 17971 } else if (!strcasecmp(v->value, "international")) { 17972 confp->ss7.ss7.called_nai = SS7_NAI_INTERNATIONAL; 17973 } else if (!strcasecmp(v->value, "subscriber")) { 17974 confp->ss7.ss7.called_nai = SS7_NAI_SUBSCRIBER; 17975 } else if (!strcasecmp(v->value, "unknown")) { 17976 confp->ss7.ss7.called_nai = SS7_NAI_UNKNOWN; 17977 } else if (!strcasecmp(v->value, "dynamic")) { 17978 confp->ss7.ss7.called_nai = SS7_NAI_DYNAMIC; 17979 } else { 17980 ast_log(LOG_WARNING, "Unknown SS7 called_nai '%s' at line %d.\n", v->value, v->lineno); 17981 } 17982 } else if (!strcasecmp(v->name, "ss7_calling_nai")) { 17983 if (!strcasecmp(v->value, "national")) { 17984 confp->ss7.ss7.calling_nai = SS7_NAI_NATIONAL; 17985 } else if (!strcasecmp(v->value, "international")) { 17986 confp->ss7.ss7.calling_nai = SS7_NAI_INTERNATIONAL; 17987 } else if (!strcasecmp(v->value, "subscriber")) { 17988 confp->ss7.ss7.calling_nai = SS7_NAI_SUBSCRIBER; 17989 } else if (!strcasecmp(v->value, "unknown")) { 17990 confp->ss7.ss7.calling_nai = SS7_NAI_UNKNOWN; 17991 } else if (!strcasecmp(v->value, "dynamic")) { 17992 confp->ss7.ss7.calling_nai = SS7_NAI_DYNAMIC; 17993 } else { 17994 ast_log(LOG_WARNING, "Unknown SS7 calling_nai '%s' at line %d.\n", v->value, v->lineno); 17995 } 17996 } else if (!strcasecmp(v->name, "sigchan")) { 17997 int sigchan, res; 17998 sigchan = atoi(v->value); 17999 res = linkset_addsigchan(sigchan); 18000 if (res < 0) 18001 return -1; 18002 18003 } else if (!strcasecmp(v->name, "ss7_explicitacm")) { 18004 struct dahdi_ss7 *link; 18005 link = ss7_resolve_linkset(cur_linkset); 18006 if (!link) { 18007 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1); 18008 return -1; 18009 } 18010 if (ast_true(v->value)) 18011 link->ss7.flags |= LINKSET_FLAG_EXPLICITACM; 18012 #endif /* defined(HAVE_SS7) */ 18013 #ifdef HAVE_OPENR2 18014 } else if (!strcasecmp(v->name, "mfcr2_advanced_protocol_file")) { 18015 ast_copy_string(confp->mfcr2.r2proto_file, v->value, sizeof(confp->mfcr2.r2proto_file)); 18016 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); 18017 } else if (!strcasecmp(v->name, "mfcr2_logdir")) { 18018 ast_copy_string(confp->mfcr2.logdir, v->value, sizeof(confp->mfcr2.logdir)); 18019 } else if (!strcasecmp(v->name, "mfcr2_variant")) { 18020 confp->mfcr2.variant = openr2_proto_get_variant(v->value); 18021 if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) { 18022 ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d, defaulting to ITU.\n", v->value, v->lineno); 18023 confp->mfcr2.variant = OR2_VAR_ITU; 18024 } 18025 } else if (!strcasecmp(v->name, "mfcr2_mfback_timeout")) { 18026 confp->mfcr2.mfback_timeout = atoi(v->value); 18027 if (!confp->mfcr2.mfback_timeout) { 18028 ast_log(LOG_WARNING, "MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n"); 18029 confp->mfcr2.mfback_timeout = -1; 18030 } else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) { 18031 ast_log(LOG_WARNING, "MF timeout less than 500ms is not recommended, you have been warned!\n"); 18032 } 18033 } else if (!strcasecmp(v->name, "mfcr2_metering_pulse_timeout")) { 18034 confp->mfcr2.metering_pulse_timeout = atoi(v->value); 18035 if (confp->mfcr2.metering_pulse_timeout > 500) { 18036 ast_log(LOG_WARNING, "Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n"); 18037 } 18038 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2 18039 } else if (!strcasecmp(v->name, "mfcr2_dtmf_detection")) { 18040 confp->mfcr2.dtmf_detection = ast_true(v->value) ? 1 : 0; 18041 } else if (!strcasecmp(v->name, "mfcr2_dtmf_dialing")) { 18042 confp->mfcr2.dtmf_dialing = ast_true(v->value) ? 1 : 0; 18043 } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_on")) { 18044 confp->mfcr2.dtmf_time_on = atoi(v->value); 18045 } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_off")) { 18046 confp->mfcr2.dtmf_time_off = atoi(v->value); 18047 #endif 18048 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3 18049 } else if (!strcasecmp(v->name, "mfcr2_dtmf_end_timeout")) { 18050 confp->mfcr2.dtmf_end_timeout = atoi(v->value); 18051 #endif 18052 } else if (!strcasecmp(v->name, "mfcr2_get_ani_first")) { 18053 confp->mfcr2.get_ani_first = ast_true(v->value) ? 1 : 0; 18054 } else if (!strcasecmp(v->name, "mfcr2_double_answer")) { 18055 confp->mfcr2.double_answer = ast_true(v->value) ? 1 : 0; 18056 } else if (!strcasecmp(v->name, "mfcr2_charge_calls")) { 18057 confp->mfcr2.charge_calls = ast_true(v->value) ? 1 : 0; 18058 } else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) { 18059 confp->mfcr2.accept_on_offer = ast_true(v->value) ? 1 : 0; 18060 } else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) { 18061 confp->mfcr2.allow_collect_calls = ast_true(v->value) ? 1 : 0; 18062 } else if (!strcasecmp(v->name, "mfcr2_forced_release")) { 18063 confp->mfcr2.forced_release = ast_true(v->value) ? 1 : 0; 18064 } else if (!strcasecmp(v->name, "mfcr2_immediate_accept")) { 18065 confp->mfcr2.immediate_accept = ast_true(v->value) ? 1 : 0; 18066 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1 18067 } else if (!strcasecmp(v->name, "mfcr2_skip_category")) { 18068 confp->mfcr2.skip_category_request = ast_true(v->value) ? 1 : 0; 18069 #endif 18070 } else if (!strcasecmp(v->name, "mfcr2_call_files")) { 18071 confp->mfcr2.call_files = ast_true(v->value) ? 1 : 0; 18072 } else if (!strcasecmp(v->name, "mfcr2_max_ani")) { 18073 confp->mfcr2.max_ani = atoi(v->value); 18074 if (confp->mfcr2.max_ani >= AST_MAX_EXTENSION){ 18075 confp->mfcr2.max_ani = AST_MAX_EXTENSION - 1; 18076 } 18077 } else if (!strcasecmp(v->name, "mfcr2_max_dnis")) { 18078 confp->mfcr2.max_dnis = atoi(v->value); 18079 if (confp->mfcr2.max_dnis >= AST_MAX_EXTENSION){ 18080 confp->mfcr2.max_dnis = AST_MAX_EXTENSION - 1; 18081 } 18082 } else if (!strcasecmp(v->name, "mfcr2_category")) { 18083 confp->mfcr2.category = openr2_proto_get_category(v->value); 18084 if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) { 18085 confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER; 18086 ast_log(LOG_WARNING, "Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n", 18087 v->value, v->lineno); 18088 } 18089 } else if (!strcasecmp(v->name, "mfcr2_logging")) { 18090 openr2_log_level_t tmplevel; 18091 char *clevel; 18092 char *logval = ast_strdupa(v->value); 18093 while (logval) { 18094 clevel = strsep(&logval,","); 18095 if (-1 == (tmplevel = openr2_log_get_level(clevel))) { 18096 ast_log(LOG_WARNING, "Ignoring invalid logging level: '%s' at line %d.\n", clevel, v->lineno); 18097 continue; 18098 } 18099 confp->mfcr2.loglevel |= tmplevel; 18100 } 18101 #endif /* HAVE_OPENR2 */ 18102 } else if (!strcasecmp(v->name, "cadence")) { 18103 /* setup to scan our argument */ 18104 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 18105 int i; 18106 struct dahdi_ring_cadence new_cadence; 18107 int cid_location = -1; 18108 int firstcadencepos = 0; 18109 char original_args[80]; 18110 int cadence_is_ok = 1; 18111 18112 ast_copy_string(original_args, v->value, sizeof(original_args)); 18113 /* 16 cadences allowed (8 pairs) */ 18114 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]); 18115 18116 /* Cadence must be even (on/off) */ 18117 if (element_count % 2 == 1) { 18118 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s at line %d.\n", original_args, v->lineno); 18119 cadence_is_ok = 0; 18120 } 18121 18122 /* Ring cadences cannot be negative */ 18123 for (i = 0; i < element_count; i++) { 18124 if (c[i] == 0) { 18125 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s at line %d.\n", original_args, v->lineno); 18126 cadence_is_ok = 0; 18127 break; 18128 } else if (c[i] < 0) { 18129 if (i % 2 == 1) { 18130 /* Silence duration, negative possibly okay */ 18131 if (cid_location == -1) { 18132 cid_location = i; 18133 c[i] *= -1; 18134 } else { 18135 ast_log(LOG_ERROR, "CID location specified twice: %s at line %d.\n", original_args, v->lineno); 18136 cadence_is_ok = 0; 18137 break; 18138 } 18139 } else { 18140 if (firstcadencepos == 0) { 18141 firstcadencepos = i; /* only recorded to avoid duplicate specification */ 18142 /* duration will be passed negative to the DAHDI driver */ 18143 } else { 18144 ast_log(LOG_ERROR, "First cadence position specified twice: %s at line %d.\n", original_args, v->lineno); 18145 cadence_is_ok = 0; 18146 break; 18147 } 18148 } 18149 } 18150 } 18151 18152 /* Substitute our scanned cadence */ 18153 for (i = 0; i < 16; i++) { 18154 new_cadence.ringcadence[i] = c[i]; 18155 } 18156 18157 if (cadence_is_ok) { 18158 /* ---we scanned it without getting annoyed; now some sanity checks--- */ 18159 if (element_count < 2) { 18160 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s at line %d.\n", original_args, v->lineno); 18161 } else { 18162 if (cid_location == -1) { 18163 /* user didn't say; default to first pause */ 18164 cid_location = 1; 18165 } else { 18166 /* convert element_index to cidrings value */ 18167 cid_location = (cid_location + 1) / 2; 18168 } 18169 /* ---we like their cadence; try to install it--- */ 18170 if (!user_has_defined_cadences++) 18171 /* this is the first user-defined cadence; clear the default user cadences */ 18172 num_cadence = 0; 18173 if ((num_cadence+1) >= NUM_CADENCE_MAX) 18174 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s at line %d.\n", NUM_CADENCE_MAX, original_args, v->lineno); 18175 else { 18176 cadences[num_cadence] = new_cadence; 18177 cidrings[num_cadence++] = cid_location; 18178 ast_verb(3, "cadence 'r%d' added: %s\n",num_cadence,original_args); 18179 } 18180 } 18181 } 18182 } else if (!strcasecmp(v->name, "ringtimeout")) { 18183 ringt_base = (atoi(v->value) * 8) / READ_SIZE; 18184 } else if (!strcasecmp(v->name, "prewink")) { 18185 confp->timing.prewinktime = atoi(v->value); 18186 } else if (!strcasecmp(v->name, "preflash")) { 18187 confp->timing.preflashtime = atoi(v->value); 18188 } else if (!strcasecmp(v->name, "wink")) { 18189 confp->timing.winktime = atoi(v->value); 18190 } else if (!strcasecmp(v->name, "flash")) { 18191 confp->timing.flashtime = atoi(v->value); 18192 } else if (!strcasecmp(v->name, "start")) { 18193 confp->timing.starttime = atoi(v->value); 18194 } else if (!strcasecmp(v->name, "rxwink")) { 18195 confp->timing.rxwinktime = atoi(v->value); 18196 } else if (!strcasecmp(v->name, "rxflash")) { 18197 confp->timing.rxflashtime = atoi(v->value); 18198 } else if (!strcasecmp(v->name, "debounce")) { 18199 confp->timing.debouncetime = atoi(v->value); 18200 } else if (!strcasecmp(v->name, "toneduration")) { 18201 int toneduration; 18202 int ctlfd; 18203 int res; 18204 struct dahdi_dialparams dps; 18205 18206 ctlfd = open("/dev/dahdi/ctl", O_RDWR); 18207 if (ctlfd == -1) { 18208 ast_log(LOG_ERROR, "Unable to open /dev/dahdi/ctl to set toneduration at line %d.\n", v->lineno); 18209 return -1; 18210 } 18211 18212 toneduration = atoi(v->value); 18213 if (toneduration > -1) { 18214 memset(&dps, 0, sizeof(dps)); 18215 18216 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration; 18217 res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps); 18218 if (res < 0) { 18219 ast_log(LOG_ERROR, "Invalid tone duration: %d ms at line %d: %s\n", toneduration, v->lineno, strerror(errno)); 18220 close(ctlfd); 18221 return -1; 18222 } 18223 } 18224 close(ctlfd); 18225 } else if (!strcasecmp(v->name, "defaultcic")) { 18226 ast_copy_string(defaultcic, v->value, sizeof(defaultcic)); 18227 } else if (!strcasecmp(v->name, "defaultozz")) { 18228 ast_copy_string(defaultozz, v->value, sizeof(defaultozz)); 18229 } else if (!strcasecmp(v->name, "mwilevel")) { 18230 mwilevel = atoi(v->value); 18231 } else if (!strcasecmp(v->name, "dtmfcidlevel")) { 18232 dtmfcid_level = atoi(v->value); 18233 } else if (!strcasecmp(v->name, "reportalarms")) { 18234 if (!strcasecmp(v->value, "all")) 18235 report_alarms = REPORT_CHANNEL_ALARMS | REPORT_SPAN_ALARMS; 18236 if (!strcasecmp(v->value, "none")) 18237 report_alarms = 0; 18238 else if (!strcasecmp(v->value, "channels")) 18239 report_alarms = REPORT_CHANNEL_ALARMS; 18240 else if (!strcasecmp(v->value, "spans")) 18241 report_alarms = REPORT_SPAN_ALARMS; 18242 } 18243 } else if (!(options & PROC_DAHDI_OPT_NOWARN) ) 18244 ast_log(LOG_WARNING, "Ignoring any changes to '%s' (on reload) at line %d.\n", v->name, v->lineno); 18245 } 18246 18247 /* Since confp has already filled invidual dahdi_pvt objects with channels at this point, clear the variables in confp's pvt. */ 18248 if (confp->chan.vars) { 18249 ast_variables_destroy(confp->chan.vars); 18250 confp->chan.vars = NULL; 18251 } 18252 18253 if (dahdichan) { 18254 /* Process the deferred dahdichan value. */ 18255 if (build_channels(confp, dahdichan->value, reload, dahdichan->lineno, 18256 &found_pseudo)) { 18257 if (confp->ignore_failed_channels) { 18258 ast_log(LOG_WARNING, 18259 "Dahdichan '%s' failure ignored: ignore_failed_channels.\n", 18260 dahdichan->value); 18261 } else { 18262 return -1; 18263 } 18264 } 18265 } 18266 18267 /* mark the first channels of each DAHDI span to watch for their span alarms */ 18268 for (tmp = iflist, y=-1; tmp; tmp = tmp->next) { 18269 if (!tmp->destroy && tmp->span != y) { 18270 tmp->manages_span_alarms = 1; 18271 y = tmp->span; 18272 } else { 18273 tmp->manages_span_alarms = 0; 18274 } 18275 } 18276 18277 /*< \todo why check for the pseudo in the per-channel section. 18278 * Any actual use for manual setup of the pseudo channel? */ 18279 if (!found_pseudo && reload != 1 && !(options & PROC_DAHDI_OPT_NOCHAN)) { 18280 /* use the default configuration for a channel, so 18281 that any settings from real configured channels 18282 don't "leak" into the pseudo channel config 18283 */ 18284 struct dahdi_chan_conf conf = dahdi_chan_conf_default(); 18285 18286 if (conf.chan.cc_params) { 18287 tmp = mkintf(CHAN_PSEUDO, &conf, reload); 18288 } else { 18289 tmp = NULL; 18290 } 18291 if (tmp) { 18292 ast_verb(3, "Automatically generated pseudo channel\n"); 18293 } else { 18294 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n"); 18295 } 18296 ast_cc_config_params_destroy(conf.chan.cc_params); 18297 } 18298 return 0; 18299 }
| static void process_echocancel | ( | struct dahdi_chan_conf * | confp, | |
| const char * | data, | |||
| unsigned int | line | |||
| ) | [static] |
Definition at line 16968 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().
16969 { 16970 char *parse = ast_strdupa(data); 16971 char *params[DAHDI_MAX_ECHOCANPARAMS + 1]; 16972 unsigned int param_count; 16973 unsigned int x; 16974 16975 if (!(param_count = ast_app_separate_args(parse, ',', params, ARRAY_LEN(params)))) 16976 return; 16977 16978 memset(&confp->chan.echocancel, 0, sizeof(confp->chan.echocancel)); 16979 16980 /* first parameter is tap length, process it here */ 16981 16982 x = ast_strlen_zero(params[0]) ? 0 : atoi(params[0]); 16983 16984 if ((x == 32) || (x == 64) || (x == 128) || (x == 256) || (x == 512) || (x == 1024)) 16985 confp->chan.echocancel.head.tap_length = x; 16986 else if ((confp->chan.echocancel.head.tap_length = ast_true(params[0]))) 16987 confp->chan.echocancel.head.tap_length = 128; 16988 16989 /* now process any remaining parameters */ 16990 16991 for (x = 1; x < param_count; x++) { 16992 struct { 16993 char *name; 16994 char *value; 16995 } param; 16996 16997 if (ast_app_separate_args(params[x], '=', (char **) ¶m, 2) < 1) { 16998 ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %d: '%s'\n", line, params[x]); 16999 continue; 17000 } 17001 17002 if (ast_strlen_zero(param.name) || (strlen(param.name) > sizeof(confp->chan.echocancel.params[0].name)-1)) { 17003 ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %d: '%s'\n", line, param.name); 17004 continue; 17005 } 17006 17007 strcpy(confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].name, param.name); 17008 17009 if (param.value) { 17010 if (sscanf(param.value, "%30d", &confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].value) != 1) { 17011 ast_log(LOG_WARNING, "Invalid echocancel parameter value supplied at line %d: '%s'\n", line, param.value); 17012 continue; 17013 } 17014 } 17015 confp->chan.echocancel.head.param_count++; 17016 } 17017 }
| static int reload | ( | void | ) | [static] |
Definition at line 19010 of file chan_dahdi.c.
References ast_log(), LOG_WARNING, and setup_dahdi().
19011 { 19012 int res = 0; 19013 19014 res = setup_dahdi(1); 19015 if (res) { 19016 ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n"); 19017 return -1; 19018 } 19019 return 0; 19020 }
| static int reset_conf | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4816 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().
04817 { 04818 p->confno = -1; 04819 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf)); 04820 if (p->subs[SUB_REAL].dfd > -1) { 04821 struct dahdi_confinfo zi; 04822 04823 memset(&zi, 0, sizeof(zi)); 04824 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi)) 04825 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno)); 04826 } 04827 return 0; 04828 }
| static int restart_monitor | ( | void | ) | [static] |
Definition at line 11958 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, LOG_WARNING, and monlock.
Referenced by dahdi_hangup(), dahdi_request(), h323_reload(), load_module(), mgcp_reload(), mgcp_request(), my_all_subchannels_hungup(), oh323_request(), phone_hangup(), phone_request(), setup_dahdi_int(), sip_reload(), sip_request_call(), unistim_reload(), and unistim_request().
11959 { 11960 /* If we're supposed to be stopped -- stay stopped */ 11961 if (monitor_thread == AST_PTHREADT_STOP) 11962 return 0; 11963 ast_mutex_lock(&monlock); 11964 if (monitor_thread == pthread_self()) { 11965 ast_mutex_unlock(&monlock); 11966 ast_log(LOG_WARNING, "Cannot kill myself\n"); 11967 return -1; 11968 } 11969 if (monitor_thread != AST_PTHREADT_NULL) { 11970 /* Wake up the thread */ 11971 pthread_kill(monitor_thread, SIGURG); 11972 } else { 11973 /* Start a new monitor */ 11974 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 11975 ast_mutex_unlock(&monlock); 11976 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 11977 return -1; 11978 } 11979 } 11980 ast_mutex_unlock(&monlock); 11981 return 0; 11982 }
| static int restore_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5229 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().
05230 { 05231 int res; 05232 if (p->saveconf.confmode) { 05233 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf); 05234 p->saveconf.confmode = 0; 05235 if (res) { 05236 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno)); 05237 return -1; 05238 } 05239 ast_debug(1, "Restored conferencing\n"); 05240 } 05241 return 0; 05242 }
| static int restore_gains | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5136 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().
05137 { 05138 int res; 05139 05140 res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law); 05141 if (res) { 05142 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno)); 05143 return -1; 05144 } 05145 05146 return 0; 05147 }
| static int revert_fax_buffers | ( | struct dahdi_pvt * | p, | |
| struct ast_channel * | ast | |||
| ) | [static] |
Definition at line 6147 of file chan_dahdi.c.
References ast_channel_name(), 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().
06148 { 06149 if (p->bufferoverrideinuse) { 06150 /* faxbuffers are in use, revert them */ 06151 struct dahdi_bufferinfo bi = { 06152 .txbufpolicy = p->buf_policy, 06153 .rxbufpolicy = p->buf_policy, 06154 .bufsize = p->bufsize, 06155 .numbufs = p->buf_no 06156 }; 06157 int bpres; 06158 06159 if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) { 06160 ast_log(LOG_WARNING, "Channel '%s' unable to revert buffer policy: %s\n", ast_channel_name(ast), strerror(errno)); 06161 } 06162 p->bufferoverrideinuse = 0; 06163 return bpres; 06164 } 06165 06166 return -1; 06167 }
| static int save_conference | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5203 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().
05204 { 05205 struct dahdi_confinfo c; 05206 int res; 05207 if (p->saveconf.confmode) { 05208 ast_log(LOG_WARNING, "Can't save conference -- already in use\n"); 05209 return -1; 05210 } 05211 p->saveconf.chan = 0; 05212 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf); 05213 if (res) { 05214 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno)); 05215 p->saveconf.confmode = 0; 05216 return -1; 05217 } 05218 memset(&c, 0, sizeof(c)); 05219 c.confmode = DAHDI_CONF_NORMAL; 05220 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c); 05221 if (res) { 05222 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno)); 05223 return -1; 05224 } 05225 ast_debug(1, "Disabled conferencing\n"); 05226 return 0; 05227 }
| static int send_callerid | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5289 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().
05290 { 05291 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */ 05292 int res; 05293 /* Take out of linear mode if necessary */ 05294 if (p->subs[SUB_REAL].linear) { 05295 p->subs[SUB_REAL].linear = 0; 05296 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0); 05297 } 05298 while (p->cidpos < p->cidlen) { 05299 res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos); 05300 ast_debug(4, "writing callerid at pos %d of %d, res = %d\n", p->cidpos, p->cidlen, res); 05301 if (res < 0) { 05302 if (errno == EAGAIN) 05303 return 0; 05304 else { 05305 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno)); 05306 return -1; 05307 } 05308 } 05309 if (!res) 05310 return 0; 05311 p->cidpos += res; 05312 } 05313 p->cid_suppress_expire = CALLWAITING_SUPPRESS_SAMPLES; 05314 ast_free(p->cidspill); 05315 p->cidspill = NULL; 05316 if (p->callwaitcas) { 05317 /* Wait for CID/CW to expire */ 05318 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES; 05319 p->cid_suppress_expire = p->cidcwexpire; 05320 } else 05321 restore_conference(p); 05322 return 0; 05323 }
| static int send_cwcidspill | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 5244 of file chan_dahdi.c.
References ast_callerid_callwaiting_generate(), ast_format_set(), 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().
05245 { 05246 struct ast_format tmpfmt; 05247 05248 p->callwaitcas = 0; 05249 p->cidcwexpire = 0; 05250 p->cid_suppress_expire = 0; 05251 if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) 05252 return -1; 05253 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, ast_format_set(&tmpfmt, AST_LAW(p), 0)); 05254 /* Make sure we account for the end */ 05255 p->cidlen += READ_SIZE * 4; 05256 p->cidpos = 0; 05257 send_callerid(p); 05258 ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num); 05259 return 0; 05260 }
| static int set_actual_gain | ( | int | fd, | |
| float | rxgain, | |||
| float | txgain, | |||
| float | rxdrc, | |||
| float | txdrc, | |||
| int | law | |||
| ) | [static] |
Definition at line 5117 of file chan_dahdi.c.
References set_actual_rxgain(), and set_actual_txgain().
Referenced by bump_gains(), dahdi_call(), mkintf(), and restore_gains().
05118 { 05119 return set_actual_txgain(fd, txgain, txdrc, law) | set_actual_rxgain(fd, rxgain, rxdrc, law); 05120 }
| static int set_actual_rxgain | ( | int | fd, | |
| float | gain, | |||
| float | drc, | |||
| int | law | |||
| ) | [static] |
Definition at line 5100 of file chan_dahdi.c.
References ast_debug, errno, and fill_rxgain().
Referenced by dahdi_set_swgain(), dahdi_setoption(), and set_actual_gain().
05101 { 05102 struct dahdi_gains g; 05103 int res; 05104 05105 memset(&g, 0, sizeof(g)); 05106 res = ioctl(fd, DAHDI_GETGAINS, &g); 05107 if (res) { 05108 ast_debug(1, "Failed to read gains: %s\n", strerror(errno)); 05109 return res; 05110 } 05111 05112 fill_rxgain(&g, gain, drc, law); 05113 05114 return ioctl(fd, DAHDI_SETGAINS, &g); 05115 }
| static int set_actual_txgain | ( | int | fd, | |
| float | gain, | |||
| float | drc, | |||
| int | law | |||
| ) | [static] |
Definition at line 5083 of file chan_dahdi.c.
References ast_debug, errno, and fill_txgain().
Referenced by dahdi_set_swgain(), dahdi_setoption(), and set_actual_gain().
05084 { 05085 struct dahdi_gains g; 05086 int res; 05087 05088 memset(&g, 0, sizeof(g)); 05089 res = ioctl(fd, DAHDI_GETGAINS, &g); 05090 if (res) { 05091 ast_debug(1, "Failed to read gains: %s\n", strerror(errno)); 05092 return res; 05093 } 05094 05095 fill_txgain(&g, gain, drc, law); 05096 05097 return ioctl(fd, DAHDI_SETGAINS, &g); 05098 }
| static int setup_dahdi | ( | int | reload | ) | [static] |
Definition at line 18620 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().
18621 { 18622 int res; 18623 struct dahdi_chan_conf default_conf = dahdi_chan_conf_default(); 18624 struct dahdi_chan_conf base_conf = dahdi_chan_conf_default(); 18625 struct dahdi_chan_conf conf = dahdi_chan_conf_default(); 18626 18627 if (default_conf.chan.cc_params && base_conf.chan.cc_params && conf.chan.cc_params) { 18628 res = setup_dahdi_int(reload, &default_conf, &base_conf, &conf); 18629 } else { 18630 res = -1; 18631 } 18632 ast_cc_config_params_destroy(default_conf.chan.cc_params); 18633 ast_cc_config_params_destroy(base_conf.chan.cc_params); 18634 ast_cc_config_params_destroy(conf.chan.cc_params); 18635 18636 return res; 18637 }
| 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 18333 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, iflock, 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().
18334 { 18335 struct ast_config *cfg; 18336 struct ast_config *ucfg; 18337 struct ast_variable *v; 18338 struct ast_flags config_flags = { reload == 1 ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 18339 const char *chans; 18340 const char *cat; 18341 int res; 18342 18343 #ifdef HAVE_PRI 18344 char *c; 18345 int spanno; 18346 int i; 18347 int logicalspan; 18348 int trunkgroup; 18349 int dchannels[SIG_PRI_NUM_DCHANS]; 18350 #endif 18351 int have_cfg_now; 18352 static int had_cfg_before = 1;/* So initial load will complain if we don't have cfg. */ 18353 18354 cfg = ast_config_load(config, config_flags); 18355 have_cfg_now = !!cfg; 18356 if (!cfg) { 18357 /* Error if we have no config file */ 18358 if (had_cfg_before) { 18359 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 18360 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 18361 } 18362 cfg = ast_config_new();/* Dummy config */ 18363 if (!cfg) { 18364 return 0; 18365 } 18366 ucfg = ast_config_load("users.conf", config_flags); 18367 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 18368 ast_config_destroy(cfg); 18369 return 0; 18370 } 18371 if (ucfg == CONFIG_STATUS_FILEINVALID) { 18372 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n"); 18373 ast_config_destroy(cfg); 18374 return 0; 18375 } 18376 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 18377 ucfg = ast_config_load("users.conf", config_flags); 18378 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) { 18379 return 0; 18380 } 18381 if (ucfg == CONFIG_STATUS_FILEINVALID) { 18382 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n"); 18383 return 0; 18384 } 18385 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 18386 cfg = ast_config_load(config, config_flags); 18387 have_cfg_now = !!cfg; 18388 if (!cfg) { 18389 if (had_cfg_before) { 18390 /* We should have been able to load the config. */ 18391 ast_log(LOG_ERROR, "Bad. Unable to load config %s\n", config); 18392 ast_config_destroy(ucfg); 18393 return 0; 18394 } 18395 cfg = ast_config_new();/* Dummy config */ 18396 if (!cfg) { 18397 ast_config_destroy(ucfg); 18398 return 0; 18399 } 18400 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 18401 ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config); 18402 ast_config_destroy(ucfg); 18403 return 0; 18404 } 18405 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 18406 ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config); 18407 return 0; 18408 } else { 18409 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 18410 ucfg = ast_config_load("users.conf", config_flags); 18411 if (ucfg == CONFIG_STATUS_FILEINVALID) { 18412 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n"); 18413 ast_config_destroy(cfg); 18414 return 0; 18415 } 18416 } 18417 had_cfg_before = have_cfg_now; 18418 18419 /* It's a little silly to lock it, but we might as well just to be sure */ 18420 ast_mutex_lock(&iflock); 18421 #ifdef HAVE_PRI 18422 if (reload != 1) { 18423 /* Process trunkgroups first */ 18424 v = ast_variable_browse(cfg, "trunkgroups"); 18425 while (v) { 18426 if (!strcasecmp(v->name, "trunkgroup")) { 18427 trunkgroup = atoi(v->value); 18428 if (trunkgroup > 0) { 18429 if ((c = strchr(v->value, ','))) { 18430 i = 0; 18431 memset(dchannels, 0, sizeof(dchannels)); 18432 while (c && (i < SIG_PRI_NUM_DCHANS)) { 18433 dchannels[i] = atoi(c + 1); 18434 if (dchannels[i] < 0) { 18435 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); 18436 } else 18437 i++; 18438 c = strchr(c + 1, ','); 18439 } 18440 if (i) { 18441 if (pri_create_trunkgroup(trunkgroup, dchannels)) { 18442 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); 18443 } else 18444 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"); 18445 } else 18446 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno); 18447 } else 18448 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno); 18449 } else 18450 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->lineno); 18451 } else if (!strcasecmp(v->name, "spanmap")) { 18452 spanno = atoi(v->value); 18453 if (spanno > 0) { 18454 if ((c = strchr(v->value, ','))) { 18455 trunkgroup = atoi(c + 1); 18456 if (trunkgroup > 0) { 18457 if ((c = strchr(c + 1, ','))) 18458 logicalspan = atoi(c + 1); 18459 else 18460 logicalspan = 0; 18461 if (logicalspan >= 0) { 18462 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) { 18463 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 18464 } else 18465 ast_verb(2, "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan); 18466 } else 18467 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); 18468 } else 18469 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of chan_dahdi.conf\n", v->lineno); 18470 } else 18471 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of chan_dahdi.conf\n", v->lineno); 18472 } else 18473 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of chan_dahdi.conf\n", v->lineno); 18474 } else { 18475 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name); 18476 } 18477 v = v->next; 18478 } 18479 } 18480 #endif 18481 18482 /* Copy the default jb config over global_jbconf */ 18483 memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf)); 18484 18485 mwimonitornotify[0] = '\0'; 18486 18487 v = ast_variable_browse(cfg, "channels"); 18488 if ((res = process_dahdi(base_conf, 18489 "" /* Must be empty for the channels category. Silly voicemail mailbox. */, 18490 v, reload, 0))) { 18491 ast_mutex_unlock(&iflock); 18492 ast_config_destroy(cfg); 18493 if (ucfg) { 18494 ast_config_destroy(ucfg); 18495 } 18496 return res; 18497 } 18498 18499 /* Now get configuration from all normal sections in chan_dahdi.conf: */ 18500 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) { 18501 /* [channels] and [trunkgroups] are used. Let's also reserve 18502 * [globals] and [general] for future use 18503 */ 18504 if (!strcasecmp(cat, "general") || 18505 !strcasecmp(cat, "trunkgroups") || 18506 !strcasecmp(cat, "globals") || 18507 !strcasecmp(cat, "channels")) { 18508 continue; 18509 } 18510 18511 chans = ast_variable_retrieve(cfg, cat, "dahdichan"); 18512 if (ast_strlen_zero(chans)) { 18513 /* Section is useless without a dahdichan value present. */ 18514 continue; 18515 } 18516 18517 /* Copy base_conf to conf. */ 18518 deep_copy_dahdi_chan_conf(conf, base_conf); 18519 18520 if ((res = process_dahdi(conf, cat, ast_variable_browse(cfg, cat), reload, PROC_DAHDI_OPT_NOCHAN))) { 18521 ast_mutex_unlock(&iflock); 18522 ast_config_destroy(cfg); 18523 if (ucfg) { 18524 ast_config_destroy(ucfg); 18525 } 18526 return res; 18527 } 18528 } 18529 18530 ast_config_destroy(cfg); 18531 18532 if (ucfg) { 18533 /* Reset base_conf, so things don't leak from chan_dahdi.conf */ 18534 deep_copy_dahdi_chan_conf(base_conf, default_conf); 18535 process_dahdi(base_conf, 18536 "" /* Must be empty for the general category. Silly voicemail mailbox. */, 18537 ast_variable_browse(ucfg, "general"), 1, 0); 18538 18539 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 18540 if (!strcasecmp(cat, "general")) { 18541 continue; 18542 } 18543 18544 chans = ast_variable_retrieve(ucfg, cat, "dahdichan"); 18545 if (ast_strlen_zero(chans)) { 18546 /* Section is useless without a dahdichan value present. */ 18547 continue; 18548 } 18549 18550 /* Copy base_conf to conf. */ 18551 deep_copy_dahdi_chan_conf(conf, base_conf); 18552 18553 if ((res = process_dahdi(conf, cat, ast_variable_browse(ucfg, cat), reload, PROC_DAHDI_OPT_NOCHAN | PROC_DAHDI_OPT_NOWARN))) { 18554 ast_config_destroy(ucfg); 18555 ast_mutex_unlock(&iflock); 18556 return res; 18557 } 18558 } 18559 ast_config_destroy(ucfg); 18560 } 18561 ast_mutex_unlock(&iflock); 18562 18563 #ifdef HAVE_PRI 18564 if (reload != 1) { 18565 int x; 18566 for (x = 0; x < NUM_SPANS; x++) { 18567 if (pris[x].pri.pvts[0]) { 18568 prepare_pri(pris + x); 18569 if (sig_pri_start_pri(&pris[x].pri)) { 18570 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1); 18571 return -1; 18572 } else 18573 ast_verb(2, "Starting D-Channel on span %d\n", x + 1); 18574 } 18575 } 18576 } 18577 #endif 18578 #if defined(HAVE_SS7) 18579 if (reload != 1) { 18580 int x; 18581 for (x = 0; x < NUM_SPANS; x++) { 18582 if (linksets[x].ss7.ss7) { 18583 linksets[x].ss7.calls = &dahdi_ss7_callbacks; 18584 if (ast_pthread_create(&linksets[x].ss7.master, NULL, ss7_linkset, &linksets[x].ss7)) { 18585 ast_log(LOG_ERROR, "Unable to start SS7 linkset on span %d\n", x + 1); 18586 return -1; 18587 } else 18588 ast_verb(2, "Starting SS7 linkset on span %d\n", x + 1); 18589 } 18590 } 18591 } 18592 #endif /* defined(HAVE_SS7) */ 18593 #ifdef HAVE_OPENR2 18594 if (reload != 1) { 18595 int x; 18596 for (x = 0; x < r2links_count; x++) { 18597 if (ast_pthread_create(&r2links[x]->r2master, NULL, mfcr2_monitor, r2links[x])) { 18598 ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1); 18599 return -1; 18600 } else { 18601 ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1); 18602 } 18603 } 18604 } 18605 #endif 18606 /* And start the monitor for the first time */ 18607 restart_monitor(); 18608 return 0; 18609 }
| static int sigtype_to_signalling | ( | int | sigtype | ) | [static] |
Definition at line 12242 of file chan_dahdi.c.
Referenced by mkintf().
12243 { 12244 return sigtype; 12245 }
| static void string_replace | ( | char * | str, | |
| int | char1, | |||
| int | char2 | |||
| ) | [static] |
Definition at line 16872 of file chan_dahdi.c.
Referenced by parse_spanchan().
16873 { 16874 for (; *str; str++) { 16875 if (*str == char1) { 16876 *str = char2; 16877 } 16878 } 16879 }
| static void swap_subs | ( | struct dahdi_pvt * | p, | |
| int | a, | |||
| int | b | |||
| ) | [static] |
Definition at line 4275 of file chan_dahdi.c.
References ast_channel_set_fd(), ast_debug, dahdi_subchannel::chan, dahdi_subchannel::dfd, dahdi_subchannel::inthreeway, dahdi_subchannel::owner, dahdi_pvt::subs, and wakeup_sub().
Referenced by analog_ss_thread(), attempt_transfer(), dahdi_handle_event(), dahdi_hangup(), HandleCallOutgoing(), and unistim_hangup().
04276 { 04277 int tchan; 04278 int tinthreeway; 04279 struct ast_channel *towner; 04280 04281 ast_debug(1, "Swapping %d and %d\n", a, b); 04282 04283 tchan = p->subs[a].chan; 04284 towner = p->subs[a].owner; 04285 tinthreeway = p->subs[a].inthreeway; 04286 04287 p->subs[a].chan = p->subs[b].chan; 04288 p->subs[a].owner = p->subs[b].owner; 04289 p->subs[a].inthreeway = p->subs[b].inthreeway; 04290 04291 p->subs[b].chan = tchan; 04292 p->subs[b].owner = towner; 04293 p->subs[b].inthreeway = tinthreeway; 04294 04295 if (p->subs[a].owner) 04296 ast_channel_set_fd(p->subs[a].owner, 0, p->subs[a].dfd); 04297 if (p->subs[b].owner) 04298 ast_channel_set_fd(p->subs[b].owner, 0, p->subs[b].dfd); 04299 wakeup_sub(p, a); 04300 wakeup_sub(p, b); 04301 }
| static int unalloc_sub | ( | struct dahdi_pvt * | p, | |
| int | x | |||
| ) | [static] |
Definition at line 4421 of file chan_dahdi.c.
References ast_debug, ast_log(), dahdi_subchannel::chan, dahdi_pvt::channel, dahdi_subchannel::curconf, dahdi_close_sub(), dahdi_subchannel::inthreeway, dahdi_subchannel::linear, LOG_WARNING, dahdi_subchannel::owner, dahdi_pvt::polarity, POLARITY_IDLE, and dahdi_pvt::subs.
Referenced by analog_ss_thread(), attempt_transfer(), dahdi_handle_event(), dahdi_hangup(), my_unallocate_sub(), and unistim_hangup().
04422 { 04423 if (!x) { 04424 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel); 04425 return -1; 04426 } 04427 ast_debug(1, "Released sub %d of channel %d\n", x, p->channel); 04428 dahdi_close_sub(p, x); 04429 p->subs[x].linear = 0; 04430 p->subs[x].chan = 0; 04431 p->subs[x].owner = NULL; 04432 p->subs[x].inthreeway = 0; 04433 p->polarity = POLARITY_IDLE; 04434 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf)); 04435 return 0; 04436 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 16856 of file chan_dahdi.c.
References __unload_module(), ast_mutex_destroy, and sig_ss7_linkset::lock.
16857 { 16858 #if defined(HAVE_PRI) || defined(HAVE_SS7) 16859 int y; 16860 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */ 16861 #ifdef HAVE_PRI 16862 for (y = 0; y < NUM_SPANS; y++) 16863 ast_mutex_destroy(&pris[y].pri.lock); 16864 #endif 16865 #if defined(HAVE_SS7) 16866 for (y = 0; y < NUM_SPANS; y++) 16867 ast_mutex_destroy(&linksets[y].ss7.lock); 16868 #endif /* defined(HAVE_SS7) */ 16869 return __unload_module(); 16870 }
| static int update_conf | ( | struct dahdi_pvt * | p | ) | [static] |
Definition at line 4830 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().
04831 { 04832 int needconf = 0; 04833 int x; 04834 int useslavenative; 04835 struct dahdi_pvt *slave = NULL; 04836 04837 useslavenative = isslavenative(p, &slave); 04838 /* Start with the obvious, general stuff */ 04839 for (x = 0; x < 3; x++) { 04840 /* Look for three way calls */ 04841 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) { 04842 conf_add(p, &p->subs[x], x, 0); 04843 needconf++; 04844 } else { 04845 conf_del(p, &p->subs[x], x); 04846 } 04847 } 04848 /* If we have a slave, add him to our conference now. or DAX 04849 if this is slave native */ 04850 for (x = 0; x < MAX_SLAVES; x++) { 04851 if (p->slaves[x]) { 04852 if (useslavenative) 04853 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p)); 04854 else { 04855 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0); 04856 needconf++; 04857 } 04858 } 04859 } 04860 /* If we're supposed to be in there, do so now */ 04861 if (p->inconference && !p->subs[SUB_REAL].inthreeway) { 04862 if (useslavenative) 04863 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave)); 04864 else { 04865 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0); 04866 needconf++; 04867 } 04868 } 04869 /* If we have a master, add ourselves to his conference */ 04870 if (p->master) { 04871 if (isslavenative(p->master, NULL)) { 04872 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master)); 04873 } else { 04874 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0); 04875 } 04876 } 04877 if (!needconf) { 04878 /* Nobody is left (or should be left) in our conference. 04879 Kill it. */ 04880 p->confno = -1; 04881 } 04882 ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf); 04883 return 0; 04884 }
| static void wakeup_sub | ( | struct dahdi_pvt * | p, | |
| int | a | |||
| ) | [static] |
Definition at line 3788 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().
03789 { 03790 dahdi_lock_sub_owner(p, a); 03791 if (p->subs[a].owner) { 03792 ast_queue_frame(p->subs[a].owner, &ast_null_frame); 03793 ast_channel_unlock(p->subs[a].owner); 03794 } 03795 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = tdesc , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_smdi", } [static] |
Definition at line 19032 of file chan_dahdi.c.
| int alarm |
Definition at line 4568 of file chan_dahdi.c.
struct { ... } alarms[] [static] |
Referenced by alarm2str().
struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}} [static] |
Definition at line 420 of file chan_dahdi.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 19032 of file chan_dahdi.c.
struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] [static] |
Definition at line 401 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 412 of file chan_dahdi.c.
const char config[] = "chan_dahdi.conf" [static] |
Definition at line 355 of file chan_dahdi.c.
struct analog_callback dahdi_analog_callbacks [static] |
Definition at line 3665 of file chan_dahdi.c.
struct ast_data_handler dahdi_channels_data_provider [static] |
Initial value:
{
.version = AST_DATA_HANDLER_VERSION,
.get = dahdi_channels_data_provider_get
}
Definition at line 18780 of file chan_dahdi.c.
struct ast_cli_entry dahdi_cli[] [static] |
Definition at line 15867 of file chan_dahdi.c.
struct ast_data_entry dahdi_data_providers[] [static] |
Initial value:
{
AST_DATA_ENTRY("asterisk/channel/dahdi/status", &dahdi_status_data_provider),
AST_DATA_ENTRY("asterisk/channel/dahdi/channels", &dahdi_channels_data_provider),
}
Definition at line 18790 of file chan_dahdi.c.
struct ast_data_handler dahdi_status_data_provider [static] |
Initial value:
{
.version = AST_DATA_HANDLER_VERSION,
.get = dahdi_status_data_provider_get
}
Definition at line 18775 of file chan_dahdi.c.
struct ast_channel_tech dahdi_tech [static] |
Definition at line 1527 of file chan_dahdi.c.
struct ast_data_handler dahdi_version_data_provider [static] |
Initial value:
{
.version = AST_DATA_HANDLER_VERSION,
.get = dahdi_version_data_provider_get
}
Definition at line 18785 of file chan_dahdi.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 304 of file chan_dahdi.c.
char defaultcic[64] = "" [static] |
Definition at line 428 of file chan_dahdi.c.
char defaultozz[64] = "" [static] |
Definition at line 429 of file chan_dahdi.c.
int distinctiveringaftercid = 0 [static] |
Definition at line 440 of file chan_dahdi.c.
int dtmfcid_level = 256 [static] |
Definition at line 445 of file chan_dahdi.c.
const char* const events[] [static] |
Definition at line 4545 of file chan_dahdi.c.
int firstdigittimeout = 16000 [static] |
Wait up to 16 seconds for first digit (FXO logic).
Definition at line 457 of file chan_dahdi.c.
Referenced by disa_exec().
int gendigittimeout = 8000 [static] |
struct ast_jb_conf global_jbconf [static] |
Definition at line 312 of file chan_dahdi.c.
int ifcount = 0 [static] |
Definition at line 469 of file chan_dahdi.c.
Main interface list end
Definition at line 1327 of file chan_dahdi.c.
Main interface list start
Definition at line 1326 of file chan_dahdi.c.
Referenced by __oh323_destroy(), __unload_module(), do_monitor(), find_call_locked(), load_module(), oh323_alloc(), phone_request(), and unload_module().
ast_mutex_t iflock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static] |
Protect the interface list (of dahdi_pvt's).
Definition at line 466 of file chan_dahdi.c.
Referenced by __unload_module(), action_dahdishowchannels(), dahdi_cc_callback(), dahdi_channels_data_provider_get(), dahdi_destroy_channel_bynum(), dahdi_hangup(), dahdi_request(), dahdi_restart(), dahdi_set_dnd(), dahdi_set_hwgain(), dahdi_set_swgain(), dahdi_show_channel(), dahdi_show_channels(), dahdi_softhangup_all(), destroy_all_channels(), do_monitor(), find_call_locked(), find_channel(), load_module(), oh323_alloc(), oh323_destroy(), phone_request(), restart_monitor(), setup_dahdi_int(), and unload_module().
const char* const lbostr[] [static] |
Definition at line 291 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 463 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 481 of file chan_dahdi.c.
ast_mutex_t monlock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static] |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
Definition at line 477 of file chan_dahdi.c.
Referenced by __unload_module(), dahdi_restart(), do_monitor(), restart_monitor(), and unload_module().
int mwilevel = 512 [static] |
Definition at line 444 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 432 of file chan_dahdi.c.
int mwisend_rpas = 0 [static] |
Definition at line 434 of file chan_dahdi.c.
| char* name |
Definition at line 4569 of file chan_dahdi.c.
int num_cadence = 4 [static] |
Definition at line 398 of file chan_dahdi.c.
int num_restart_pending = 0 [static] |
Definition at line 486 of file chan_dahdi.c.
int numbufs = 4 [static] |
Definition at line 442 of file chan_dahdi.c.
char progzone[10] = "" [static] |
Definition at line 437 of file chan_dahdi.c.
int report_alarms = REPORT_CHANNEL_ALARMS [static] |
Definition at line 449 of file chan_dahdi.c.
ast_mutex_t restart_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static] |
int ringt_base = DEFAULT_RINGT [static] |
Configured ring timeout base.
Definition at line 542 of file chan_dahdi.c.
struct dahdi_pvt* round_robin[32] [static] |
Round robin search locations.
Definition at line 3735 of file chan_dahdi.c.
ast_cond_t ss_thread_complete [static] |
Definition at line 482 of file chan_dahdi.c.
int ss_thread_count = 0 [static] |
Definition at line 485 of file chan_dahdi.c.
ast_mutex_t ss_thread_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static] |
Definition at line 483 of file chan_dahdi.c.
Referenced by analog_ss_thread(), dahdi_restart(), my_decrease_ss_count(), and my_increase_ss_count().
const char* const subnames[] [static] |
const char tdesc[] = "DAHDI Telephony Driver" [static] |
Definition at line 334 of file chan_dahdi.c.
int usedistinctiveringdetection = 0 [static] |
Definition at line 439 of file chan_dahdi.c.
int user_has_defined_cadences = 0 [static] |
Definition at line 399 of file chan_dahdi.c.
1.5.6