Asterisk - The Open Source Telephony Project GIT-master-85241bd
Data Structures | Macros | Functions | Variables
chan_dahdi.c File Reference

DAHDI for Pseudo TDM. More...

#include "asterisk.h"
#include <sys/sysmacros.h>
#include <signal.h>
#include <sys/stat.h>
#include <math.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/pickup.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/tdd.h"
#include "asterisk/mwi.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/devicestate.h"
#include "asterisk/paths.h"
#include "asterisk/ccss.h"
#include "asterisk/features_config.h"
#include "asterisk/bridge.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/parking.h"
#include "asterisk/format_cache.h"
#include "chan_dahdi.h"
#include "dahdi/bridge_native_dahdi.h"
Include dependency graph for chan_dahdi.c:

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_starting_point
 
struct  mwi_thread_data
 

Macros

#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 DEFAULT_CIDRINGS   1
 Typically, how many rings before we should send Caller*ID. More...
 
#define DEFAULT_DIALTONE_DETECT_TIMEOUT   ((10000 * 8) / READ_SIZE)
 
#define DEFAULT_RINGT   ((8000 * 8) / READ_SIZE)
 
#define END_SILENCE_LEN   400
 
#define FORMAT   "%7s %4d %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"
 
#define FORMAT   "%4d %-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n"
 
#define FORMAT2   "%7s %4s %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"
 
#define FORMAT2   "%4s %-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n"
 
#define gen_pvt_field_callback(type, field)
 
#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 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. More...
 
#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 SMDI_MD_WAIT_TIMEOUT   1500 /* 1.5 seconds */
 
#define TRAILER_MS   5
 
#define TRANSFER   0
 

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)
 
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_dahdishowstatus (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 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)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int attempt_transfer (struct dahdi_pvt *p)
 
static int available (struct dahdi_pvt **pvt, int is_specific_channel)
 
static void build_alarm_info (char *restrict alarmstr, struct dahdi_spaninfo *spaninfo)
 
static int build_channels (struct dahdi_chan_conf *conf, const char *value, int reload, int lineno)
 
static int bump_gains (struct dahdi_pvt *p)
 
static int calc_energy (const unsigned char *buf, int len, struct ast_format *law)
 
static int canmatch_featurecode (const char *pickupexten, 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_strcreate_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 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(). More...
 
static struct dahdi_chan_conf dahdi_chan_conf_default (void)
 
static void dahdi_close (int fd)
 
static void dahdi_close_sub (struct dahdi_pvt *chan_pvt, int sub_num)
 
void dahdi_conf_update (struct dahdi_pvt *p)
 
static int dahdi_confmute (struct dahdi_pvt *p, int muted)
 
static int dahdi_create_channel_range (int start, int end)
 
static char * dahdi_create_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void dahdi_destroy_channel_range (int start, int end)
 
static char * dahdi_destroy_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int dahdi_devicestate (const char *data)
 
static int dahdi_dial_str (struct dahdi_pvt *pvt, int operation, const char *dial_str)
 
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 int dahdi_dnd (struct dahdi_pvt *dahdichan, int flag)
 enable or disable the chan_dahdi Do-Not-Disturb mode for a DAHDI channel More...
 
void dahdi_dtmf_detect_disable (struct dahdi_pvt *p)
 
void dahdi_dtmf_detect_enable (struct dahdi_pvt *p)
 
void dahdi_ec_disable (struct dahdi_pvt *p)
 
void dahdi_ec_enable (struct dahdi_pvt *p)
 
static struct ast_framedahdi_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. More...
 
static void dahdi_handle_dtmf (struct ast_channel *ast, int idx, struct ast_frame **dest)
 
static struct ast_framedahdi_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_lock_sub_owner (struct dahdi_pvt *pvt, int sub_idx)
 
void dahdi_master_slave_link (struct dahdi_pvt *slave, struct dahdi_pvt *master)
 
void dahdi_master_slave_unlink (struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
 
static struct ast_channeldahdi_new (struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, ast_callid callid)
 
static struct ast_channeldahdi_new_callid_clean (struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, ast_callid callid, int callid_created)
 
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_framedahdi_read (struct ast_channel *ast)
 
static struct ast_channeldahdi_request (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, 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_mwi (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 void dahdi_softhangup_all (void)
 
static void dahdi_train_ec (struct dahdi_pvt *p)
 
static int dahdi_wait_event (int fd)
 Avoid the silly dahdi_waitevent which ignores a bunch of events. More...
 
static int dahdi_wink (struct dahdi_pvt *p, int index)
 
static int dahdi_write (struct ast_channel *ast, struct ast_frame *frame)
 
static struct ast_manager_event_blobdahdichannel_to_ami (struct stasis_message *msg)
 
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_pvtdetermine_starting_point (const char *data, struct dahdi_starting_point *param)
 
static int digit_to_dtmfindex (char digit)
 
static void * do_monitor (void *data)
 
static int drc_sample (int sample, float drc)
 
static struct dahdi_pvtduplicate_pseudo (struct dahdi_pvt *src)
 
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_pvtfind_channel (int channel)
 
static struct dahdi_pvtfind_channel_from_str (const char *channel)
 
static struct dahdi_pvtfind_next_iface_in_span (struct dahdi_pvt *cur)
 
static struct dahdi_pvtfxo_pvt (struct ast_channel *chan)
 Return DAHDI pivot if channel is FXO signalled. More...
 
 gen_pvt_field_callback (int, firstdigit_timeout)
 
 gen_pvt_field_callback (int, interdigit_timeout)
 
 gen_pvt_field_callback (int, matchdigit_timeout)
 
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_pvthandle_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)
 Load the module. More...
 
static struct dahdi_pvtmkintf (int channel, const struct dahdi_chan_conf *conf, int reloading)
 
static void monitor_pfds_clean (void *arg)
 
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_channelmy_new_analog_ast_channel (void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
 
static int my_off_hook (void *pvt)
 
static int my_on_hook (void *pvt)
 
static int my_play_tone (void *pvt, enum analog_sub sub, enum analog_tone tone)
 
static int my_ring (void *pvt)
 
static int my_send_callerid (void *pvt, int cwcid, struct ast_party_caller *caller)
 
static void my_set_alarm (void *pvt, int in_alarm)
 
static void my_set_cadence (void *pvt, int *cid_rings, struct ast_channel *ast)
 
static void my_set_callwaiting (void *pvt, int callwaiting_enable)
 
static void my_set_confirmanswer (void *pvt, int flag)
 
static void my_set_dialing (void *pvt, int is_dialing)
 
static int my_set_echocanceller (void *pvt, int enable)
 
static void my_set_inthreeway (void *pvt, enum analog_sub sub, int inthreeway)
 
static int my_set_linear_mode (void *pvt, enum analog_sub sub, int linear_mode)
 
static void my_set_needringing (void *pvt, int value)
 
static void my_set_new_owner (void *pvt, struct ast_channel *new_owner)
 
static void my_set_outgoing (void *pvt, int is_outgoing)
 
static void my_set_polarity (void *pvt, int value)
 
static void my_set_pulsedial (void *pvt, int flag)
 
static void my_set_ringtimeout (void *pvt, int ringt)
 
static void my_set_waitingfordt (void *pvt, struct ast_channel *ast)
 
static int my_start (void *pvt)
 
static int my_start_cid_detect (void *pvt, int cid_signalling)
 
static void my_start_polarityswitch (void *pvt)
 
static int my_stop_callwait (void *pvt)
 
static int my_stop_cid_detect (void *pvt)
 
static void my_swap_subchannels (void *pvt, enum analog_sub a, struct ast_channel *ast_a, enum analog_sub b, struct ast_channel *ast_b)
 
static int my_train_echocanceller (void *pvt)
 
static int my_unallocate_sub (void *pvt, enum analog_sub analogsub)
 
static void my_unlock_private (void *pvt)
 
static int my_wait_event (void *pvt)
 
static int my_wink (void *pvt, enum analog_sub sub)
 
static void notify_message (char *mailbox, int thereornot)
 Send MWI state change. More...
 
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 int polarity_read (struct ast_channel *chan, const char *cmd, char *data, char *buffer, size_t buflen)
 
static int polarity_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 
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 void publish_channel_alarm (int channel, const char *alarm_txt)
 
static void publish_channel_alarm_clear (int channel)
 
static void publish_dahdichannel (struct ast_channel *chan, ast_group_t group, int span, const char *dahdi_channel)
 Sends a DAHDIChannel channel blob used to produce DAHDIChannel AMI messages. More...
 
static void publish_dnd_state (int channel, const char *status)
 
static void publish_span_alarm (int span, const char *alarm_txt)
 
static void publish_span_alarm_clear (int span)
 
static void release_doomed_pris (void)
 
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 set_hwgain (int fd, float gain, int tx_direction)
 
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)
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (dahdichannel_type,.to_ami=dahdichannel_to_ami,)
 
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 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, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .requires = "ccss", .optional_modules = "res_smdi", }
 
struct {
   int   alarm
 
   char *   name
 
alarms []
 
struct analog_callback analog_callbacks
 
static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}}
 
static const struct ast_module_infoast_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. More...
 
static const char config [] = "chan_dahdi.conf"
 
static struct ast_cli_entry dahdi_cli []
 
static struct ast_channel_tech dahdi_tech
 
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 struct ast_jb_conf global_jbconf
 
static int has_pseudo
 
static int ifcount = 0
 
static struct dahdi_pvtifend = NULL
 
static struct dahdi_pvtiflist = NULL
 
static ast_mutex_t iflock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 Protect the interface list (of dahdi_pvt's) More...
 
static const char *const lbostr []
 
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. More...
 
static ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. More...
 
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 struct ast_custom_function polarity_function
 
static char progzone [10] = ""
 
static int report_alarms = REPORT_CHANNEL_ALARMS
 
static ast_mutex_t restart_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static int ringt_base = DEFAULT_RINGT
 Configured ring timeout base. More...
 
static struct dahdi_pvtround_robin [64]
 
static ast_cond_t ss_thread_complete
 
static int ss_thread_count = 0
 
static ast_mutex_t ss_thread_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
const char *const subnames []
 
static const char tdesc [] = "DAHDI Telephony"
 
static int usedistinctiveringdetection = 0
 
static int user_has_defined_cadences = 0
 

Detailed Description

DAHDI for Pseudo TDM.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

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.

Todo:
Deprecate the "musiconhold" configuration option post 1.4

Definition in file chan_dahdi.c.

Macro Definition Documentation

◆ ASCII_BYTES_PER_CHAR

#define ASCII_BYTES_PER_CHAR   80

◆ AST_LAW

#define AST_LAW (   p)    (((p)->law == DAHDI_LAW_ALAW) ? ast_format_alaw : ast_format_ulaw)

Definition at line 642 of file chan_dahdi.c.

◆ CALLPROGRESS_FAX

#define CALLPROGRESS_FAX   (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)

Definition at line 682 of file chan_dahdi.c.

◆ CALLPROGRESS_FAX_INCOMING

#define CALLPROGRESS_FAX_INCOMING   4

Definition at line 681 of file chan_dahdi.c.

◆ CALLPROGRESS_FAX_OUTGOING

#define CALLPROGRESS_FAX_OUTGOING   2

Definition at line 680 of file chan_dahdi.c.

◆ CALLPROGRESS_PROGRESS

#define CALLPROGRESS_PROGRESS   1

Definition at line 679 of file chan_dahdi.c.

◆ CALLWAITING_REPEAT_SAMPLES

#define CALLWAITING_REPEAT_SAMPLES   ((10000 * 8) / READ_SIZE)

10,000 ms

Definition at line 800 of file chan_dahdi.c.

◆ CALLWAITING_SILENT_SAMPLES

#define CALLWAITING_SILENT_SAMPLES   ((300 * 8) / READ_SIZE)

300 ms

Definition at line 799 of file chan_dahdi.c.

◆ CALLWAITING_SUPPRESS_SAMPLES

#define CALLWAITING_SUPPRESS_SAMPLES   ((100 * 8) / READ_SIZE)

100 ms

Definition at line 801 of file chan_dahdi.c.

◆ CANBUSYDETECT

#define CANBUSYDETECT (   p)    (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)

Definition at line 714 of file chan_dahdi.c.

◆ CANPROGRESSDETECT

#define CANPROGRESSDETECT (   p)    (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)

Definition at line 715 of file chan_dahdi.c.

◆ CHAN_PSEUDO

#define CHAN_PSEUDO   -2

Definition at line 677 of file chan_dahdi.c.

◆ CIDCW_EXPIRE_SAMPLES

#define CIDCW_EXPIRE_SAMPLES   ((500 * 8) / READ_SIZE)

500 ms

Definition at line 802 of file chan_dahdi.c.

◆ DEFAULT_CIDRINGS

#define DEFAULT_CIDRINGS   1

Typically, how many rings before we should send Caller*ID.

Note
Define ZHONE_HACK to cause us to go off hook and then back on hook when the user hangs up to reset the state machine so ring works properly. This is used to be able to support kewlstart by putting the zhone in groundstart mode since their forward disconnect supervision is entirely broken even though their documentation says it isn't and their support is entirely unwilling to provide any assistance with their channel banks even though their web site says they support their products for life.

Definition at line 640 of file chan_dahdi.c.

◆ DEFAULT_DIALTONE_DETECT_TIMEOUT

#define DEFAULT_DIALTONE_DETECT_TIMEOUT   ((10000 * 8) / READ_SIZE)

10,000 ms

Definition at line 805 of file chan_dahdi.c.

◆ DEFAULT_RINGT

#define DEFAULT_RINGT   ((8000 * 8) / READ_SIZE)

8,000 ms

Definition at line 804 of file chan_dahdi.c.

◆ END_SILENCE_LEN

#define END_SILENCE_LEN   400

◆ FORMAT [1/2]

#define FORMAT   "%7s %4d %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"

◆ FORMAT [2/2]

#define FORMAT   "%4d %-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n"

◆ FORMAT2 [1/2]

#define FORMAT2   "%7s %4s %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"

◆ FORMAT2 [2/2]

#define FORMAT2   "%4s %-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n"

◆ gen_pvt_field_callback

#define gen_pvt_field_callback (   type,
  field 
)
Value:
static type my_get_##field(void *pvt) \
{ \
struct dahdi_pvt *p = pvt; \
return p->field; \
}
static const char type[]
Definition: chan_ooh323.c:109

Definition at line 3603 of file chan_dahdi.c.

◆ GET_CHANNEL

#define GET_CHANNEL (   p)    ((p)->channel)

Definition at line 1180 of file chan_dahdi.c.

◆ HANGUP

#define HANGUP   1

Definition at line 16737 of file chan_dahdi.c.

◆ HEADER_LEN

#define HEADER_LEN   ((HEADER_MS + TRAILER_MS) * 8)

◆ HEADER_MS

#define HEADER_MS   50

◆ ISTRUNK

#define ISTRUNK (   p)
Value:
((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
(p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
#define SIG_FXSLS
Definition: chan_dahdi.h:786
#define SIG_FXSKS
Definition: chan_dahdi.h:788
#define SIG_FXSGS
Definition: chan_dahdi.h:787
#define SIG_PRI
Definition: chan_dahdi.h:800

Definition at line 711 of file chan_dahdi.c.

◆ MASK_AVAIL

#define MASK_AVAIL   (1 << 0)

Channel available for PRI use

Definition at line 796 of file chan_dahdi.c.

◆ MASK_INUSE

#define MASK_INUSE   (1 << 1)

Channel currently in use

Definition at line 797 of file chan_dahdi.c.

◆ MAX_CHANLIST_LEN

#define MAX_CHANLIST_LEN   80

The length of the parameters list of 'dahdichan'.

Todo:
Move definition of MAX_CHANLIST_LEN to a proper place.

Definition at line 18297 of file chan_dahdi.c.

◆ MIN_MS_SINCE_FLASH

#define MIN_MS_SINCE_FLASH   ((2000) )

2000 ms

Definition at line 803 of file chan_dahdi.c.

◆ NEED_MFDETECT

#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 646 of file chan_dahdi.c.

◆ NUM_CADENCE_MAX

#define NUM_CADENCE_MAX   25

Definition at line 684 of file chan_dahdi.c.

◆ NUM_SPANS

#define NUM_SPANS   32

Definition at line 674 of file chan_dahdi.c.

◆ POLARITY_IDLE

#define POLARITY_IDLE   0

Definition at line 913 of file chan_dahdi.c.

◆ POLARITY_REV

#define POLARITY_REV   1

Definition at line 914 of file chan_dahdi.c.

◆ PROC_DAHDI_OPT_NOCHAN

#define PROC_DAHDI_OPT_NOCHAN   (1 << 0)

process_dahdi() - ignore keyword 'channel' and similar

Definition at line 18432 of file chan_dahdi.c.

◆ PROC_DAHDI_OPT_NOWARN

#define PROC_DAHDI_OPT_NOWARN   (1 << 1)

process_dahdi() - No warnings on non-existing cofiguration keywords

Definition at line 18434 of file chan_dahdi.c.

◆ READ_SIZE

#define READ_SIZE   160

Chunk size to read – we use 20ms chunks to make things happy.

Definition at line 794 of file chan_dahdi.c.

◆ REPORT_CHANNEL_ALARMS

#define REPORT_CHANNEL_ALARMS   1

Definition at line 736 of file chan_dahdi.c.

◆ REPORT_SPAN_ALARMS

#define REPORT_SPAN_ALARMS   2

Definition at line 737 of file chan_dahdi.c.

◆ sig2str

#define sig2str   dahdi_sig2str

Definition at line 4715 of file chan_dahdi.c.

◆ SMDI_MD_WAIT_TIMEOUT

#define SMDI_MD_WAIT_TIMEOUT   1500 /* 1.5 seconds */

Definition at line 603 of file chan_dahdi.c.

◆ TRAILER_MS

#define TRAILER_MS   5

◆ TRANSFER

#define TRANSFER   0

Definition at line 16736 of file chan_dahdi.c.

Function Documentation

◆ __dahdi_exception()

static struct ast_frame * __dahdi_exception ( struct ast_channel ast)
static

Definition at line 8651 of file chan_dahdi.c.

8652{
8653 int res;
8654 int idx;
8655 struct ast_frame *f;
8656 int usedindex = -1;
8657 struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
8658
8659 if ((idx = dahdi_get_index(ast, p, 0)) < 0) {
8660 idx = SUB_REAL;
8661 }
8662
8663 p->subs[idx].f.frametype = AST_FRAME_NULL;
8664 p->subs[idx].f.datalen = 0;
8665 p->subs[idx].f.samples = 0;
8666 p->subs[idx].f.mallocd = 0;
8667 p->subs[idx].f.offset = 0;
8668 p->subs[idx].f.subclass.integer = 0;
8669 p->subs[idx].f.delivery = ast_tv(0,0);
8670 p->subs[idx].f.src = "dahdi_exception";
8671 p->subs[idx].f.data.ptr = NULL;
8672
8673
8674 if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
8675 /* If nobody owns us, absorb the event appropriately, otherwise
8676 we loop indefinitely. This occurs when, during call waiting, the
8677 other end hangs up our channel so that it no longer exists, but we
8678 have neither FLASH'd nor ONHOOK'd to signify our desire to
8679 change to the other channel. */
8680 if (p->fake_event) {
8681 res = p->fake_event;
8682 p->fake_event = 0;
8683 } else
8684 res = dahdi_get_event(p->subs[SUB_REAL].dfd);
8685 /* Switch to real if there is one and this isn't something really silly... */
8686 if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) &&
8687 (res != DAHDI_EVENT_HOOKCOMPLETE)) {
8688 ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
8689 p->owner = p->subs[SUB_REAL].owner;
8690 if (p->owner) {
8692 }
8693 p->subs[SUB_REAL].needunhold = 1;
8694 }
8695 switch (res) {
8696 case DAHDI_EVENT_ONHOOK:
8698 if (p->owner) {
8699 ast_verb(3, "Channel %s still has call, ringing phone\n", ast_channel_name(p->owner));
8701 p->callwaitingrepeat = 0;
8702 p->cidcwexpire = 0;
8703 p->cid_suppress_expire = 0;
8704 } else
8705 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
8707 break;
8708 case DAHDI_EVENT_RINGOFFHOOK:
8709 dahdi_ec_enable(p);
8710 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
8711 if (p->owner && (ast_channel_state(p->owner) == AST_STATE_RINGING)) {
8712 p->subs[SUB_REAL].needanswer = 1;
8713 p->dialing = 0;
8714 }
8715 break;
8716 case DAHDI_EVENT_HOOKCOMPLETE:
8717 case DAHDI_EVENT_RINGERON:
8718 case DAHDI_EVENT_RINGEROFF:
8719 /* Do nothing */
8720 break;
8721 case DAHDI_EVENT_WINKFLASH:
8722 p->flashtime = ast_tvnow();
8723 if (p->owner) {
8724 ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, ast_channel_name(p->owner));
8726 /* Answer if necessary */
8727 usedindex = dahdi_get_index(p->owner, p, 0);
8728 if (usedindex > -1) {
8729 p->subs[usedindex].needanswer = 1;
8730 }
8732 }
8733 p->callwaitingrepeat = 0;
8734 p->cidcwexpire = 0;
8735 p->cid_suppress_expire = 0;
8737 p->subs[SUB_REAL].needunhold = 1;
8738 } else
8739 ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
8741 break;
8742 default:
8743 ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
8744 }
8745 f = &p->subs[idx].f;
8746 return f;
8747 }
8748 if (!(p->radio || (p->oprmode < 0)))
8749 ast_debug(1, "Exception on %d, channel %d\n", ast_channel_fd(ast, 0), p->channel);
8750 /* If it's not us, return NULL immediately */
8751 if (ast != p->owner) {
8752 if (p->owner) {
8753 ast_log(LOG_WARNING, "We're %s, not %s\n", ast_channel_name(ast), ast_channel_name(p->owner));
8754 }
8755 f = &p->subs[idx].f;
8756 return f;
8757 }
8758
8759 f = dahdi_handle_event(ast);
8760 if (!f) {
8761 const char *name = ast_strdupa(ast_channel_name(ast));
8762
8763 /* Tell the CDR this DAHDI device hung up */
8765 ast_channel_unlock(ast);
8766 ast_set_hangupsource(ast, name, 0);
8767 ast_channel_lock(ast);
8768 ast_mutex_lock(&p->lock);
8769 }
8770 return f;
8771}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
static int dahdi_ring_phone(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7464
char * name
Definition: chan_dahdi.c:4621
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:5182
void dahdi_ec_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4898
void dahdi_conf_update(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4843
static struct ast_frame * dahdi_handle_event(struct ast_channel *ast)
Definition: chan_dahdi.c:7749
static const char * event2str(int event)
Definition: chan_dahdi.c:4642
void dahdi_ec_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4970
static int dahdi_get_event(int fd)
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition: chan_dahdi.c:773
#define SUB_REAL
Definition: chan_dahdi.h:57
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:882
const char * ast_channel_name(const struct ast_channel *chan)
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
int ast_channel_fd(const struct ast_channel *chan, int which)
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
Definition: channel.c:2499
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
#define ast_channel_unlock(chan)
Definition: channel.h:2923
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_RINGING
Definition: channelstate.h:41
@ AST_STATE_UP
Definition: channelstate.h:42
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7386
@ AST_FRAME_NULL
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
#define LOG_WARNING
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
#define NULL
Definition: resample.c:96
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
struct timeval delivery
enum ast_frame_type frametype
const char * src
int cid_suppress_expire
Definition: chan_dahdi.h:595
struct timeval flashtime
Definition: chan_dahdi.h:692
int oprmode
Definition: chan_dahdi.h:151
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct ast_channel * owner
Definition: chan_dahdi.h:127
int fake_event
Holding place for event injected from outside normal operation.
Definition: chan_dahdi.h:722
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
int cidcwexpire
Definition: chan_dahdi.h:594
int callwaitingrepeat
Definition: chan_dahdi.h:593
ast_mutex_t lock
Definition: chan_dahdi.h:125
int channel
Definition: chan_dahdi.h:585
unsigned int dialing
TRUE if in the process of dialing digits or sending something.
Definition: chan_dahdi.h:258
unsigned int needanswer
Definition: chan_dahdi.h:86
unsigned int needunhold
Definition: chan_dahdi.h:89
struct ast_frame f
Definition: chan_dahdi.h:82
struct ast_channel * owner
Definition: chan_dahdi.h:79
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:235

References ast_channel_fd(), ast_channel_lock, ast_channel_name(), ast_channel_tech_pvt(), ast_channel_unlock, ast_debug, AST_FRAME_NULL, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_queue_unhold(), ast_set_hangupsource(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_tv(), ast_tvnow(), ast_verb, dahdi_pvt::callwaitingrepeat, dahdi_pvt::channel, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cidcwexpire, dahdi_conf_update(), dahdi_ec_disable(), dahdi_ec_enable(), 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, dahdi_pvt::flashtime, ast_frame::frametype, ast_frame_subclass::integer, dahdi_pvt::lock, LOG_WARNING, ast_frame::mallocd, name, dahdi_subchannel::needanswer, dahdi_subchannel::needunhold, NULL, 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, and dahdi_pvt::subs.

Referenced by dahdi_exception(), and dahdi_read().

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 20533 of file chan_dahdi.c.

◆ __unload_module()

static int __unload_module ( void  )
static

Definition at line 18108 of file chan_dahdi.c.

18109{
18110 struct dahdi_pvt *p;
18111#if defined(HAVE_PRI) || defined(HAVE_SS7)
18112 int i, j;
18113#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
18114
18115#ifdef HAVE_PRI
18116 for (i = 0; i < NUM_SPANS; i++) {
18117 if (pris[i].pri.master != AST_PTHREADT_NULL) {
18118 pthread_cancel(pris[i].pri.master);
18119 pthread_kill(pris[i].pri.master, SIGURG);
18120 }
18121 }
18122 ast_cli_unregister_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
18123 ast_unregister_application(dahdi_send_keypad_facility_app);
18124#ifdef HAVE_PRI_PROG_W_CAUSE
18125 ast_unregister_application(dahdi_send_callrerouting_facility_app);
18126#endif
18127#endif
18128#if defined(HAVE_SS7)
18129 for (i = 0; i < NUM_SPANS; i++) {
18130 if (linksets[i].ss7.master != AST_PTHREADT_NULL) {
18131 pthread_cancel(linksets[i].ss7.master);
18132 pthread_kill(linksets[i].ss7.master, SIGURG);
18133 }
18134 }
18135 ast_cli_unregister_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli));
18136#endif /* defined(HAVE_SS7) */
18137#if defined(HAVE_OPENR2)
18138 dahdi_r2_destroy_links();
18139 ast_cli_unregister_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli));
18140 ast_unregister_application(dahdi_accept_r2_call_app);
18141#endif
18142
18144
18146 ast_manager_unregister("DAHDIDialOffhook");
18147 ast_manager_unregister("DAHDIHangup");
18148 ast_manager_unregister("DAHDITransfer");
18149 ast_manager_unregister("DAHDIDNDoff");
18150 ast_manager_unregister("DAHDIDNDon");
18151 ast_manager_unregister("DAHDIShowChannels");
18152 ast_manager_unregister("DAHDIShowStatus");
18153 ast_manager_unregister("DAHDIRestart");
18154#if defined(HAVE_PRI)
18155 ast_manager_unregister("PRIShowSpans");
18156 ast_manager_unregister("PRIDebugSet");
18157 ast_manager_unregister("PRIDebugFileSet");
18158 ast_manager_unregister("PRIDebugFileUnset");
18159#endif /* defined(HAVE_PRI) */
18161
18162 /* Hangup all interfaces if they have an owner */
18164 for (p = iflist; p; p = p->next) {
18165 if (p->owner)
18167 }
18169
18172 pthread_cancel(monitor_thread);
18173 pthread_kill(monitor_thread, SIGURG);
18174 pthread_join(monitor_thread, NULL);
18175 }
18178
18180
18181#if defined(HAVE_PRI)
18182 for (i = 0; i < NUM_SPANS; i++) {
18183 if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) {
18184 pthread_join(pris[i].pri.master, NULL);
18185 }
18186 for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) {
18187 dahdi_close_pri_fd(&(pris[i]), j);
18188 }
18189 sig_pri_stop_pri(&pris[i].pri);
18190 }
18191#if defined(HAVE_PRI_CCSS)
18192 ast_cc_agent_unregister(&dahdi_pri_cc_agent_callbacks);
18193 ast_cc_monitor_unregister(&dahdi_pri_cc_monitor_callbacks);
18194#endif /* defined(HAVE_PRI_CCSS) */
18196#endif
18197
18198#if defined(HAVE_SS7)
18199 for (i = 0; i < NUM_SPANS; i++) {
18200 if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) {
18201 pthread_join(linksets[i].ss7.master, NULL);
18202 }
18203 for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) {
18204 dahdi_close_ss7_fd(&(linksets[i]), j);
18205 }
18206 if (linksets[i].ss7.ss7) {
18207 ss7_destroy(linksets[i].ss7.ss7);
18208 linksets[i].ss7.ss7 = NULL;
18209 }
18210 }
18211#endif /* defined(HAVE_SS7) */
18213
18215
18218 STASIS_MESSAGE_TYPE_CLEANUP(dahdichannel_type);
18219 return 0;
18220}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
void dahdi_native_unload(void)
void ast_cc_monitor_unregister(const struct ast_cc_monitor_callbacks *callbacks)
Unregister a set of monitor callbacks with the core.
Definition: ccss.c:1195
void ast_cc_agent_unregister(const struct ast_cc_agent_callbacks *callbacks)
Unregister a set of agent callbacks with the core.
Definition: ccss.c:1232
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt's)
Definition: chan_dahdi.c:746
#define NUM_SPANS
Definition: chan_dahdi.c:674
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:922
static ast_cond_t ss_thread_complete
Definition: chan_dahdi.c:762
static ast_mutex_t monlock
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing some...
Definition: chan_dahdi.c:757
static struct ast_channel_tech dahdi_tech
Definition: chan_dahdi.c:1157
static struct ast_custom_function polarity_function
Definition: chan_dahdi.c:2915
static struct ast_cli_entry dahdi_cli[]
Definition: chan_dahdi.c:16721
static pthread_t monitor_thread
This is the thread for the monitor which checks for input on the channels which are not currently in ...
Definition: chan_dahdi.c:761
static void destroy_all_channels(void)
Definition: chan_dahdi.c:5925
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2471
@ AST_SOFTHANGUP_APPUNLOAD
Definition: channel.h:1143
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8057
#define ast_cond_destroy(cond)
Definition: lock.h:202
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define AST_PTHREADT_STOP
Definition: lock.h:67
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
void sig_pri_unload(void)
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:239
void sig_pri_stop_pri(struct sig_pri_span *pri)
#define SIG_SS7_NUM_DCHANS
Definition: sig_ss7.h:56
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515
struct ast_format_cap * capabilities
Definition: channel.h:632
struct dahdi_pvt * next
Definition: chan_dahdi.h:169
#define ARRAY_LEN(a)
Definition: utils.h:666

References ao2_cleanup, ARRAY_LEN, ast_cc_agent_unregister(), ast_cc_monitor_unregister(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_destroy, ast_custom_function_unregister(), 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, dahdi_cli, dahdi_native_unload(), dahdi_tech, destroy_all_channels(), iflist, iflock, sig_pri_span::master, sig_ss7_linkset::master, monitor_thread, monlock, dahdi_pvt::next, NULL, NUM_SPANS, dahdi_pvt::owner, polarity_function, SIG_PRI_NUM_DCHANS, sig_pri_stop_pri(), sig_pri_unload(), SIG_SS7_NUM_DCHANS, sig_ss7_linkset::ss7, ss_thread_complete, and STASIS_MESSAGE_TYPE_CLEANUP.

Referenced by load_module(), and unload_module().

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 20533 of file chan_dahdi.c.

◆ _dahdi_get_index()

int _dahdi_get_index ( struct ast_channel ast,
struct dahdi_pvt p,
int  nullok,
const char *  fname,
unsigned long  line 
)

Definition at line 3692 of file chan_dahdi.c.

3693{
3694 int res;
3695 if (p->subs[SUB_REAL].owner == ast)
3696 res = 0;
3697 else if (p->subs[SUB_CALLWAIT].owner == ast)
3698 res = 1;
3699 else if (p->subs[SUB_THREEWAY].owner == ast)
3700 res = 2;
3701 else {
3702 res = -1;
3703 if (!nullok)
3705 "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
3706 ast ? ast_channel_name(ast) : "", p->channel, fname, line);
3707 }
3708 return res;
3709}
#define SUB_THREEWAY
Definition: chan_dahdi.h:59
#define SUB_CALLWAIT
Definition: chan_dahdi.h:58

References ast_channel_name(), ast_log, dahdi_pvt::channel, LOG_WARNING, dahdi_subchannel::owner, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, and dahdi_pvt::subs.

◆ action_dahdidialoffhook()

static int action_dahdidialoffhook ( struct mansession s,
const struct message m 
)
static

Definition at line 16874 of file chan_dahdi.c.

16875{
16876 struct dahdi_pvt *p;
16877 const char *channel = astman_get_header(m, "DAHDIChannel");
16878 const char *number = astman_get_header(m, "Number");
16879 int i;
16880
16881 if (ast_strlen_zero(channel)) {
16882 astman_send_error(s, m, "No channel specified");
16883 return 0;
16884 }
16885 if (ast_strlen_zero(number)) {
16886 astman_send_error(s, m, "No number specified");
16887 return 0;
16888 }
16890 if (!p) {
16891 astman_send_error(s, m, "No such channel");
16892 return 0;
16893 }
16894 if (!p->owner) {
16895 astman_send_error(s, m, "Channel does not have it's owner");
16896 return 0;
16897 }
16898 for (i = 0; i < strlen(number); i++) {
16899 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = number[i] };
16900 dahdi_queue_frame(p, &f);
16901 }
16902 astman_send_ack(s, m, "DAHDIDialOffhook");
16903 return 0;
16904}
static struct dahdi_pvt * find_channel_from_str(const char *channel)
Definition: chan_dahdi.c:16778
static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
Definition: chan_dahdi.c:3749
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3389
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3421
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:3050
#define AST_FRAME_DTMF
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Number structure.
Definition: app_followme.c:154

References AST_FRAME_DTMF, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_queue_frame(), find_channel_from_str(), and dahdi_pvt::owner.

Referenced by load_module().

◆ action_dahdidndoff()

static int action_dahdidndoff ( struct mansession s,
const struct message m 
)
static

Definition at line 16809 of file chan_dahdi.c.

16810{
16811 struct dahdi_pvt *p;
16812 const char *channel = astman_get_header(m, "DAHDIChannel");
16813
16814 if (ast_strlen_zero(channel)) {
16815 astman_send_error(s, m, "No channel specified");
16816 return 0;
16817 }
16819 if (!p) {
16820 astman_send_error(s, m, "No such channel");
16821 return 0;
16822 }
16823 dahdi_dnd(p, 0);
16824 astman_send_ack(s, m, "DND Disabled");
16825 return 0;
16826}
static int dahdi_dnd(struct dahdi_pvt *dahdichan, int flag)
enable or disable the chan_dahdi Do-Not-Disturb mode for a DAHDI channel
Definition: chan_dahdi.c:9843

References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_dnd(), and find_channel_from_str().

Referenced by load_module().

◆ action_dahdidndon()

static int action_dahdidndon ( struct mansession s,
const struct message m 
)
static

Definition at line 16790 of file chan_dahdi.c.

16791{
16792 struct dahdi_pvt *p;
16793 const char *channel = astman_get_header(m, "DAHDIChannel");
16794
16795 if (ast_strlen_zero(channel)) {
16796 astman_send_error(s, m, "No channel specified");
16797 return 0;
16798 }
16800 if (!p) {
16801 astman_send_error(s, m, "No such channel");
16802 return 0;
16803 }
16804 dahdi_dnd(p, 1);
16805 astman_send_ack(s, m, "DND Enabled");
16806 return 0;
16807}

References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_dnd(), and find_channel_from_str().

Referenced by load_module().

◆ action_dahdirestart()

static int action_dahdirestart ( struct mansession s,
const struct message m 
)
static

Definition at line 15979 of file chan_dahdi.c.

15980{
15981 if (dahdi_restart() != 0) {
15982 astman_send_error(s, m, "Failed rereading DAHDI configuration");
15983 return 1;
15984 }
15985 astman_send_ack(s, m, "DAHDIRestart: Success");
15986 return 0;
15987}
static int dahdi_restart(void)
Definition: chan_dahdi.c:15841

References astman_send_ack(), astman_send_error(), and dahdi_restart().

Referenced by load_module().

◆ action_dahdishowchannels()

static int action_dahdishowchannels ( struct mansession s,
const struct message m 
)
static

Definition at line 16906 of file chan_dahdi.c.

16907{
16908 struct dahdi_pvt *tmp = NULL;
16909 const char *id = astman_get_header(m, "ActionID");
16910 const char *dahdichannel = astman_get_header(m, "DAHDIChannel");
16911 char idText[256];
16912 int channels = 0;
16913 int dahdichanquery;
16914
16915 if (!dahdichannel || sscanf(dahdichannel, "%30d", &dahdichanquery) != 1) {
16916 /* Not numeric string. */
16917 dahdichanquery = -1;
16918 }
16919
16920 idText[0] = '\0';
16921 if (!ast_strlen_zero(id)) {
16922 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
16923 }
16924
16925 astman_send_listack(s, m, "DAHDI channel status will follow", "start");
16926
16928
16929 for (tmp = iflist; tmp; tmp = tmp->next) {
16930 if (tmp->channel > 0) {
16931 int alm;
16932
16933 /* If a specific channel is queried for, only deliver status for that channel */
16934 if (dahdichanquery > 0 && tmp->channel != dahdichanquery)
16935 continue;
16936
16937 alm = get_alarms(tmp);
16938 channels++;
16939 if (tmp->owner) {
16940 /* Add data if we have a current call */
16941 astman_append(s,
16942 "Event: DAHDIShowChannels\r\n"
16943 "DAHDIChannel: %d\r\n"
16944 "Channel: %s\r\n"
16945 "Uniqueid: %s\r\n"
16946 "AccountCode: %s\r\n"
16947 "Signalling: %s\r\n"
16948 "SignallingCode: %d\r\n"
16949 "Context: %s\r\n"
16950 "DND: %s\r\n"
16951 "Alarm: %s\r\n"
16952 "Description: %s\r\n"
16953 "%s"
16954 "\r\n",
16955 tmp->channel,
16956 ast_channel_name(tmp->owner),
16957 ast_channel_uniqueid(tmp->owner),
16959 sig2str(tmp->sig),
16960 tmp->sig,
16961 tmp->context,
16962 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled",
16963 alarm2str(alm),
16964 tmp->description, idText);
16965 } else {
16966 astman_append(s,
16967 "Event: DAHDIShowChannels\r\n"
16968 "DAHDIChannel: %d\r\n"
16969 "Signalling: %s\r\n"
16970 "SignallingCode: %d\r\n"
16971 "Context: %s\r\n"
16972 "DND: %s\r\n"
16973 "Alarm: %s\r\n"
16974 "Description: %s\r\n"
16975 "%s"
16976 "\r\n",
16977 tmp->channel, sig2str(tmp->sig), tmp->sig,
16978 tmp->context,
16979 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled",
16980 alarm2str(alm),
16981 tmp->description, idText);
16982 }
16983 }
16984 }
16985
16987
16988 astman_send_list_complete_start(s, m, "DAHDIShowChannelsComplete", channels);
16989 astman_append(s, "Items: %d\r\n", channels);
16991 return 0;
16992}
static int tmp()
Definition: bt_open.c:389
static char * alarm2str(int alm)
Definition: chan_dahdi.c:4632
#define sig2str
Definition: chan_dahdi.c:4715
static int get_alarms(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7567
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_channel_accountcode(const struct ast_channel *chan)
static struct channel_usage channels
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3431
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3467
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3475
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3310

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_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), channels, dahdi_dnd(), get_alarms(), iflist, iflock, NULL, sig2str, and tmp().

Referenced by load_module().

◆ action_dahdishowstatus()

static int action_dahdishowstatus ( struct mansession s,
const struct message m 
)
static

Definition at line 16994 of file chan_dahdi.c.

16995{
16996 const char *id = astman_get_header(m, "ActionID");
16997 int span;
16998 int res;
16999 char alarmstr[50];
17000 int ctl;
17001 char idText[256];
17002 int numspans = 0;
17003 struct dahdi_spaninfo spaninfo;
17004
17005 ctl = open("/dev/dahdi/ctl", O_RDWR);
17006 if (ctl < 0) {
17007 astman_send_error(s, m, "No DAHDI detected");
17008 return 0;
17009 }
17010
17011 idText[0] = '\0';
17012 if (!ast_strlen_zero(id)) {
17013 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
17014 }
17015 astman_send_listack(s, m, "DAHDI span statuses will follow", "start");
17016
17017 for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
17018 spaninfo.spanno = span;
17019 res = ioctl(ctl, DAHDI_SPANSTAT, &spaninfo);
17020 if (res) {
17021 continue;
17022 }
17023 numspans++;
17024 build_alarm_info(alarmstr, &spaninfo);
17025 astman_append(s,
17026 "Event: DAHDIShowStatus\r\n"
17027 "Span: %d\r\n"
17028 "Description: %s\r\n"
17029 "Alarms: %s\r\n"
17030 "IRQ: %d\r\n"
17031 "bpviol: %d\r\n"
17032 "CRC: %d\r\n"
17033 "Framing: %s\r\n"
17034 "Coding: %s\r\n"
17035 "Options: %s\r\n"
17036 "LBO: %s\r\n"
17037 "%s"
17038 "\r\n",
17039 span, spaninfo.desc, alarmstr, spaninfo.irqmisses, spaninfo.bpvcount, spaninfo.crc4count,
17040 spaninfo.lineconfig & DAHDI_CONFIG_D4 ? "D4" :
17041 spaninfo.lineconfig & DAHDI_CONFIG_ESF ? "ESF" :
17042 spaninfo.lineconfig & DAHDI_CONFIG_CCS ? "CCS" :
17043 "CAS",
17044 spaninfo.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" :
17045 spaninfo.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" :
17046 spaninfo.lineconfig & DAHDI_CONFIG_AMI ? "AMI" :
17047 "Unk",
17048 spaninfo.lineconfig & DAHDI_CONFIG_CRC4 ?
17049 spaninfo.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" :
17050 spaninfo.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : "",
17051 lbostr[spaninfo.lbo],
17052 idText);
17053 }
17054 close(ctl);
17055
17056 astman_send_list_complete_start(s, m, "DAHDIShowStatusComplete", numspans);
17057 astman_append(s, "Items: %d\r\n", numspans);
17059 return 0;
17060}
static void build_alarm_info(char *restrict alarmstr, struct dahdi_spaninfo *spaninfo)
Definition: chan_dahdi.c:16309
static const char *const lbostr[]
Definition: chan_dahdi.c:605

References ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), build_alarm_info(), lbostr, and dahdi_pvt::span.

Referenced by load_module().

◆ action_transfer()

static int action_transfer ( struct mansession s,
const struct message m 
)
static

Definition at line 16828 of file chan_dahdi.c.

16829{
16830 struct dahdi_pvt *p;
16831 const char *channel = astman_get_header(m, "DAHDIChannel");
16832
16833 if (ast_strlen_zero(channel)) {
16834 astman_send_error(s, m, "No channel specified");
16835 return 0;
16836 }
16838 if (!p) {
16839 astman_send_error(s, m, "No such channel");
16840 return 0;
16841 }
16842 if (!dahdi_analog_lib_handles(p->sig, 0, 0)) {
16843 astman_send_error(s, m, "Channel signaling is not analog");
16844 return 0;
16845 }
16847 astman_send_ack(s, m, "DAHDITransfer");
16848 return 0;
16849}
#define TRANSFER
Definition: chan_dahdi.c:16736
static int dahdi_fake_event(struct dahdi_pvt *p, int mode)
Definition: chan_dahdi.c:16739
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:841

References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_analog_lib_handles(), dahdi_fake_event(), find_channel_from_str(), dahdi_pvt::sig, and TRANSFER.

Referenced by load_module().

◆ action_transferhangup()

static int action_transferhangup ( struct mansession s,
const struct message m 
)
static

Definition at line 16851 of file chan_dahdi.c.

16852{
16853 struct dahdi_pvt *p;
16854 const char *channel = astman_get_header(m, "DAHDIChannel");
16855
16856 if (ast_strlen_zero(channel)) {
16857 astman_send_error(s, m, "No channel specified");
16858 return 0;
16859 }
16861 if (!p) {
16862 astman_send_error(s, m, "No such channel");
16863 return 0;
16864 }
16865 if (!dahdi_analog_lib_handles(p->sig, 0, 0)) {
16866 astman_send_error(s, m, "Channel signaling is not analog");
16867 return 0;
16868 }
16870 astman_send_ack(s, m, "DAHDIHangup");
16871 return 0;
16872}
#define HANGUP
Definition: chan_dahdi.c:16737

References ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_pvt::channel, dahdi_analog_lib_handles(), dahdi_fake_event(), find_channel_from_str(), HANGUP, and dahdi_pvt::sig.

Referenced by load_module().

◆ alarm2str()

static char * alarm2str ( int  alm)
static

Definition at line 4632 of file chan_dahdi.c.

4633{
4634 int x;
4635 for (x = 0; x < ARRAY_LEN(alarms); x++) {
4636 if (alarms[x].alarm & alm)
4637 return alarms[x].name;
4638 }
4639 return alm ? "Unknown Alarm" : "No Alarm";
4640}
int alarm
Definition: chan_dahdi.c:4620
static struct @114 alarms[]

References alarm, alarms, and ARRAY_LEN.

Referenced by action_dahdishowchannels(), dahdi_show_channels(), and handle_alarms().

◆ alloc_sub()

static int alloc_sub ( struct dahdi_pvt p,
int  x 
)
static

Definition at line 4427 of file chan_dahdi.c.

4428{
4429 struct dahdi_bufferinfo bi;
4430 int res;
4431 if (p->subs[x].dfd >= 0) {
4432 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
4433 return -1;
4434 }
4435
4436 p->subs[x].dfd = dahdi_open("/dev/dahdi/pseudo");
4437 if (p->subs[x].dfd <= -1) {
4438 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
4439 return -1;
4440 }
4441
4442 res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi);
4443 if (!res) {
4444 bi.txbufpolicy = p->buf_policy;
4445 bi.rxbufpolicy = p->buf_policy;
4446 bi.numbufs = p->buf_no;
4447 res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi);
4448 if (res < 0) {
4449 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno));
4450 }
4451 } else
4452 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno));
4453
4454 if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) {
4455 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno));
4456 dahdi_close_sub(p, x);
4457 p->subs[x].dfd = -1;
4458 return -1;
4459 }
4460 ast_debug(1, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan);
4461 return 0;
4462}
static int dahdi_open(char *fn)
Definition: chan_dahdi.c:4346
static void dahdi_close_sub(struct dahdi_pvt *chan_pvt, int sub_num)
Definition: chan_dahdi.c:4399
const char *const subnames[]
Definition: chan_dahdi.c:916
int errno
int buf_policy
Definition: chan_dahdi.h:140
int buf_no
Definition: chan_dahdi.h:139

References ast_debug, ast_log, dahdi_pvt::buf_no, dahdi_pvt::buf_policy, dahdi_subchannel::chan, dahdi_pvt::channel, dahdi_close_sub(), dahdi_open(), dahdi_subchannel::dfd, errno, LOG_WARNING, subnames, and dahdi_pvt::subs.

Referenced by analog_ss_thread(), dahdi_handle_event(), and my_allocate_sub().

◆ analog_ss_thread()

static void * analog_ss_thread ( void *  data)
static

Definition at line 9889 of file chan_dahdi.c.

9890{
9891 struct ast_channel *chan = data;
9892 struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
9893 char exten[AST_MAX_EXTENSION] = "";
9894 char exten2[AST_MAX_EXTENSION] = "";
9895 unsigned char buf[256];
9896 char dtmfcid[300];
9897 char dtmfbuf[300];
9898 struct callerid_state *cs = NULL;
9899 char *name = NULL, *number = NULL;
9900 int distMatches;
9901 int curRingData[3];
9902 int receivedRingT;
9903 int counter1;
9904 int counter;
9905 int samples = 0;
9906 struct ast_smdi_md_message *smdi_msg = NULL;
9907 int flags = 0;
9908 int i;
9909 int timeout;
9910 int getforward = 0;
9911 char *s1, *s2;
9912 int len = 0;
9913 int res;
9914 int idx;
9915 RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
9916 const char *pickupexten;
9917
9921 /* in the bizarre case where the channel has become a zombie before we
9922 even get started here, abort safely
9923 */
9924 if (!p) {
9925 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", ast_channel_name(chan));
9926 ast_hangup(chan);
9927 goto quit;
9928 }
9929 ast_verb(3, "Starting simple switch on '%s'\n", ast_channel_name(chan));
9930 idx = dahdi_get_index(chan, p, 1);
9931 if (idx < 0) {
9932 ast_log(LOG_WARNING, "Huh?\n");
9933 ast_hangup(chan);
9934 goto quit;
9935 }
9936
9937 ast_channel_lock(chan);
9938 pickup_cfg = ast_get_chan_features_pickup_config(chan);
9939 if (!pickup_cfg) {
9940 ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
9941 pickupexten = "";
9942 } else {
9943 pickupexten = ast_strdupa(pickup_cfg->pickupexten);
9944 }
9945 ast_channel_unlock(chan);
9946
9947 if (p->dsp)
9949 switch (p->sig) {
9950 case SIG_FEATD:
9951 case SIG_FEATDMF:
9952 case SIG_FEATDMF_TA:
9953 case SIG_E911:
9954 case SIG_FGC_CAMAMF:
9955 case SIG_FEATB:
9956 case SIG_EMWINK:
9957 case SIG_SF_FEATD:
9958 case SIG_SF_FEATDMF:
9959 case SIG_SF_FEATB:
9960 case SIG_SFWINK:
9961 if (dahdi_wink(p, idx))
9962 goto quit;
9963 /* Fall through */
9964 case SIG_EM:
9965 case SIG_EM_E1:
9966 case SIG_SF:
9967 case SIG_FGC_CAMA:
9968 res = tone_zone_play_tone(p->subs[idx].dfd, -1);
9969 if (p->dsp)
9971 /* set digit mode appropriately */
9972 if (p->dsp) {
9973 if (NEED_MFDETECT(p))
9975 else
9977 }
9978 memset(dtmfbuf, 0, sizeof(dtmfbuf));
9979 /* Wait for the first digit only if immediate=no */
9980 if (!p->immediate)
9981 /* Wait for the first digit (up to 5 seconds). */
9982 res = ast_waitfordigit(chan, 5000);
9983 else
9984 res = 0;
9985 if (res > 0) {
9986 /* save first char */
9987 dtmfbuf[0] = res;
9988 switch (p->sig) {
9989 case SIG_FEATD:
9990 case SIG_SF_FEATD:
9991 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
9992 if (res > 0)
9993 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
9994 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
9995 break;
9996 case SIG_FEATDMF_TA:
9997 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
9998 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
9999 if (dahdi_wink(p, idx)) goto quit;
10000 dtmfbuf[0] = 0;
10001 /* Wait for the first digit (up to 5 seconds). */
10002 res = ast_waitfordigit(chan, 5000);
10003 if (res <= 0) break;
10004 dtmfbuf[0] = res;
10005 /* fall through intentionally */
10006 case SIG_FEATDMF:
10007 case SIG_E911:
10008 case SIG_FGC_CAMAMF:
10009 case SIG_SF_FEATDMF:
10010 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
10011 /* if international caca, do it again to get real ANO */
10012 if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
10013 {
10014 if (dahdi_wink(p, idx)) goto quit;
10015 dtmfbuf[0] = 0;
10016 /* Wait for the first digit (up to 5 seconds). */
10017 res = ast_waitfordigit(chan, 5000);
10018 if (res <= 0) break;
10019 dtmfbuf[0] = res;
10020 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
10021 }
10022 if (res > 0) {
10023 /* if E911, take off hook */
10024 if (p->sig == SIG_E911)
10025 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
10026 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
10027 }
10028 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
10029 break;
10030 case SIG_FEATB:
10031 case SIG_SF_FEATB:
10032 res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
10033 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
10034 break;
10035 case SIG_EMWINK:
10036 /* if we received a '*', we are actually receiving Feature Group D
10037 dial syntax, so use that mode; otherwise, fall through to normal
10038 mode
10039 */
10040 if (res == '*') {
10041 res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
10042 if (res > 0)
10043 res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
10044 if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
10045 break;
10046 }
10047 default:
10048 /* If we got the first digit, get the rest */
10049 len = 1;
10050 dtmfbuf[len] = '\0';
10051 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
10052 if (ast_exists_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
10053 timeout = p->matchdigit_timeout;
10054 } else {
10055 timeout = p->interdigit_timeout;
10056 }
10057 res = ast_waitfordigit(chan, timeout);
10058 if (res < 0) {
10059 ast_debug(1, "waitfordigit returned < 0...\n");
10060 ast_hangup(chan);
10061 goto quit;
10062 } else if (res) {
10063 dtmfbuf[len++] = res;
10064 dtmfbuf[len] = '\0';
10065 } else {
10066 break;
10067 }
10068 }
10069 break;
10070 }
10071 }
10072 if (res == -1) {
10073 ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
10074 ast_hangup(chan);
10075 goto quit;
10076 } else if (res < 0) {
10077 ast_debug(1, "Got hung up before digits finished\n");
10078 ast_hangup(chan);
10079 goto quit;
10080 }
10081
10082 if (p->sig == SIG_FGC_CAMA) {
10083 char anibuf[100];
10084
10085 if (ast_safe_sleep(chan,1000) == -1) {
10086 ast_hangup(chan);
10087 goto quit;
10088 }
10089 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
10091 res = my_getsigstr(chan, anibuf, "#", 10000);
10092 if ((res > 0) && (strlen(anibuf) > 2)) {
10093 if (anibuf[strlen(anibuf) - 1] == '#')
10094 anibuf[strlen(anibuf) - 1] = 0;
10095 ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
10096 }
10098 }
10099
10100 ast_copy_string(exten, dtmfbuf, sizeof(exten));
10101 if (ast_strlen_zero(exten))
10102 ast_copy_string(exten, "s", sizeof(exten));
10103 if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
10104 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
10105 if (exten[0] == '*') {
10106 char *stringp=NULL;
10107 ast_copy_string(exten2, exten, sizeof(exten2));
10108 /* Parse out extension and callerid */
10109 stringp=exten2 +1;
10110 s1 = strsep(&stringp, "*");
10111 s2 = strsep(&stringp, "*");
10112 if (s2) {
10113 if (!ast_strlen_zero(p->cid_num))
10114 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
10115 else
10116 ast_set_callerid(chan, s1, NULL, s1);
10117 ast_copy_string(exten, s2, sizeof(exten));
10118 } else
10119 ast_copy_string(exten, s1, sizeof(exten));
10120 } else if (p->sig == SIG_FEATD)
10121 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel);
10122 }
10123 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
10124 if (exten[0] == '*') {
10125 char *stringp=NULL;
10126 ast_copy_string(exten2, exten, sizeof(exten2));
10127 /* Parse out extension and callerid */
10128 stringp=exten2 +1;
10129 s1 = strsep(&stringp, "#");
10130 s2 = strsep(&stringp, "#");
10131 if (s2) {
10132 if (!ast_strlen_zero(p->cid_num))
10133 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
10134 else
10135 if (*(s1 + 2))
10136 ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
10137 ast_copy_string(exten, s2 + 1, sizeof(exten));
10138 } else
10139 ast_copy_string(exten, s1 + 2, sizeof(exten));
10140 } else
10141 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel);
10142 }
10143 if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
10144 if (exten[0] == '*') {
10145 char *stringp=NULL;
10146 ast_copy_string(exten2, exten, sizeof(exten2));
10147 /* Parse out extension and callerid */
10148 stringp=exten2 +1;
10149 s1 = strsep(&stringp, "#");
10150 s2 = strsep(&stringp, "#");
10151 if (s2 && (*(s2 + 1) == '0')) {
10152 if (*(s2 + 2))
10153 ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
10154 }
10155 if (s1) ast_copy_string(exten, s1, sizeof(exten));
10156 else ast_copy_string(exten, "911", sizeof(exten));
10157 } else
10158 ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel);
10159 }
10160 if (p->sig == SIG_FEATB) {
10161 if (exten[0] == '*') {
10162 char *stringp=NULL;
10163 ast_copy_string(exten2, exten, sizeof(exten2));
10164 /* Parse out extension and callerid */
10165 stringp=exten2 +1;
10166 s1 = strsep(&stringp, "#");
10167 ast_copy_string(exten, exten2 + 1, sizeof(exten));
10168 } else
10169 ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel);
10170 }
10171 if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
10172 dahdi_wink(p, idx);
10173 /* some switches require a minimum guard time between
10174 the last FGD wink and something that answers
10175 immediately. This ensures it */
10176 if (ast_safe_sleep(chan, 100)) {
10177 ast_hangup(chan);
10178 goto quit;
10179 }
10180 }
10181 dahdi_ec_enable(p);
10182 if (NEED_MFDETECT(p)) {
10183 if (p->dsp) {
10184 if (!p->hardwaredtmf)
10186 else {
10187 ast_dsp_free(p->dsp);
10188 p->dsp = NULL;
10189 }
10190 }
10191 }
10192
10193 if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1,
10194 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
10195 ast_channel_exten_set(chan, exten);
10196 if (p->dsp) ast_dsp_digitreset(p->dsp);
10197 res = ast_pbx_run(chan);
10198 if (res) {
10199 ast_log(LOG_WARNING, "PBX exited non-zero\n");
10200 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
10201 }
10202 goto quit;
10203 } else {
10204 ast_verb(2, "Unknown extension '%s' in context '%s' requested\n", exten, ast_channel_context(chan));
10205 sleep(2);
10206 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_INFO);
10207 if (res < 0)
10208 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
10209 else
10210 sleep(1);
10211 res = ast_streamfile(chan, "ss-noservice", ast_channel_language(chan));
10212 if (res >= 0)
10213 ast_waitstream(chan, "");
10214 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
10215 ast_hangup(chan);
10216 goto quit;
10217 }
10218 break;
10219 case SIG_FXOLS:
10220 case SIG_FXOGS:
10221 case SIG_FXOKS:
10222 /* Read the first digit */
10223 timeout = p->firstdigit_timeout;
10224 /* If starting a threeway call, never timeout on the first digit so someone
10225 can use flash-hook as a "hold" feature */
10226 if (p->subs[SUB_THREEWAY].owner)
10227 timeout = INT_MAX;
10228 while (len < AST_MAX_EXTENSION-1) {
10229 int is_exten_parking = 0;
10230
10231 /* Read digit unless it's supposed to be immediate, in which case the
10232 only answer is 's' */
10233 if (p->immediate)
10234 res = 's';
10235 else
10236 res = ast_waitfordigit(chan, timeout);
10237 timeout = 0;
10238 if (res < 0) {
10239 ast_debug(1, "waitfordigit returned < 0...\n");
10240 res = tone_zone_play_tone(p->subs[idx].dfd, -1);
10241 ast_hangup(chan);
10242 goto quit;
10243 } else if (res) {
10244 ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
10245 exten[len++]=res;
10246 exten[len] = '\0';
10247 }
10248 if (!ast_ignore_pattern(ast_channel_context(chan), exten)) {
10249 tone_zone_play_tone(p->subs[idx].dfd, -1);
10250 } else {
10251 tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE);
10252 }
10254 is_exten_parking = ast_parking_is_exten_park(ast_channel_context(chan), exten);
10255 }
10256 if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num) && !is_exten_parking) {
10257 if (!res || !ast_matchmore_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) {
10258 if (getforward) {
10259 /* Record this as the forwarding extension */
10260 ast_copy_string(p->call_forward, exten, sizeof(p->call_forward));
10261 ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
10262 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10263 if (res)
10264 break;
10265 usleep(500000);
10266 res = tone_zone_play_tone(p->subs[idx].dfd, -1);
10267 sleep(1);
10268 memset(exten, 0, sizeof(exten));
10269 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE);
10270 len = 0;
10271 getforward = 0;
10272 } else {
10273 res = tone_zone_play_tone(p->subs[idx].dfd, -1);
10274 ast_channel_lock(chan);
10275 ast_channel_exten_set(chan, exten);
10276 if (!ast_strlen_zero(p->cid_num)) {
10277 if (!p->hidecallerid)
10278 ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
10279 else
10280 ast_set_callerid(chan, NULL, NULL, p->cid_num);
10281 }
10282 if (!ast_strlen_zero(p->cid_name)) {
10283 if (!p->hidecallerid)
10284 ast_set_callerid(chan, NULL, p->cid_name, NULL);
10285 }
10287 ast_channel_unlock(chan);
10288 dahdi_ec_enable(p);
10289 res = ast_pbx_run(chan);
10290 if (res) {
10291 ast_log(LOG_WARNING, "PBX exited non-zero\n");
10292 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
10293 }
10294 goto quit;
10295 }
10296 } else {
10297 /* It's a match, but they just typed a digit, and there is an ambiguous match,
10298 so just set the timeout to matchdigit_timeout and wait some more */
10299 timeout = p->matchdigit_timeout;
10300 }
10301 } else if (res == 0) {
10302 ast_debug(1, "not enough digits (and no ambiguous match)...\n");
10303 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
10304 dahdi_wait_event(p->subs[idx].dfd);
10305 ast_hangup(chan);
10306 goto quit;
10307 } else if (p->callwaiting && !strcmp(exten, "*70")) {
10308 ast_verb(3, "Disabling call waiting on %s\n", ast_channel_name(chan));
10309 /* Disable call waiting if enabled */
10310 p->callwaiting = 0;
10311 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10312 if (res) {
10313 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
10314 ast_channel_name(chan), strerror(errno));
10315 }
10316 len = 0;
10317 ioctl(p->subs[idx].dfd,DAHDI_CONFDIAG,&len);
10318 memset(exten, 0, sizeof(exten));
10319 timeout = p->firstdigit_timeout;
10320
10321 } else if (!strcmp(exten, pickupexten)) {
10322 /* Scan all channels and see if there are any
10323 * ringing channels that have call groups
10324 * that equal this channels pickup group
10325 */
10326 if (idx == SUB_REAL) {
10327 /* Switch us from Third call to Call Wait */
10328 if (p->subs[SUB_THREEWAY].owner) {
10329 /* If you make a threeway call and the *8# a call, it should actually
10330 look like a callwait */
10334 }
10335 dahdi_ec_enable(p);
10336 if (ast_pickup_call(chan)) {
10337 ast_debug(1, "No call pickup possible...\n");
10338 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
10339 dahdi_wait_event(p->subs[idx].dfd);
10340 }
10341 ast_hangup(chan);
10342 goto quit;
10343 } else {
10344 ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n");
10345 ast_hangup(chan);
10346 goto quit;
10347 }
10348
10349 } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
10350 ast_verb(3, "Disabling Caller*ID on %s\n", ast_channel_name(chan));
10351 /* Disable Caller*ID if enabled */
10352 p->hidecallerid = 1;
10357 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10358 if (res) {
10359 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
10360 ast_channel_name(chan), strerror(errno));
10361 }
10362 len = 0;
10363 memset(exten, 0, sizeof(exten));
10364 timeout = p->firstdigit_timeout;
10365 } else if (p->callreturn && !strcmp(exten, "*69")) {
10366 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10367 break;
10368 } else if (!strcmp(exten, "*78")) {
10369 dahdi_dnd(p, 1);
10370 /* Do not disturb */
10371 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10372 getforward = 0;
10373 memset(exten, 0, sizeof(exten));
10374 len = 0;
10375 } else if (!strcmp(exten, "*79")) {
10376 dahdi_dnd(p, 0);
10377 /* Do not disturb */
10378 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10379 getforward = 0;
10380 memset(exten, 0, sizeof(exten));
10381 len = 0;
10382 } else if (p->cancallforward && !strcmp(exten, "*72")) {
10383 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10384 getforward = 1;
10385 memset(exten, 0, sizeof(exten));
10386 len = 0;
10387 } else if (p->cancallforward && !strcmp(exten, "*73")) {
10388 ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel);
10389 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10390 memset(p->call_forward, 0, sizeof(p->call_forward));
10391 getforward = 0;
10392 memset(exten, 0, sizeof(exten));
10393 len = 0;
10394 } else if ((p->transfer || p->canpark) && is_exten_parking
10395 && p->subs[SUB_THREEWAY].owner) {
10396 struct ast_bridge_channel *bridge_channel;
10397
10398 /*
10399 * This is a three way call, the main call being a real channel,
10400 * and we're parking the first call.
10401 */
10405 if (bridge_channel) {
10406 if (!ast_parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), exten, NULL, NULL)) {
10407 /*
10408 * Swap things around between the three-way and real call so we
10409 * can hear where the channel got parked.
10410 */
10411 ast_mutex_lock(&p->lock);
10412 p->owner = p->subs[SUB_THREEWAY].owner;
10415
10416 ast_verb(3, "%s: Parked call\n", ast_channel_name(chan));
10418 ao2_ref(bridge_channel, -1);
10419 goto quit;
10420 }
10421 ao2_ref(bridge_channel, -1);
10422 }
10423 break;
10424 } else if (p->hidecallerid && !strcmp(exten, "*82")) {
10425 ast_verb(3, "Enabling Caller*ID on %s\n", ast_channel_name(chan));
10426 /* Enable Caller*ID if enabled */
10427 p->hidecallerid = 0;
10429 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10430 if (res) {
10431 ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
10432 ast_channel_name(chan), strerror(errno));
10433 }
10434 len = 0;
10435 memset(exten, 0, sizeof(exten));
10436 timeout = p->firstdigit_timeout;
10437 } else if (!strcmp(exten, "*0")) {
10438 struct ast_channel *nbridge =
10440 struct dahdi_pvt *pbridge = NULL;
10441 RAII_VAR(struct ast_channel *, bridged, nbridge ? ast_channel_bridge_peer(nbridge) : NULL, ast_channel_cleanup);
10442
10443 /* set up the private struct of the bridged one, if any */
10444 if (nbridge && bridged) {
10445 pbridge = ast_channel_tech_pvt(bridged);
10446 }
10447 if (nbridge && pbridge &&
10448 (ast_channel_tech(nbridge) == &dahdi_tech) &&
10449 (ast_channel_tech(bridged) == &dahdi_tech) &&
10450 ISTRUNK(pbridge)) {
10451 int func = DAHDI_FLASH;
10452 /* Clear out the dial buffer */
10453 p->dop.dialstr[0] = '\0';
10454 /* flash hookswitch */
10455 if ((ioctl(pbridge->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
10456 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
10457 ast_channel_name(nbridge), strerror(errno));
10458 }
10461 p->owner = p->subs[SUB_REAL].owner;
10463 ast_hangup(chan);
10464 goto quit;
10465 } else {
10466 tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
10467 dahdi_wait_event(p->subs[idx].dfd);
10468 tone_zone_play_tone(p->subs[idx].dfd, -1);
10471 p->owner = p->subs[SUB_REAL].owner;
10472 ast_hangup(chan);
10473 goto quit;
10474 }
10475 } else if (!ast_canmatch_extension(chan, ast_channel_context(chan), exten, 1,
10476 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
10477 && !canmatch_featurecode(pickupexten, exten)) {
10478 ast_debug(1, "Can't match %s from '%s' in context %s\n", exten,
10479 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<Unknown Caller>"),
10480 ast_channel_context(chan));
10481 break;
10482 }
10483 if (!timeout)
10484 timeout = p->interdigit_timeout;
10486 tone_zone_play_tone(p->subs[idx].dfd, -1);
10487 }
10488 break;
10489 case SIG_FXSLS:
10490 case SIG_FXSGS:
10491 case SIG_FXSKS:
10492 /* check for SMDI messages */
10493 if (p->use_smdi && p->smdi_iface) {
10495
10496 if (smdi_msg != NULL) {
10497 ast_channel_exten_set(chan, smdi_msg->fwd_st);
10498
10499 if (smdi_msg->type == 'B')
10500 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
10501 else if (smdi_msg->type == 'N')
10502 pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
10503
10504 ast_debug(1, "Received SMDI message on %s\n", ast_channel_name(chan));
10505 } else {
10506 ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
10507 }
10508 }
10509
10510 if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
10511 number = smdi_msg->calling_st;
10512
10513 /* If we want caller id, we're in a prering state due to a polarity reversal
10514 * and we're set to use a polarity reversal to trigger the start of caller id,
10515 * grab the caller id and wait for ringing to start... */
10516 } else if (p->use_callerid && (ast_channel_state(chan) == AST_STATE_PRERING &&
10518 /* If set to use DTMF CID signalling, listen for DTMF */
10519 if (p->cid_signalling == CID_SIG_DTMF) {
10520 int k = 0;
10521 int off_ms;
10522 struct timeval start = ast_tvnow();
10523 int ms;
10524 cs = NULL;
10525 ast_debug(1, "Receiving DTMF cid on channel %s\n", ast_channel_name(chan));
10526 dahdi_setlinear(p->subs[idx].dfd, 0);
10527 /*
10528 * We are the only party interested in the Rx stream since
10529 * we have not answered yet. We don't need or even want DTMF
10530 * emulation. The DTMF digits can come so fast that emulation
10531 * can drop some of them.
10532 */
10533 ast_channel_lock(chan);
10535 ast_channel_unlock(chan);
10536 off_ms = 4000;/* This is a typical OFF time between rings. */
10537 for (;;) {
10538 struct ast_frame *f;
10539
10540 ms = ast_remaining_ms(start, off_ms);
10541 res = ast_waitfor(chan, ms);
10542 if (res <= 0) {
10543 /*
10544 * We do not need to restore the dahdi_setlinear()
10545 * or AST_FLAG_END_DTMF_ONLY flag settings since we
10546 * are hanging up the channel.
10547 */
10548 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
10549 "Exiting simple switch\n");
10550 ast_hangup(chan);
10551 goto quit;
10552 }
10553 f = ast_read(chan);
10554 if (!f)
10555 break;
10556 if (f->frametype == AST_FRAME_DTMF) {
10557 if (k < ARRAY_LEN(dtmfbuf) - 1) {
10558 dtmfbuf[k++] = f->subclass.integer;
10559 }
10560 ast_debug(1, "CID got digit '%c'\n", f->subclass.integer);
10561 start = ast_tvnow();
10562 }
10563 ast_frfree(f);
10564 if (ast_channel_state(chan) == AST_STATE_RING ||
10566 break; /* Got ring */
10567 }
10568 ast_channel_lock(chan);
10570 ast_channel_unlock(chan);
10571 dtmfbuf[k] = '\0';
10572 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
10573 /* Got cid and ring. */
10574 ast_debug(1, "CID got string '%s'\n", dtmfbuf);
10575 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
10576 ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags);
10577 /* If first byte is NULL, we have no cid */
10578 if (!ast_strlen_zero(dtmfcid))
10579 number = dtmfcid;
10580 else
10581 number = NULL;
10582 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
10583 } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
10585 if (cs) {
10586 int off_ms;
10587 struct timeval start;
10588 int ms;
10589 samples = 0;
10590#if 1
10591 bump_gains(p);
10592#endif
10593 /* Take out of linear mode for Caller*ID processing */
10594 dahdi_setlinear(p->subs[idx].dfd, 0);
10595
10596 /* First we wait and listen for the Caller*ID */
10597 for (;;) {
10598 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10599 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
10600 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
10601 callerid_free(cs);
10602 ast_hangup(chan);
10603 goto quit;
10604 }
10605 if (i & DAHDI_IOMUX_SIGEVENT) {
10606 res = dahdi_get_event(p->subs[idx].dfd);
10607 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
10608 if (res == DAHDI_EVENT_NOALARM) {
10609 p->inalarm = 0;
10610 }
10611
10612 if (p->cid_signalling == CID_SIG_V23_JP) {
10613 if (res == DAHDI_EVENT_RINGBEGIN) {
10614 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
10615 usleep(1);
10616 }
10617 } else {
10618 res = 0;
10619 break;
10620 }
10621 } else if (i & DAHDI_IOMUX_READ) {
10622 res = read(p->subs[idx].dfd, buf, sizeof(buf));
10623 if (res < 0) {
10624 if (errno != ELAST) {
10625 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
10626 callerid_free(cs);
10627 ast_hangup(chan);
10628 goto quit;
10629 }
10630 break;
10631 }
10632 samples += res;
10633
10634 if (p->cid_signalling == CID_SIG_V23_JP) {
10635 res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
10636 } else {
10637 res = callerid_feed(cs, buf, res, AST_LAW(p));
10638 }
10639 if (res < 0) {
10640 /*
10641 * The previous diagnostic message output likely
10642 * explains why it failed.
10643 */
10645 "Failed to decode CallerID on channel '%s'\n",
10646 ast_channel_name(chan));
10647 break;
10648 } else if (res)
10649 break;
10650 else if (samples > (8000 * 10))
10651 break;
10652 }
10653 }
10654 if (res == 1) {
10655 callerid_get(cs, &name, &number, &flags);
10656 ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
10657 }
10658
10659 if (p->cid_signalling == CID_SIG_V23_JP) {
10660 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
10661 usleep(1);
10662 }
10663
10664 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
10665 start = ast_tvnow();
10666 off_ms = 4000;/* This is a typical OFF time between rings. */
10667 for (;;) {
10668 struct ast_frame *f;
10669
10670 ms = ast_remaining_ms(start, off_ms);
10671 res = ast_waitfor(chan, ms);
10672 if (res <= 0) {
10673 ast_log(LOG_WARNING, "CID timed out waiting for ring. "
10674 "Exiting simple switch\n");
10675 ast_hangup(chan);
10676 goto quit;
10677 }
10678 if (!(f = ast_read(chan))) {
10679 ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n");
10680 ast_hangup(chan);
10681 goto quit;
10682 }
10683 ast_frfree(f);
10684 if (ast_channel_state(chan) == AST_STATE_RING ||
10686 break; /* Got ring */
10687 }
10688
10689 /* We must have a ring by now, so, if configured, lets try to listen for
10690 * distinctive ringing */
10692 len = 0;
10693 distMatches = 0;
10694 /* Clear the current ring data array so we don't have old data in it. */
10695 for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++)
10696 curRingData[receivedRingT] = 0;
10697 receivedRingT = 0;
10698 counter = 0;
10699 counter1 = 0;
10700 /* Check to see if context is what it should be, if not set to be. */
10701 if (strcmp(p->context,p->defcontext) != 0) {
10702 ast_copy_string(p->context, p->defcontext, sizeof(p->context));
10704 }
10705
10706 for (;;) {
10707 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10708 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
10709 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
10710 callerid_free(cs);
10711 ast_hangup(chan);
10712 goto quit;
10713 }
10714 if (i & DAHDI_IOMUX_SIGEVENT) {
10715 res = dahdi_get_event(p->subs[idx].dfd);
10716 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
10717 if (res == DAHDI_EVENT_NOALARM) {
10718 p->inalarm = 0;
10719 }
10720 res = 0;
10721 /* Let us detect distinctive ring */
10722
10723 curRingData[receivedRingT] = p->ringt;
10724
10725 if (p->ringt < p->ringt_base/2)
10726 break;
10727 /* Increment the ringT counter so we can match it against
10728 values in chan_dahdi.conf for distinctive ring */
10729 if (++receivedRingT == ARRAY_LEN(curRingData))
10730 break;
10731 } else if (i & DAHDI_IOMUX_READ) {
10732 res = read(p->subs[idx].dfd, buf, sizeof(buf));
10733 if (res < 0) {
10734 if (errno != ELAST) {
10735 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
10736 callerid_free(cs);
10737 ast_hangup(chan);
10738 goto quit;
10739 }
10740 break;
10741 }
10742 if (p->ringt > 0) {
10743 if (!(--p->ringt)) {
10744 res = -1;
10745 break;
10746 }
10747 }
10748 }
10749 }
10750 /* this only shows up if you have n of the dring patterns filled in */
10751 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
10752 for (counter = 0; counter < 3; counter++) {
10753 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
10754 channel */
10755 distMatches = 0;
10756 for (counter1 = 0; counter1 < 3; counter1++) {
10757 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
10758 if (p->drings.ringnum[counter].ring[counter1] == -1) {
10759 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
10760 curRingData[counter1]);
10761 distMatches++;
10762 } else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
10763 curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
10764 ast_verb(3, "Ring pattern matched in range: %d to %d\n",
10765 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
10766 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
10767 distMatches++;
10768 }
10769 }
10770
10771 if (distMatches == 3) {
10772 /* The ring matches, set the context to whatever is for distinctive ring.. */
10773 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context));
10775 ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
10776 break;
10777 }
10778 }
10779 }
10780 /* Restore linear mode (if appropriate) for Caller*ID processing */
10781 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
10782#if 1
10783 restore_gains(p);
10784#endif
10785 } else
10786 ast_log(LOG_WARNING, "Unable to get caller ID space\n");
10787 } else {
10788 ast_log(LOG_WARNING, "Channel %s in prering "
10789 "state, but I have nothing to do. "
10790 "Terminating simple switch, should be "
10791 "restarted by the actual ring.\n",
10792 ast_channel_name(chan));
10793 ast_hangup(chan);
10794 goto quit;
10795 }
10796 } else if (p->use_callerid && p->cid_start == CID_START_RING) {
10797 if (p->cid_signalling == CID_SIG_DTMF) {
10798 int k = 0;
10799 int off_ms;
10800 struct timeval start;
10801 int ms;
10802 cs = NULL;
10803 dahdi_setlinear(p->subs[idx].dfd, 0);
10804 off_ms = 2000;
10805 start = ast_tvnow();
10806 for (;;) {
10807 struct ast_frame *f;
10808
10809 ms = ast_remaining_ms(start, off_ms);
10810 res = ast_waitfor(chan, ms);
10811 if (res <= 0) {
10812 ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
10813 "Exiting simple switch\n");
10814 ast_hangup(chan);
10815 goto quit;
10816 }
10817 f = ast_read(chan);
10818 if (!f) {
10819 /* Hangup received waiting for DTMFCID. Exiting simple switch. */
10820 ast_hangup(chan);
10821 goto quit;
10822 }
10823 if (f->frametype == AST_FRAME_DTMF) {
10824 dtmfbuf[k++] = f->subclass.integer;
10825 ast_debug(1, "CID got digit '%c'\n", f->subclass.integer);
10826 start = ast_tvnow();
10827 }
10828 ast_frfree(f);
10829
10830 if (p->ringt_base == p->ringt)
10831 break;
10832 }
10833 dtmfbuf[k] = '\0';
10834 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
10835 /* Got cid and ring. */
10836 callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
10837 ast_debug(1, "CID is '%s', flags %d\n",
10838 dtmfcid, flags);
10839 /* If first byte is NULL, we have no cid */
10840 if (!ast_strlen_zero(dtmfcid))
10841 number = dtmfcid;
10842 else
10843 number = NULL;
10844 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
10845 } else {
10846 /* FSK Bell202 callerID */
10848 if (cs) {
10849#if 1
10850 bump_gains(p);
10851#endif
10852 samples = 0;
10853 len = 0;
10854 distMatches = 0;
10855 /* Clear the current ring data array so we don't have old data in it. */
10856 for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++)
10857 curRingData[receivedRingT] = 0;
10858 receivedRingT = 0;
10859 counter = 0;
10860 counter1 = 0;
10861 /* Check to see if context is what it should be, if not set to be. */
10862 if (strcmp(p->context,p->defcontext) != 0) {
10863 ast_copy_string(p->context, p->defcontext, sizeof(p->context));
10865 }
10866
10867 /* Take out of linear mode for Caller*ID processing */
10868 dahdi_setlinear(p->subs[idx].dfd, 0);
10869 for (;;) {
10870 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10871 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
10872 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
10873 callerid_free(cs);
10874 ast_hangup(chan);
10875 goto quit;
10876 }
10877 if (i & DAHDI_IOMUX_SIGEVENT) {
10878 res = dahdi_get_event(p->subs[idx].dfd);
10879 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
10880 if (res == DAHDI_EVENT_NOALARM) {
10881 p->inalarm = 0;
10882 }
10883 /* If we get a PR event, they hung up while processing calerid */
10884 if ( res == DAHDI_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
10885 ast_debug(1, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
10887 callerid_free(cs);
10888 ast_hangup(chan);
10889 goto quit;
10890 }
10891 res = 0;
10892 /* Let us detect callerid when the telco uses distinctive ring */
10893
10894 curRingData[receivedRingT] = p->ringt;
10895
10896 if (p->ringt < p->ringt_base/2)
10897 break;
10898 /* Increment the ringT counter so we can match it against
10899 values in chan_dahdi.conf for distinctive ring */
10900 if (++receivedRingT == ARRAY_LEN(curRingData))
10901 break;
10902 } else if (i & DAHDI_IOMUX_READ) {
10903 res = read(p->subs[idx].dfd, buf, sizeof(buf));
10904 if (res < 0) {
10905 if (errno != ELAST) {
10906 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
10907 callerid_free(cs);
10908 ast_hangup(chan);
10909 goto quit;
10910 }
10911 break;
10912 }
10913 if (p->ringt > 0) {
10914 if (!(--p->ringt)) {
10915 res = -1;
10916 break;
10917 }
10918 }
10919 samples += res;
10920 res = callerid_feed(cs, buf, res, AST_LAW(p));
10921 if (res < 0) {
10922 /*
10923 * The previous diagnostic message output likely
10924 * explains why it failed.
10925 */
10927 "Failed to decode CallerID on channel '%s'\n",
10928 ast_channel_name(chan));
10929 break;
10930 } else if (res)
10931 break;
10932 else if (samples > (8000 * 10))
10933 break;
10934 }
10935 }
10936 if (res == 1) {
10937 callerid_get(cs, &name, &number, &flags);
10938 ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
10939 }
10940 if (distinctiveringaftercid == 1) {
10941 /* Clear the current ring data array so we don't have old data in it. */
10942 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
10943 curRingData[receivedRingT] = 0;
10944 }
10945 receivedRingT = 0;
10946 ast_verb(3, "Detecting post-CID distinctive ring\n");
10947 for (;;) {
10948 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10949 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
10950 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
10951 callerid_free(cs);
10952 ast_hangup(chan);
10953 goto quit;
10954 }
10955 if (i & DAHDI_IOMUX_SIGEVENT) {
10956 res = dahdi_get_event(p->subs[idx].dfd);
10957 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
10958 if (res == DAHDI_EVENT_NOALARM) {
10959 p->inalarm = 0;
10960 }
10961 res = 0;
10962 /* Let us detect callerid when the telco uses distinctive ring */
10963
10964 curRingData[receivedRingT] = p->ringt;
10965
10966 if (p->ringt < p->ringt_base/2)
10967 break;
10968 /* Increment the ringT counter so we can match it against
10969 values in chan_dahdi.conf for distinctive ring */
10970 if (++receivedRingT == ARRAY_LEN(curRingData))
10971 break;
10972 } else if (i & DAHDI_IOMUX_READ) {
10973 res = read(p->subs[idx].dfd, buf, sizeof(buf));
10974 if (res < 0) {
10975 if (errno != ELAST) {
10976 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
10977 callerid_free(cs);
10978 ast_hangup(chan);
10979 goto quit;
10980 }
10981 break;
10982 }
10983 if (p->ringt > 0) {
10984 if (!(--p->ringt)) {
10985 res = -1;
10986 break;
10987 }
10988 }
10989 }
10990 }
10991 }
10993 /* this only shows up if you have n of the dring patterns filled in */
10994 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
10995
10996 for (counter = 0; counter < 3; counter++) {
10997 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
10998 channel */
10999 /* this only shows up if you have n of the dring patterns filled in */
11000 ast_verb(3, "Checking %d,%d,%d\n",
11001 p->drings.ringnum[counter].ring[0],
11002 p->drings.ringnum[counter].ring[1],
11003 p->drings.ringnum[counter].ring[2]);
11004 distMatches = 0;
11005 for (counter1 = 0; counter1 < 3; counter1++) {
11006 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
11007 if (p->drings.ringnum[counter].ring[counter1] == -1) {
11008 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
11009 curRingData[counter1]);
11010 distMatches++;
11011 }
11012 else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
11013 curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
11014 ast_verb(3, "Ring pattern matched in range: %d to %d\n",
11015 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
11016 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
11017 distMatches++;
11018 }
11019 }
11020 if (distMatches == 3) {
11021 /* The ring matches, set the context to whatever is for distinctive ring.. */
11022 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context));
11024 ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
11025 break;
11026 }
11027 }
11028 }
11029 /* Restore linear mode (if appropriate) for Caller*ID processing */
11030 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
11031#if 1
11032 restore_gains(p);
11033#endif
11034 if (res < 0) {
11035 ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", ast_channel_name(chan));
11036 }
11037 } else
11038 ast_log(LOG_WARNING, "Unable to get caller ID space\n");
11039 }
11040 } else
11041 cs = NULL;
11042
11043 if (number)
11046
11047 ao2_cleanup(smdi_msg);
11048
11049 if (cs)
11050 callerid_free(cs);
11051
11052 my_handle_notify_message(chan, p, flags, -1);
11053
11054 ast_channel_lock(chan);
11056 ast_channel_rings_set(chan, 1);
11057 ast_channel_unlock(chan);
11058 p->ringt = p->ringt_base;
11059 res = ast_pbx_run(chan);
11060 if (res) {
11061 ast_hangup(chan);
11062 ast_log(LOG_WARNING, "PBX exited non-zero\n");
11063 }
11064 goto quit;
11065 default:
11066 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
11067 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
11068 if (res < 0)
11069 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
11070 }
11071 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
11072 if (res < 0)
11073 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
11074 ast_hangup(chan);
11075quit:
11080 return NULL;
11081}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define CID_SIG_V23_JP
Definition: callerid.h:63
#define CID_SIG_SMDI
Definition: callerid.h:64
int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int samples, struct ast_format *codec)
Read samples into the state machine.
Definition: callerid.c:316
void callerid_free(struct callerid_state *cid)
This function frees callerid_state cid.
Definition: callerid.c:833
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
Definition: callerid.c:1101
#define CID_SIG_DTMF
Definition: callerid.h:62
struct callerid_state * callerid_new(int cid_signalling)
Create a callerID state machine.
Definition: callerid.c:130
#define CID_SIG_V23
Definition: callerid.h:61
int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, struct ast_format *codec)
Read samples into the state machine.
Definition: callerid.c:570
void callerid_get_dtmf(char *cidstring, char *number, int *flags)
Get and parse DTMF-based callerid.
Definition: callerid.c:211
#define CID_START_RING
Definition: callerid.h:66
#define CID_START_POLARITY
Definition: callerid.h:67
void callerid_get(struct callerid_state *cid, char **number, char **name, int *flags)
Extract info out of callerID state machine. Flags are listed above.
Definition: callerid.c:205
#define CID_START_POLARITY_IN
Definition: callerid.h:68
#define CID_START_DTMF_NOALERT
Definition: callerid.h:69
static ast_mutex_t ss_thread_lock
Definition: chan_dahdi.c:763
static int restore_gains(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5169
static int unalloc_sub(struct dahdi_pvt *p, int x)
Definition: chan_dahdi.c:4464
static int dahdi_wink(struct dahdi_pvt *p, int index)
Definition: chan_dahdi.c:9796
static int dahdi_wait_event(int fd)
Avoid the silly dahdi_waitevent which ignores a bunch of events.
Definition: chan_dahdi.c:782
static int canmatch_featurecode(const char *pickupexten, const char *exten)
Definition: chan_dahdi.c:9862
static int distinctiveringaftercid
Definition: chan_dahdi.c:729
static int bump_gains(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5155
#define AST_LAW(p)
Definition: chan_dahdi.c:642
static int dahdi_setlinear(int dfd, int linear)
Definition: chan_dahdi.c:4421
static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent)
Definition: chan_dahdi.c:3568
static int alloc_sub(struct dahdi_pvt *p, int x)
Definition: chan_dahdi.c:4427
#define NEED_MFDETECT(p)
Signaling types that need to use MF detection should be placed in this macro.
Definition: chan_dahdi.c:646
static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
Definition: chan_dahdi.c:9777
#define SMDI_MD_WAIT_TIMEOUT
Definition: chan_dahdi.c:603
static void swap_subs(struct dahdi_pvt *p, int a, int b)
Definition: chan_dahdi.c:4318
#define ISTRUNK(p)
Definition: chan_dahdi.c:711
#define POLARITY_IDLE
Definition: chan_dahdi.c:913
#define POLARITY_REV
Definition: chan_dahdi.c:914
static int ss_thread_count
Definition: chan_dahdi.c:765
#define SIG_FEATB
Definition: chan_dahdi.h:781
#define SIG_FGC_CAMA
Definition: chan_dahdi.h:784
#define SIG_SFWINK
Definition: chan_dahdi.h:793
#define SIG_EMWINK
Definition: chan_dahdi.h:778
#define SIG_SF_FEATB
Definition: chan_dahdi.h:796
#define SIG_FXOGS
Definition: chan_dahdi.h:790
#define SIG_SF_FEATDMF
Definition: chan_dahdi.h:795
#define SIG_FXOKS
Definition: chan_dahdi.h:791
#define SIG_FGC_CAMAMF
Definition: chan_dahdi.h:785
#define SIG_FEATDMF
Definition: chan_dahdi.h:780
#define SIG_EM_E1
Definition: chan_dahdi.h:797
#define SIG_SF_FEATD
Definition: chan_dahdi.h:794
#define SIG_FEATD
Definition: chan_dahdi.h:779
#define SIG_FEATDMF_TA
Definition: chan_dahdi.h:783
#define SIG_FXOLS
Definition: chan_dahdi.h:789
#define SIG_E911
Definition: chan_dahdi.h:782
#define SIG_EM
Definition: chan_dahdi.h:777
#define SIG_SF
Definition: chan_dahdi.h:792
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3175
void ast_channel_rings_set(struct ast_channel *chan, int value)
void ast_party_name_init(struct ast_party_name *init)
Initialize the given name structure.
Definition: channel.c:1591
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
Definition: channel.c:1644
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
Definition: channel.c:10564
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3162
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4257
void ast_party_name_free(struct ast_party_name *doomed)
Destroy the party name contents.
Definition: channel.c:1638
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
Definition: channel.c:7334
void ast_party_number_free(struct ast_party_number *doomed)
Destroy the party number contents.
Definition: channel.c:1691
const char * ast_channel_language(const struct ast_channel *chan)
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
Definition: channel.c:10582
void ast_channel_context_set(struct ast_channel *chan, const char *value)
@ AST_FLAG_END_DTMF_ONLY
Definition: channel.h:1007
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
#define AST_MAX_EXTENSION
Definition: channel.h:134
@ AST_STATE_RING
Definition: channelstate.h:40
@ AST_STATE_PRERING
Definition: channelstate.h:45
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1783
void ast_dsp_digitreset(struct ast_dsp *dsp)
Reset DTMF detector.
Definition: dsp.c:1810
#define DSP_DIGITMODE_MF
Definition: dsp.h:32
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1857
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char * strsep(char **str, const char *delims)
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
#define ast_frfree(fr)
#define LOG_ERROR
#define LOG_NOTICE
#define ast_cond_signal(cond)
Definition: lock.h:203
int ast_parking_blind_transfer_park(struct ast_bridge_channel *parker, const char *context, const char *exten, transfer_channel_cb parked_channel_cb, struct transfer_channel_data *parked_channel_data)
Perform a blind transfer to a parking extension.
Definition: parking.c:143
int ast_parking_is_exten_park(const char *context, const char *exten)
Determine if the context/exten is a "parking" extension.
Definition: parking.c:179
int ast_parking_provider_registered(void)
Check whether a parking provider is registered.
Definition: parking.c:241
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:4755
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:4190
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition: pbx.c:6879
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch)
Definition: pbx.c:4195
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition: pickup.c:199
struct ast_smdi_md_message * ast_smdi_md_message_wait(struct ast_smdi_interface *iface, int timeout)
Get the next SMDI message from the queue.
Definition: res_smdi.c:539
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure that contains information regarding a channel in a bridge.
struct ast_channel * chan
Main Channel structure associated with a channel.
const char * data
Configuration relating to call pickup.
unsigned int flags
An SMDI message desk message.
Definition: smdi.h:65
char calling_st[SMDI_MAX_STATION_NUM_LEN+1]
Definition: smdi.h:70
char fwd_st[SMDI_MAX_STATION_NUM_LEN+1]
Definition: smdi.h:69
struct ringContextData ringContext[3]
Definition: chan_dahdi.h:71
struct distRingData ringnum[3]
Definition: chan_dahdi.h:70
unsigned int immediate
TRUE if the channel should be answered immediately without attempting to gather any digits.
Definition: chan_dahdi.h:316
struct dahdi_distRings drings
Distinctive Ring data.
Definition: chan_dahdi.h:485
unsigned int canpark
TRUE if support for call parking is enabled.
Definition: chan_dahdi.h:243
struct dahdi_dialoperation dop
DAHDI dial operation command struct for ioctl() call.
Definition: chan_dahdi.h:696
char cid_num[AST_MAX_EXTENSION]
Caller ID number from an incoming call.
Definition: chan_dahdi.h:526
int ringt
Ring timeout timer??
Definition: chan_dahdi.h:603
int interdigit_timeout
Time (ms) to detect following digits (in an analog phone)
Definition: chan_dahdi.h:685
unsigned int usedistinctiveringdetection
TRUE if distinctive rings are to be detected.
Definition: chan_dahdi.h:403
int dtmfrelax
Definition: chan_dahdi.h:720
unsigned int callwaiting
TRUE if busy extensions will hear the call-waiting tone and can use hook-flash to switch between call...
Definition: chan_dahdi.h:226
char exten[AST_MAX_EXTENSION]
Extension to use in the dialplan.
Definition: chan_dahdi.h:502
unsigned int hanguponpolarityswitch
TRUE if the call will be considered "hung up" on a polarity reversal.
Definition: chan_dahdi.h:285
char call_forward[AST_MAX_EXTENSION]
Accumulated call forwarding number.
Definition: chan_dahdi.h:704
unsigned int hidecallerid
TRUE if the outgoing caller ID is blocked/hidden.
Definition: chan_dahdi.h:302
unsigned int callreturn
TRUE if call return is enabled. (*69, if your dialplan doesn't catch this first)
Definition: chan_dahdi.h:219
unsigned int use_smdi
TRUE if SMDI (Simplified Message Desk Interface) is enabled.
Definition: chan_dahdi.h:479
int ringt_base
Ring timeout base.
Definition: chan_dahdi.h:608
int cid_start
Definition: chan_dahdi.h:589
char defcontext[AST_MAX_CONTEXT]
Default distinctive ring context.
Definition: chan_dahdi.h:500
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:694
char context[AST_MAX_CONTEXT]
The configured context for incoming calls.
Definition: chan_dahdi.h:491
unsigned int cancallforward
TRUE if support for call forwarding enabled. Dial *72 to enable call forwarding. Dial *73 to disable ...
Definition: chan_dahdi.h:238
unsigned int hardwaredtmf
TRUE if DTMF detection needs to be done by hardware.
Definition: chan_dahdi.h:295
int firstdigit_timeout
Time (ms) to detect first digit (in an analog phone)
Definition: chan_dahdi.h:680
int cid_signalling
Definition: chan_dahdi.h:588
unsigned int transfer
TRUE if call transfer is enabled.
Definition: chan_dahdi.h:382
unsigned int inalarm
TRUE if in an alarm condition.
Definition: chan_dahdi.h:324
char cid_name[AST_MAX_EXTENSION]
Caller ID name from an incoming call.
Definition: chan_dahdi.h:535
int matchdigit_timeout
Time (ms) to wait, in case of ambiguous match (in an analog phone)
Definition: chan_dahdi.h:690
unsigned int use_callerid
TRUE if caller ID is used on this channel.
Definition: chan_dahdi.h:390
int polarity
Current line interface polarity. POLARITY_IDLE, POLARITY_REV.
Definition: chan_dahdi.h:736
struct ast_smdi_interface * smdi_iface
The SMDI interface to get SMDI messages from.
Definition: chan_dahdi.h:482
unsigned int linear
Definition: chan_dahdi.h:90
int ring[3]
Definition: chan_dahdi.h:63
char contextData[AST_MAX_CONTEXT]
Definition: chan_dahdi.h:67
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: utils.c:2281
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define ast_set_flag(p, flag)
Definition: utils.h:70

References alloc_sub(), ao2_cleanup, ao2_ref, ARRAY_LEN, ast_canmatch_extension(), ast_channel_bridge_peer(), ast_channel_caller(), ast_channel_cleanup, ast_channel_context(), ast_channel_context_set(), ast_channel_exten_set(), ast_channel_flags(), ast_channel_get_bridge_channel(), ast_channel_language(), ast_channel_lock, ast_channel_name(), ast_channel_rings_set(), ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_clear_flag, ast_cond_signal, ast_copy_string(), ast_debug, ast_dsp_digitreset(), ast_dsp_free(), ast_dsp_set_digitmode(), ast_exists_extension(), AST_FLAG_END_DTMF_ONLY, AST_FRAME_DTMF, ast_frfree, ast_get_chan_features_pickup_config(), ast_hangup(), ast_ignore_pattern(), AST_LAW, ast_log, ast_matchmore_extension(), AST_MAX_EXTENSION, ast_mutex_lock, ast_mutex_unlock, ast_parking_blind_transfer_park(), ast_parking_is_exten_park(), ast_parking_provider_registered(), ast_party_name_free(), ast_party_name_init(), ast_party_number_free(), ast_party_number_init(), ast_pbx_run(), ast_pickup_call(), ast_queue_unhold(), ast_read(), ast_remaining_ms(), ast_safe_sleep(), ast_set_callerid(), ast_set_flag, ast_setstate(), ast_shrink_phone_number(), ast_smdi_md_message_wait(), AST_STATE_PRERING, AST_STATE_RING, AST_STATE_RINGING, ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_tvnow(), ast_verb, ast_waitfor(), ast_waitfordigit(), ast_waitstream(), buf, bump_gains(), dahdi_pvt::call_forward, 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, ast_bridge_channel::chan, 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, ringContextData::contextData, dahdi_dnd(), dahdi_ec_enable(), dahdi_get_event(), dahdi_get_index, dahdi_set_hook(), dahdi_setlinear(), dahdi_tech, dahdi_wait_event(), dahdi_wink(), ast_channel::data, dahdi_pvt::defcontext, dahdi_subchannel::dfd, distinctiveringaftercid, dahdi_pvt::dop, dahdi_pvt::drings, dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, dahdi_pvt::dtmfrelax, errno, event2str(), dahdi_pvt::exten, dahdi_pvt::firstdigit_timeout, ast_frame::flags, ast_frame::frametype, ast_smdi_md_message::fwd_st, dahdi_pvt::hanguponpolarityswitch, dahdi_pvt::hardwaredtmf, dahdi_pvt::hidecallerid, dahdi_pvt::immediate, dahdi_pvt::inalarm, ast_frame_subclass::integer, dahdi_pvt::interdigit_timeout, ISTRUNK, len(), dahdi_subchannel::linear, dahdi_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, dahdi_pvt::matchdigit_timeout, my_getsigstr(), my_handle_notify_message(), name, NEED_MFDETECT, NULL, dahdi_subchannel::owner, dahdi_pvt::owner, pbx_builtin_setvar_helper(), dahdi_pvt::polarity, POLARITY_IDLE, POLARITY_REV, RAII_VAR, distRingData::range, restore_gains(), distRingData::ring, dahdi_distRings::ringContext, dahdi_distRings::ringnum, dahdi_pvt::ringt, dahdi_pvt::ringt_base, S_COR, S_OR, ast_frame::samples, 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_complete, ss_thread_count, ss_thread_lock, strsep(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, dahdi_pvt::subs, swap_subs(), dahdi_pvt::transfer, ast_smdi_md_message::type, unalloc_sub(), dahdi_pvt::use_callerid, dahdi_pvt::use_smdi, and dahdi_pvt::usedistinctiveringdetection.

Referenced by dahdi_handle_event(), do_monitor(), handle_init_event(), and mwi_thread().

◆ analog_tone_to_dahditone()

static int analog_tone_to_dahditone ( enum analog_tone  tone)
static

Definition at line 1233 of file chan_dahdi.c.

1234{
1235 switch (tone) {
1237 return DAHDI_TONE_RINGTONE;
1239 return DAHDI_TONE_STUTTER;
1241 return DAHDI_TONE_CONGESTION;
1243 return DAHDI_TONE_DIALTONE;
1245 return DAHDI_TONE_DIALRECALL;
1246 case ANALOG_TONE_INFO:
1247 return DAHDI_TONE_INFO;
1248 default:
1249 return -1;
1250 }
1251}
@ ANALOG_TONE_CONGESTION
Definition: sig_analog.h:73
@ ANALOG_TONE_INFO
Definition: sig_analog.h:76
@ ANALOG_TONE_DIALTONE
Definition: sig_analog.h:74
@ ANALOG_TONE_DIALRECALL
Definition: sig_analog.h:75
@ ANALOG_TONE_STUTTER
Definition: sig_analog.h:72
@ ANALOG_TONE_RINGTONE
Definition: sig_analog.h:71

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().

◆ analogsub_to_dahdisub()

static int analogsub_to_dahdisub ( enum analog_sub  analogsub)
static

Definition at line 1253 of file chan_dahdi.c.

1254{
1255 int index;
1256
1257 switch (analogsub) {
1258 case ANALOG_SUB_REAL:
1259 index = SUB_REAL;
1260 break;
1262 index = SUB_CALLWAIT;
1263 break;
1265 index = SUB_THREEWAY;
1266 break;
1267 default:
1268 ast_log(LOG_ERROR, "Unidentified sub!\n");
1269 index = SUB_REAL;
1270 }
1271
1272 return index;
1273}
@ ANALOG_SUB_THREEWAY
Definition: sig_analog.h:111
@ ANALOG_SUB_REAL
Definition: sig_analog.h:109
@ ANALOG_SUB_CALLWAIT
Definition: sig_analog.h:110

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_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().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 20533 of file chan_dahdi.c.

◆ attempt_transfer()

static int attempt_transfer ( struct dahdi_pvt p)
static

Definition at line 7508 of file chan_dahdi.c.

7509{
7510 struct ast_channel *owner_real;
7511 struct ast_channel *owner_3way;
7512 enum ast_transfer_result xfer_res;
7513 int res = 0;
7514
7515 owner_real = ast_channel_ref(p->subs[SUB_REAL].owner);
7516 owner_3way = ast_channel_ref(p->subs[SUB_THREEWAY].owner);
7517
7518 ast_verb(3, "TRANSFERRING %s to %s\n",
7519 ast_channel_name(owner_3way), ast_channel_name(owner_real));
7520
7521 ast_channel_unlock(owner_real);
7522 ast_channel_unlock(owner_3way);
7524
7525 xfer_res = ast_bridge_transfer_attended(owner_3way, owner_real);
7526 if (xfer_res != AST_BRIDGE_TRANSFER_SUCCESS) {
7528 res = -1;
7529 }
7530
7531 /* Must leave with these locked. */
7532 ast_channel_lock(owner_real);
7533 ast_mutex_lock(&p->lock);
7534
7535 ast_channel_unref(owner_real);
7536 ast_channel_unref(owner_3way);
7537
7538 return res;
7539}
ast_transfer_result
Definition: bridge.h:1098
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1100
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
Definition: bridge.c:4677
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
@ AST_SOFTHANGUP_DEV
Definition: channel.h:1121

References ast_bridge_transfer_attended(), AST_BRIDGE_TRANSFER_SUCCESS, ast_channel_lock, ast_channel_name(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_mutex_lock, ast_mutex_unlock, ast_softhangup(), AST_SOFTHANGUP_DEV, ast_verb, dahdi_pvt::lock, dahdi_subchannel::owner, SUB_REAL, SUB_THREEWAY, and dahdi_pvt::subs.

Referenced by dahdi_handle_event().

◆ available()

static int available ( struct dahdi_pvt **  pvt,
int  is_specific_channel 
)
static

Definition at line 13472 of file chan_dahdi.c.

13473{
13474 struct dahdi_pvt *p = *pvt;
13475
13476 if (p->inalarm)
13477 return 0;
13478
13479 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode))
13480 return analog_available(p->sig_pvt);
13481
13482 switch (p->sig) {
13483#if defined(HAVE_PRI)
13485 {
13486 struct sig_pri_chan *pvt_chan;
13487 int res;
13488
13489 pvt_chan = p->sig_pvt;
13490 res = sig_pri_available(&pvt_chan, is_specific_channel);
13491 *pvt = pvt_chan->chan_pvt;
13492 return res;
13493 }
13494#endif /* defined(HAVE_PRI) */
13495#if defined(HAVE_SS7)
13496 case SIG_SS7:
13497 return sig_ss7_available(p->sig_pvt);
13498#endif /* defined(HAVE_SS7) */
13499 default:
13500 break;
13501 }
13502
13503 if (p->locallyblocked || p->remotelyblocked) {
13504 return 0;
13505 }
13506
13507 /* If no owner definitely available */
13508 if (!p->owner) {
13509#ifdef HAVE_OPENR2
13510 /* Trust MFC/R2 */
13511 if (p->mfcr2) {
13512 if (p->mfcr2call) {
13513 return 0;
13514 } else {
13515 return 1;
13516 }
13517 }
13518#endif
13519 return 1;
13520 }
13521
13522 return 0;
13523}
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:811
#define SIG_SS7
Definition: chan_dahdi.h:805
int analog_available(struct analog_pvt *p)
Definition: sig_analog.c:793
int sig_pri_available(struct sig_pri_chan **pvt, int is_specific_channel)
int sig_ss7_available(struct sig_ss7_chan *p)
unsigned int locallyblocked
Bitmask for the channel being locally blocked.
Definition: chan_dahdi.h:451
unsigned int remotelyblocked
Bitmask for the channel being remotely blocked. 1 maintenance, 2 blocked in hardware.
Definition: chan_dahdi.h:460
void * sig_pvt
Definition: chan_dahdi.h:764
void * chan_pvt
Definition: sig_pri.h:374

References analog_available(), sig_pri_chan::chan_pvt, dahdi_analog_lib_handles(), 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(), dahdi_request(), is_member_available(), logger_register_level(), sip_options_contact_status_available_count(), and sip_options_update_aor_task().

◆ build_alarm_info()

static void build_alarm_info ( char *restrict  alarmstr,
struct dahdi_spaninfo *  spaninfo 
)
static

Definition at line 16309 of file chan_dahdi.c.

16310{
16311 alarmstr[0] = '\0';
16312 if (spaninfo->alarms > 0) {
16313 if (spaninfo->alarms & DAHDI_ALARM_BLUE) {
16314 strcat(alarmstr, "BLU/");
16315 }
16316 if (spaninfo->alarms & DAHDI_ALARM_YELLOW) {
16317 strcat(alarmstr, "YEL/");
16318 }
16319 if (spaninfo->alarms & DAHDI_ALARM_RED) {
16320 strcat(alarmstr, "RED/");
16321 }
16322 if (spaninfo->alarms & DAHDI_ALARM_LOOPBACK) {
16323 strcat(alarmstr, "LB/");
16324 }
16325 if (spaninfo->alarms & DAHDI_ALARM_RECOVER) {
16326 strcat(alarmstr, "REC/");
16327 }
16328 if (spaninfo->alarms & DAHDI_ALARM_NOTOPEN) {
16329 strcat(alarmstr, "NOP/");
16330 }
16331 if (!strlen(alarmstr)) {
16332 strcat(alarmstr, "UUU/");
16333 }
16334 if (strlen(alarmstr)) {
16335 /* Strip trailing / */
16336 alarmstr[strlen(alarmstr) - 1] = '\0';
16337 }
16338 } else {
16339 if (spaninfo->numchans) {
16340 strcpy(alarmstr, "OK");
16341 } else {
16342 strcpy(alarmstr, "UNCONFIGURED");
16343 }
16344 }
16345}

Referenced by action_dahdishowstatus(), and dahdi_show_status().

◆ build_channels()

static int build_channels ( struct dahdi_chan_conf conf,
const char *  value,
int  reload,
int  lineno 
)
static

Definition at line 18238 of file chan_dahdi.c.

18239{
18240 char *c, *chan;
18241 int x, start, finish;
18242 struct dahdi_pvt *tmp;
18243
18244 if ((reload == 0) && (conf->chan.sig < 0) && !conf->is_sig_auto) {
18245 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
18246 return -1;
18247 }
18248
18249 c = ast_strdupa(value);
18250
18251 while ((chan = strsep(&c, ","))) {
18252 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
18253 /* Range */
18254 } else if (sscanf(chan, "%30d", &start)) {
18255 /* Just one */
18256 finish = start;
18257 } else if (!strcasecmp(chan, "pseudo")) {
18258 finish = start = CHAN_PSEUDO;
18259 } else {
18260 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
18261 return -1;
18262 }
18263 if (finish < start) {
18264 ast_log(LOG_WARNING, "Silliness: %d < %d\n", start, finish);
18265 x = finish;
18266 finish = start;
18267 start = x;
18268 }
18269
18270 for (x = start; x <= finish; x++) {
18271 if (conf->wanted_channels_start &&
18272 (x < conf->wanted_channels_start ||
18273 x > conf->wanted_channels_end)
18274 ) {
18275 continue;
18276 }
18277 tmp = mkintf(x, conf, reload);
18278
18279 if (tmp) {
18280 ast_verb(3, "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
18281 } else {
18282 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
18283 (reload == 1) ? "reconfigure" : "register", value);
18284 return -1;
18285 }
18286 if (x == CHAN_PSEUDO) {
18287 has_pseudo = 1;
18288 }
18289 }
18290 }
18291
18292 return 0;
18293}
static struct dahdi_pvt * mkintf(int channel, const struct dahdi_chan_conf *conf, int reloading)
Definition: chan_dahdi.c:12493
static int has_pseudo
Definition: chan_dahdi.c:688
static int reload(void)
Definition: chan_dahdi.c:20509
#define CHAN_PSEUDO
Definition: chan_dahdi.c:677
All configuration options for http media cache.
int value
Definition: syslog.c:37
static struct test_val c

References ast_log, ast_strdupa, ast_verb, c, CHAN_PSEUDO, has_pseudo, LOG_ERROR, LOG_WARNING, mkintf(), reload(), sig2str, strsep(), tmp(), and value.

Referenced by process_dahdi().

◆ bump_gains()

static int bump_gains ( struct dahdi_pvt p)
static

Definition at line 5155 of file chan_dahdi.c.

5156{
5157 int res;
5158
5159 /* Bump receive gain by value stored in cid_rxgain */
5160 res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain + p->cid_rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
5161 if (res) {
5162 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
5163 return -1;
5164 }
5165
5166 return 0;
5167}
static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law)
Definition: chan_dahdi.c:5150
float cid_rxgain
Amount of gain to increase during caller id.
Definition: chan_dahdi.h:158
float txdrc
Definition: chan_dahdi.h:164
int law
Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:556
float rxdrc
Definition: chan_dahdi.h:165
float txgain
Software Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:162
float rxgain
Software Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:160

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().

◆ calc_energy()

static int calc_energy ( const unsigned char *  buf,
int  len,
struct ast_format law 
)
static

Definition at line 11089 of file chan_dahdi.c.

11090{
11091 int x;
11092 int sum = 0;
11093
11094 if (!len)
11095 return 0;
11096
11097 for (x = 0; x < len; x++)
11098 sum += abs(law == ast_format_ulaw ? AST_MULAW(buf[x]) : AST_ALAW(buf[x]));
11099
11100 return sum / len;
11101}
#define AST_ALAW(a)
Definition: alaw.h:84
#define abs(x)
Definition: f2c.h:195
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
#define AST_MULAW(a)
Definition: ulaw.h:85

References abs, AST_ALAW, ast_format_ulaw, AST_MULAW, buf, dahdi_pvt::law, and len().

Referenced by do_monitor(), and mwi_thread().

◆ canmatch_featurecode()

static int canmatch_featurecode ( const char *  pickupexten,
const char *  exten 
)
static

Definition at line 9862 of file chan_dahdi.c.

9863{
9864 int extlen = strlen(exten);
9865
9866 if (!extlen) {
9867 return 1;
9868 }
9869
9870 if (extlen < strlen(pickupexten) && !strncmp(pickupexten, exten, extlen)) {
9871 return 1;
9872 }
9873 /* hardcoded features are *60, *67, *69, *70, *72, *73, *78, *79, *82, *0 */
9874 if (exten[0] == '*' && extlen < 3) {
9875 if (extlen == 1) {
9876 return 1;
9877 }
9878 /* "*0" should be processed before it gets here */
9879 switch (exten[1]) {
9880 case '6':
9881 case '7':
9882 case '8':
9883 return 1;
9884 }
9885 }
9886 return 0;
9887}

Referenced by analog_ss_thread().

◆ check_for_conference()

static int check_for_conference ( struct dahdi_pvt p)
static

Definition at line 7541 of file chan_dahdi.c.

7542{
7543 struct dahdi_confinfo ci;
7544 /* Fine if we already have a master, etc */
7545 if (p->master || (p->confno > -1))
7546 return 0;
7547 memset(&ci, 0, sizeof(ci));
7548 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
7549 ast_log(LOG_WARNING, "Failed to get conference info on channel %d: %s\n", p->channel, strerror(errno));
7550 return 0;
7551 }
7552 /* If we have no master and don't have a confno, then
7553 if we're in a conference, it's probably a MeetMe room or
7554 some such, so don't let us 3-way out! */
7555 if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
7556 ast_verb(3, "Avoiding 3-way call when in an external conference\n");
7557 return 1;
7558 }
7559 return 0;
7560}
struct dahdi_pvt * master
Definition: chan_dahdi.h:135
int confno
Definition: chan_dahdi.h:557
struct dahdi_confinfo curconf
Definition: chan_dahdi.h:92

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().

◆ conf_add()

static int conf_add ( struct dahdi_pvt p,
struct dahdi_subchannel c,
int  index,
int  slavechannel 
)
static

Definition at line 4717 of file chan_dahdi.c.

4718{
4719 /* If the conference already exists, and we're already in it
4720 don't bother doing anything */
4721 struct dahdi_confinfo zi;
4722
4723 memset(&zi, 0, sizeof(zi));
4724 zi.chan = 0;
4725
4726 if (slavechannel > 0) {
4727 /* If we have only one slave, do a digital mon */
4728 zi.confmode = DAHDI_CONF_DIGITALMON;
4729 zi.confno = slavechannel;
4730 } else {
4731 if (!idx) {
4732 /* Real-side and pseudo-side both participate in conference */
4733 zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |
4734 DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;
4735 } else
4736 zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
4737 zi.confno = p->confno;
4738 }
4739 if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
4740 return 0;
4741 if (c->dfd < 0)
4742 return 0;
4743 if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
4744 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno));
4745 return -1;
4746 }
4747 if (slavechannel < 1) {
4748 p->confno = zi.confno;
4749 }
4750 c->curconf = zi;
4751 ast_debug(1, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
4752 return 0;
4753}

References ast_debug, ast_log, c, dahdi_pvt::confno, errno, and LOG_WARNING.

Referenced by dahdi_conf_update(), my_complete_conference_update(), and my_conf_add().

◆ conf_del()

static int conf_del ( struct dahdi_pvt p,
struct dahdi_subchannel c,
int  index 
)
static

Definition at line 4766 of file chan_dahdi.c.

4767{
4768 struct dahdi_confinfo zi;
4769 if (/* Can't delete if there's no dfd */
4770 (c->dfd < 0) ||
4771 /* Don't delete from the conference if it's not our conference */
4772 !isourconf(p, c)
4773 /* Don't delete if we don't think it's conferenced at all (implied) */
4774 ) return 0;
4775 memset(&zi, 0, sizeof(zi));
4776 if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
4777 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno));
4778 return -1;
4779 }
4780 ast_debug(1, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
4781 memcpy(&c->curconf, &zi, sizeof(c->curconf));
4782 return 0;
4783}
static int isourconf(struct dahdi_pvt *p, struct dahdi_subchannel *c)
Definition: chan_dahdi.c:4755

References ast_debug, ast_log, c, errno, isourconf(), and LOG_WARNING.

Referenced by dahdi_conf_update(), dahdi_master_slave_unlink(), and my_conf_del().

◆ create_channel_name()

static struct ast_str * create_channel_name ( struct dahdi_pvt i)
static

Definition at line 9476 of file chan_dahdi.c.

9478{
9479 struct ast_str *chan_name;
9480 int x, y;
9481
9482 /* Create the new channel name tail. */
9483 if (!(chan_name = ast_str_create(32))) {
9484 return NULL;
9485 }
9486 if (i->channel == CHAN_PSEUDO) {
9487 ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random());
9488#if defined(HAVE_PRI)
9489 } else if (i->pri) {
9490 ast_mutex_lock(&i->pri->lock);
9491 y = ++i->pri->new_chan_seq;
9492 if (is_outgoing) {
9493 ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, address, (unsigned)y);
9494 address[0] = '\0';
9495 } else if (ast_strlen_zero(i->cid_subaddr)) {
9496 /* Put in caller-id number only since there is no subaddress. */
9497 ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, i->cid_num, (unsigned)y);
9498 } else {
9499 /* Put in caller-id number and subaddress. */
9500 ast_str_set(&chan_name, 0, "i%d/%s:%s-%x", i->pri->span, i->cid_num,
9501 i->cid_subaddr, (unsigned)y);
9502 }
9503 ast_mutex_unlock(&i->pri->lock);
9504#endif /* defined(HAVE_PRI) */
9505 } else {
9506 y = 1;
9507 do {
9508 ast_str_set(&chan_name, 0, "%d-%d", i->channel, y);
9509 for (x = 0; x < 3; ++x) {
9510 if (i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name),
9511 ast_channel_name(i->subs[x].owner) + 6)) {
9512 break;
9513 }
9514 }
9515 ++y;
9516 } while (x < 3);
9517 }
9518 return chan_name;
9519}
char * address
Definition: f2c.h:59
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
Support for dynamic strings.
Definition: strings.h:623
char cid_subaddr[AST_MAX_EXTENSION]
Caller ID subaddress from an incoming call.
Definition: chan_dahdi.h:537
long int ast_random(void)
Definition: utils.c:2312

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, NULL, dahdi_subchannel::owner, dahdi_pvt::span, and dahdi_pvt::subs.

Referenced by dahdi_cc_callback(), and dahdi_new().

◆ dahdi_ami_channel_event()

static void dahdi_ami_channel_event ( struct dahdi_pvt p,
struct ast_channel chan 
)
static

Definition at line 1968 of file chan_dahdi.c.

1969{
1970 char ch_name[23];
1971
1972 if (p->channel < CHAN_PSEUDO) {
1973 /* No B channel */
1974 snprintf(ch_name, sizeof(ch_name), "no-media (%d)", p->channel);
1975 } else if (p->channel == CHAN_PSEUDO) {
1976 /* Pseudo channel */
1977 strcpy(ch_name, "pseudo");
1978 } else {
1979 /* Real channel */
1980 snprintf(ch_name, sizeof(ch_name), "%d", p->channel);
1981 }
1982 publish_dahdichannel(chan, p->group, p->span, ch_name);
1983}
static void publish_dahdichannel(struct ast_channel *chan, ast_group_t group, int span, const char *dahdi_channel)
Sends a DAHDIChannel channel blob used to produce DAHDIChannel AMI messages.
Definition: chan_dahdi.c:1941
ast_group_t group
Bitmapped groups this belongs to.
Definition: chan_dahdi.h:552

References CHAN_PSEUDO, dahdi_pvt::channel, dahdi_pvt::group, publish_dahdichannel(), and dahdi_pvt::span.

Referenced by dahdi_new().

◆ dahdi_answer()

static int dahdi_answer ( struct ast_channel ast)
static
Todo:
XXX this is redundantly set by the analog and PRI submodules!

Definition at line 6699 of file chan_dahdi.c.

6700{
6701 struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
6702 int res = 0;
6703 int idx;
6704 ast_setstate(ast, AST_STATE_UP);/*! \todo XXX this is redundantly set by the analog and PRI submodules! */
6705 ast_mutex_lock(&p->lock);
6706 idx = dahdi_get_index(ast, p, 0);
6707 if (idx < 0)
6708 idx = SUB_REAL;
6709 /* nothing to do if a radio channel */
6710 if ((p->radio || (p->oprmode < 0))) {
6712 return 0;
6713 }
6714
6715 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
6716 res = analog_answer(p->sig_pvt, ast);
6718 return res;
6719 }
6720
6721 switch (p->sig) {
6722#if defined(HAVE_PRI)
6724 res = sig_pri_answer(p->sig_pvt, ast);
6725 break;
6726#endif /* defined(HAVE_PRI) */
6727#if defined(HAVE_SS7)
6728 case SIG_SS7:
6729 res = sig_ss7_answer(p->sig_pvt, ast);
6730 break;
6731#endif /* defined(HAVE_SS7) */
6732#ifdef HAVE_OPENR2
6733 case SIG_MFCR2:
6734 if (!p->mfcr2_call_accepted) {
6735 /* The call was not accepted on offer nor the user, so it must be accepted now before answering,
6736 openr2_chan_answer_call will be called when the callback on_call_accepted is executed */
6737 p->mfcr2_answer_pending = 1;
6738 if (p->mfcr2_charge_calls) {
6739 ast_debug(1, "Accepting MFC/R2 call with charge before answering on chan %d\n", p->channel);
6740 openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE);
6741 } else {
6742 ast_debug(1, "Accepting MFC/R2 call with no charge before answering on chan %d\n", p->channel);
6743 openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE);
6744 }
6745 } else {
6746 ast_debug(1, "Answering MFC/R2 call on chan %d\n", p->channel);
6747 dahdi_r2_answer(p);
6748 }
6749 break;
6750#endif
6751 case 0:
6753 return 0;
6754 default:
6755 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
6756 res = -1;
6757 break;
6758 }
6760 return res;
6761}
#define SIG_MFCR2
Definition: chan_dahdi.h:808
int analog_answer(struct analog_pvt *p, struct ast_channel *ast)
Definition: sig_analog.c:1490
int sig_pri_answer(struct sig_pri_chan *p, struct ast_channel *ast)
int sig_ss7_answer(struct sig_ss7_chan *p, struct ast_channel *ast)

References analog_answer(), ast_channel_tech_pvt(), ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_UP, dahdi_pvt::channel, dahdi_analog_lib_handles(), 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(), and SUB_REAL.

◆ dahdi_call()

static int dahdi_call ( struct ast_channel ast,
const char *  rdest,
int  timeout 
)
static

Definition at line 5393 of file chan_dahdi.c.

5394{
5395 struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
5396 int x, res, mysig;
5397 char *dest;
5399 AST_APP_ARG(group); /* channel/group token */
5400 AST_APP_ARG(ext); /* extension token */
5401 //AST_APP_ARG(opts); /* options token */
5402 AST_APP_ARG(other); /* Any remining unused arguments */
5403 );
5404
5405 ast_mutex_lock(&p->lock);
5406 ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
5407
5408 /* Split the dialstring */
5409 dest = ast_strdupa(rdest);
5410 AST_NONSTANDARD_APP_ARGS(args, dest, '/');
5411 if (!args.ext) {
5412 args.ext = "";
5413 }
5414
5415#if defined(HAVE_PRI)
5417 char *subaddr;
5418
5419 sig_pri_extract_called_num_subaddr(p->sig_pvt, rdest, p->exten, sizeof(p->exten));
5420
5421 /* Remove any subaddress for uniformity with incoming calls. */
5422 subaddr = strchr(p->exten, ':');
5423 if (subaddr) {
5424 *subaddr = '\0';
5425 }
5426 } else
5427#endif /* defined(HAVE_PRI) */
5428 {
5429 ast_copy_string(p->exten, args.ext, sizeof(p->exten));
5430 }
5431
5432 if ((ast_channel_state(ast) == AST_STATE_BUSY)) {
5433 p->subs[SUB_REAL].needbusy = 1;
5435 return 0;
5436 }
5438 ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
5440 return -1;
5441 }
5442 p->waitingfordt.tv_sec = 0;
5443 p->dialednone = 0;
5444 if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */
5445 {
5446 /* Special pseudo -- automatically up */
5449 return 0;
5450 }
5451 x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;
5452 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
5453 if (res)
5454 ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno));
5455 p->outgoing = 1;
5456
5458 set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, p->rxdrc, p->txdrc, p->law);
5459 } else {
5460 set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
5461 }
5462
5463#ifdef HAVE_PRI
5465 res = sig_pri_call(p->sig_pvt, ast, rdest, timeout,
5466 (p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW);
5468 return res;
5469 }
5470#endif
5471
5472#if defined(HAVE_SS7)
5473 if (p->sig == SIG_SS7) {
5474 res = sig_ss7_call(p->sig_pvt, ast, rdest);
5476 return res;
5477 }
5478#endif /* defined(HAVE_SS7) */
5479
5480 /* If this is analog signalling we can exit here */
5481 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
5482 p->callwaitrings = 0;
5483 res = analog_call(p->sig_pvt, ast, rdest, timeout);
5485 return res;
5486 }
5487
5488 mysig = p->outsigmod > -1 ? p->outsigmod : p->sig;
5489 switch (mysig) {
5490 case 0:
5491 /* Special pseudo -- automatically up*/
5493 break;
5494 case SIG_MFCR2:
5495 break;
5496 default:
5497 ast_debug(1, "not yet implemented\n");
5499 return -1;
5500 }
5501
5502#ifdef HAVE_OPENR2
5503 if (p->mfcr2) {
5504 openr2_calling_party_category_t chancat;
5505 int callres = 0;
5506 char *c, *l;
5507
5508 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
5509 p->dialdest[0] = '\0';
5510
5511 c = args.ext;
5512 if (!p->hidecallerid) {
5514 } else {
5515 l = NULL;
5516 }
5517 if (strlen(c) < p->stripmsd) {
5518 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
5520 return -1;
5521 }
5522 p->dialing = 1;
5523 chancat = dahdi_r2_get_channel_category(ast);
5524 callres = openr2_chan_make_call(p->r2chan, l, (c + p->stripmsd), chancat);
5525 if (-1 == callres) {
5527 ast_log(LOG_ERROR, "unable to make new MFC/R2 call!\n");
5528 return -1;
5529 }
5530 p->mfcr2_call_accepted = 0;
5531 p->mfcr2_progress_sent = 0;
5533 }
5534#endif /* HAVE_OPENR2 */
5536 return 0;
5537}
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:825
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
@ AST_STATE_DOWN
Definition: channelstate.h:36
@ AST_STATE_BUSY
Definition: channelstate.h:43
@ AST_STATE_DIALING
Definition: channelstate.h:39
@ AST_STATE_RESERVED
Definition: channelstate.h:37
const char * ext
Definition: http.c:150
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
int analog_call(struct analog_pvt *p, struct ast_channel *ast, const char *rdest, int timeout)
Definition: sig_analog.c:990
void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size)
int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, const char *rdest, int timeout, int layer1)
int sig_ss7_call(struct sig_ss7_chan *p, struct ast_channel *ast, const char *rdest)
struct ast_party_id id
Connected party ID.
Definition: channel.h:458
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:342
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:297
char * str
Subscriber phone number (Malloced)
Definition: channel.h:291
char dialdest[256]
Delayed dialing for E911. Overlap digits for ISDN.
Definition: chan_dahdi.h:713
unsigned int outgoing
TRUE if we originated the call leg.
Definition: chan_dahdi.h:328
int outsigmod
Definition: chan_dahdi.h:150
int callwaitrings
Number of call waiting rings.
Definition: chan_dahdi.h:624
unsigned int dialednone
TRUE if analog type line dialed no digits in Dial()
Definition: chan_dahdi.h:253
struct timeval waitingfordt
Definition: chan_dahdi.h:691
int stripmsd
Number of most significant digits/characters to strip from the dialed number.
Definition: chan_dahdi.h:615
unsigned int needbusy
Definition: chan_dahdi.h:84
const char * args
#define IS_DIGITAL(cap)
Definition: transcap.h:45

References analog_call(), args, AST_APP_ARG, ast_channel_connected(), ast_channel_name(), ast_channel_tech_pvt(), ast_channel_transfercapability(), 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, c, dahdi_pvt::callwaitrings, dahdi_pvt::channel, dahdi_analog_lib_handles(), 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, NULL, 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, dahdi_pvt::txdrc, dahdi_pvt::txgain, ast_party_number::valid, and dahdi_pvt::waitingfordt.

◆ dahdi_callwait()

static int dahdi_callwait ( struct ast_channel ast)
static

Definition at line 5359 of file chan_dahdi.c.

5360{
5361 struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
5362
5364 if (p->cidspill) {
5365 ast_log(LOG_WARNING, "Spill already exists?!?\n");
5366 ast_free(p->cidspill);
5367 }
5368
5369 /*
5370 * SAS: Subscriber Alert Signal, 440Hz for 300ms
5371 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
5372 */
5373 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
5374 return -1;
5375 save_conference(p);
5376 /* Silence */
5377 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
5378 if (!p->callwaitrings && p->callwaitingcallerid) {
5379 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
5380 p->callwaitcas = 1;
5381 p->cidlen = 2400 + 680 + READ_SIZE * 4;
5382 } else {
5383 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
5384 p->callwaitcas = 0;
5385 p->cidlen = 2400 + READ_SIZE * 4;
5386 }
5387 p->cidpos = 0;
5388 send_callerid(p);
5389
5390 return 0;
5391}
#define ast_free(a)
Definition: astmm.h:180
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
int ast_gen_cas(unsigned char *outbuf, int sas, int len, struct ast_format *codec)
Generate a CAS (CPE Alert Signal) tone for 'n' samples.
Definition: callerid.c:271
#define CALLWAITING_REPEAT_SAMPLES
Definition: chan_dahdi.c:800
static int save_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5236
#define READ_SIZE
Definition: chan_dahdi.c:794
static int send_callerid(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5323
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:597
int cidlen
Length of the cidspill buffer containing samples.
Definition: chan_dahdi.h:601
unsigned int callwaitingcallerid
TRUE if send caller ID for Call Waiting.
Definition: chan_dahdi.h:231
int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: chan_dahdi.h:622
int cidpos
Position in the cidspill buffer to send out next.
Definition: chan_dahdi.h:599

References ast_channel_tech_pvt(), 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().

Referenced by dahdi_read().

◆ dahdi_cc_callback()

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().

Since
1.8
Parameters
inboundIncoming asterisk channel.
destSame dial string passed to dahdi_request().
callbackCallback into CC core to announce a busy channel available for CC.

This callback acts like a forked dial with all prongs of the fork busy. Essentially, for each channel that could have taken the call, indicate that it is busy.

Return values
0on success.
-1on error.

Definition at line 14146 of file chan_dahdi.c.

14147{
14148 struct dahdi_pvt *p;
14149 struct dahdi_pvt *exitpvt;
14150 struct dahdi_starting_point start;
14151 int groupmatched = 0;
14152 int channelmatched = 0;
14153
14155 p = determine_starting_point(dest, &start);
14156 if (!p) {
14158 return -1;
14159 }
14160 exitpvt = p;
14161 for (;;) {
14162 if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)) {
14163 /* We found a potential match. call the callback */
14164 struct ast_str *device_name;
14165 char *dash;
14166 const char *monitor_type;
14167 char dialstring[AST_CHANNEL_NAME];
14168 char full_device_name[AST_CHANNEL_NAME];
14169
14172 break;
14176#if defined(HAVE_PRI)
14178 /*
14179 * ISDN is in a trunk busy condition so we need to monitor
14180 * the span congestion device state.
14181 */
14182 snprintf(full_device_name, sizeof(full_device_name),
14183 "DAHDI/I%d/congestion", p->pri->span);
14184 } else
14185#endif /* defined(HAVE_PRI) */
14186 {
14187#if defined(HAVE_PRI)
14188 device_name = create_channel_name(p, 1, "");
14189#else
14190 device_name = create_channel_name(p);
14191#endif /* defined(HAVE_PRI) */
14192 snprintf(full_device_name, sizeof(full_device_name), "DAHDI/%s",
14193 device_name ? ast_str_buffer(device_name) : "");
14194 ast_free(device_name);
14195 /*
14196 * The portion after the '-' in the channel name is either a random
14197 * number, a sequence number, or a subchannel number. None are
14198 * necessary so strip them off.
14199 */
14200 dash = strrchr(full_device_name, '-');
14201 if (dash) {
14202 *dash = '\0';
14203 }
14204 }
14205 snprintf(dialstring, sizeof(dialstring), "DAHDI/%s", dest);
14206
14207 /*
14208 * Analog can only do generic monitoring.
14209 * ISDN is in a trunk busy condition and any "device" is going
14210 * to be busy until a B channel becomes available. The generic
14211 * monitor can do this task.
14212 */
14213 monitor_type = AST_CC_GENERIC_MONITOR_TYPE;
14214 callback(inbound,
14215#if defined(HAVE_PRI)
14216 p->pri ? p->pri->cc_params : p->cc_params,
14217#else
14218 p->cc_params,
14219#endif /* defined(HAVE_PRI) */
14220 monitor_type, full_device_name, dialstring, NULL);
14221 break;
14222 }
14223 }
14224 p = start.backwards ? p->prev : p->next;
14225 if (!p) {
14226 p = start.backwards ? ifend : iflist;
14227 }
14228 if (p == exitpvt) {
14229 break;
14230 }
14231 }
14233 return 0;
14234}
#define AST_CC_GENERIC_MONITOR_TYPE
Definition: ccss.h:455
@ AST_CC_MONITOR_NEVER
Definition: ccss.h:76
@ AST_CC_MONITOR_ALWAYS
Definition: ccss.h:87
@ AST_CC_MONITOR_NATIVE
Definition: ccss.h:78
@ AST_CC_MONITOR_GENERIC
Definition: ccss.h:83
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
Definition: ccss.c:876
static int is_group_or_channel_match(struct dahdi_pvt *p, int span, ast_group_t groupmatch, int *groupmatched, int channelmatch, int *channelmatched)
Definition: chan_dahdi.c:13439
static struct ast_str * create_channel_name(struct dahdi_pvt *i)
Definition: chan_dahdi.c:9476
static struct dahdi_pvt * ifend
Definition: chan_dahdi.c:923
static struct dahdi_pvt * determine_starting_point(const char *data, struct dahdi_starting_point *param)
Definition: chan_dahdi.c:13742
#define AST_CHANNEL_NAME
Definition: channel.h:171
struct dahdi_pvt * prev
Definition: chan_dahdi.h:170
struct ast_cc_config_params * cc_params
Definition: chan_dahdi.h:765

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, ifend, iflist, iflock, is_group_or_channel_match(), dahdi_pvt::next, NULL, dahdi_pvt::prev, dahdi_pvt::sig, dahdi_starting_point::span, and dahdi_pvt::span.

◆ dahdi_chan_conf_default()

static struct dahdi_chan_conf dahdi_chan_conf_default ( void  )
static

returns a new dahdi_chan_conf with default values (by-value)

Definition at line 990 of file chan_dahdi.c.

991{
992 /* recall that if a field is not included here it is initialized
993 * to 0 or equivalent
994 */
995 struct dahdi_chan_conf conf = {
996#ifdef HAVE_PRI
997 .pri.pri = {
998 .nsf = PRI_NSF_NONE,
999 .switchtype = PRI_SWITCH_NI2,
1000 .dialplan = PRI_UNKNOWN + 1,
1001 .localdialplan = PRI_NATIONAL_ISDN + 1,
1002 .nodetype = PRI_CPE,
1003 .qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL,
1004
1005#if defined(HAVE_PRI_CCSS)
1006 .cc_ptmp_recall_mode = 1,/* specificRecall */
1007 .cc_qsig_signaling_link_req = 1,/* retain */
1008 .cc_qsig_signaling_link_rsp = 1,/* retain */
1009#endif /* defined(HAVE_PRI_CCSS) */
1010
1011 .minunused = 2,
1012 .idleext = "",
1013 .idledial = "",
1014 .internationalprefix = "",
1015 .nationalprefix = "",
1016 .localprefix = "",
1017 .privateprefix = "",
1018 .unknownprefix = "",
1019 .colp_send = SIG_PRI_COLP_UPDATE,
1020 .resetinterval = -1,
1021 },
1022#endif
1023#if defined(HAVE_SS7)
1024 .ss7.ss7 = {
1025 .called_nai = SS7_NAI_NATIONAL,
1026 .calling_nai = SS7_NAI_NATIONAL,
1027 .internationalprefix = "",
1028 .nationalprefix = "",
1029 .subscriberprefix = "",
1030 .unknownprefix = "",
1031 .networkroutedprefix = ""
1032 },
1033#endif /* defined(HAVE_SS7) */
1034#ifdef HAVE_OPENR2
1035 .mfcr2 = {
1036 .variant = OR2_VAR_ITU,
1037 .mfback_timeout = -1,
1038 .metering_pulse_timeout = -1,
1039 .max_ani = 10,
1040 .max_dnis = 4,
1041 .get_ani_first = -1,
1042#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
1043 .skip_category_request = -1,
1044#endif
1045 .call_files = 0,
1046 .allow_collect_calls = 0,
1047 .charge_calls = 1,
1048 .accept_on_offer = 1,
1049 .forced_release = 0,
1050 .double_answer = 0,
1051 .immediate_accept = -1,
1052#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
1053 .dtmf_dialing = -1,
1054 .dtmf_detection = -1,
1055 .dtmf_time_on = OR2_DEFAULT_DTMF_ON,
1056 .dtmf_time_off = OR2_DEFAULT_DTMF_OFF,
1057#endif
1058#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
1059 .dtmf_end_timeout = -1,
1060#endif
1061 .logdir = "",
1062 .r2proto_file = "",
1063 .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
1064 .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
1065 },
1066#endif
1067 .chan = {
1068 .context = "default",
1069 .immediatering = 1,
1070 .cid_num = "",
1071 .cid_name = "",
1072 .cid_tag = "",
1073 .mohinterpret = "default",
1074 .mohsuggest = "",
1075 .parkinglot = "",
1076 .transfertobusy = 1,
1077 .dialmode = 0,
1078
1079 .ani_info_digits = 2,
1080 .ani_wink_time = 1000,
1081 .ani_timeout = 10000,
1082
1083 .cid_signalling = CID_SIG_BELL,
1084 .cid_start = CID_START_RING,
1085 .dahditrcallerid = 0,
1086 .use_callerid = 1,
1087 .sig = -1,
1088 .outsigmod = -1,
1089
1090 .cid_rxgain = +5.0,
1091
1092 .tonezone = -1,
1093
1094 .echocancel.head.tap_length = 1,
1095
1096 .busycount = 3,
1097
1098 .accountcode = "",
1099
1100 .mailbox = "",
1101
1102#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1103 .mwisend_fsk = 1,
1104#endif
1105 .polarityonanswerdelay = 600,
1106
1107 .sendcalleridafter = DEFAULT_CIDRINGS,
1108
1109 .buf_policy = DAHDI_POLICY_IMMEDIATE,
1110 .buf_no = numbufs,
1111 .usefaxbuffers = 0,
1112 .cc_params = ast_cc_config_params_init(),
1113 .firstdigit_timeout = ANALOG_FIRST_DIGIT_TIMEOUT,
1114 .interdigit_timeout = ANALOG_INTER_DIGIT_TIMEOUT,
1115 .matchdigit_timeout = ANALOG_MATCH_DIGIT_TIMEOUT,
1116 },
1117 .timing = {
1118 .prewinktime = -1,
1119 .preflashtime = -1,
1120 .winktime = -1,
1121 .flashtime = -1,
1122 .starttime = -1,
1123 .rxwinktime = -1,
1124 .rxflashtime = -1,
1125 .debouncetime = -1
1126 },
1127 .is_sig_auto = 1,
1128 .ignore_failed_channels = 1,
1129 .smdi_port = "/dev/ttyS0",
1130 };
1131
1132 return conf;
1133}