Asterisk - The Open Source Telephony Project GIT-master-f45f878
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}
#define CID_SIG_BELL
Definition: callerid.h:60
#define ast_cc_config_params_init()
Allocate and initialize an ast_cc_config_params structure.
Definition: ccss.h:135
static int numbufs
Definition: chan_dahdi.c:731
#define DEFAULT_CIDRINGS
Typically, how many rings before we should send Caller*ID.
Definition: chan_dahdi.c:640
#define ANALOG_INTER_DIGIT_TIMEOUT
Default time (ms) to detect following digits.
Definition: sig_analog.h:40
#define ANALOG_MATCH_DIGIT_TIMEOUT
Default time (ms) to wait, in case of ambiguous match.
Definition: sig_analog.h:42
#define ANALOG_FIRST_DIGIT_TIMEOUT
Default time (ms) to detect first digit.
Definition: sig_analog.h:38
@ SIG_PRI_COLP_UPDATE
Definition: sig_pri.h:441
#define DAHDI_CHAN_MAPPING_PHYSICAL
Definition: sig_pri.h:247
Channel configuration from chan_dahdi.conf . This struct is used for parsing the [channels] section o...
Definition: chan_dahdi.c:952

References ANALOG_FIRST_DIGIT_TIMEOUT, ANALOG_INTER_DIGIT_TIMEOUT, ANALOG_MATCH_DIGIT_TIMEOUT, ast_cc_config_params_init, CID_SIG_BELL, CID_START_RING, DAHDI_CHAN_MAPPING_PHYSICAL, DEFAULT_CIDRINGS, numbufs, and SIG_PRI_COLP_UPDATE.

Referenced by dahdi_create_channel_range(), process_dahdi(), and setup_dahdi().

◆ dahdi_close()

static void dahdi_close ( int  fd)
static

Definition at line 4393 of file chan_dahdi.c.

4394{
4395 if (fd > 0)
4396 close(fd);
4397}

Referenced by dahdi_close_sub().

◆ dahdi_close_sub()

static void dahdi_close_sub ( struct dahdi_pvt chan_pvt,
int  sub_num 
)
static

Definition at line 4399 of file chan_dahdi.c.

4400{
4401 dahdi_close(chan_pvt->subs[sub_num].dfd);
4402 chan_pvt->subs[sub_num].dfd = -1;
4403}
static void dahdi_close(int fd)
Definition: chan_dahdi.c:4393

References dahdi_close(), dahdi_subchannel::dfd, and dahdi_pvt::subs.

Referenced by alloc_sub(), destroy_dahdi_pvt(), and unalloc_sub().

◆ dahdi_conf_update()

void dahdi_conf_update ( struct dahdi_pvt p)

Definition at line 4843 of file chan_dahdi.c.

4844{
4845 int needconf = 0;
4846 int x;
4847 int useslavenative;
4848 struct dahdi_pvt *slave = NULL;
4849
4850 useslavenative = isslavenative(p, &slave);
4851 /* Start with the obvious, general stuff */
4852 for (x = 0; x < 3; x++) {
4853 /* Look for three way calls */
4854 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) {
4855 conf_add(p, &p->subs[x], x, 0);
4856 needconf++;
4857 } else {
4858 conf_del(p, &p->subs[x], x);
4859 }
4860 }
4861 /* If we have a slave, add him to our conference now. or DAX
4862 if this is slave native */
4863 for (x = 0; x < MAX_SLAVES; x++) {
4864 if (p->slaves[x]) {
4865 if (useslavenative)
4866 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
4867 else {
4868 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
4869 needconf++;
4870 }
4871 }
4872 }
4873 /* If we're supposed to be in there, do so now */
4874 if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
4875 if (useslavenative)
4876 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
4877 else {
4878 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
4879 needconf++;
4880 }
4881 }
4882 /* If we have a master, add ourselves to his conference */
4883 if (p->master) {
4884 if (isslavenative(p->master, NULL)) {
4886 } else {
4887 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
4888 }
4889 }
4890 if (!needconf) {
4891 /* Nobody is left (or should be left) in our conference.
4892 Kill it. */
4893 p->confno = -1;
4894 }
4895 ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
4896}
static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index)
Definition: chan_dahdi.c:4766
static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel)
Definition: chan_dahdi.c:4717
static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out)
Definition: chan_dahdi.c:4785
#define GET_CHANNEL(p)
Definition: chan_dahdi.c:1180
#define MAX_SLAVES
Definition: chan_dahdi.h:95
struct dahdi_pvt * slaves[MAX_SLAVES]
Definition: chan_dahdi.h:134
int inconference
Definition: chan_dahdi.h:136
unsigned int inthreeway
Definition: chan_dahdi.h:91

References ast_debug, dahdi_pvt::channel, conf_add(), conf_del(), dahdi_pvt::confno, dahdi_subchannel::dfd, GET_CHANNEL, dahdi_pvt::inconference, dahdi_subchannel::inthreeway, isslavenative(), dahdi_pvt::master, MAX_SLAVES, NULL, dahdi_pvt::slaves, SUB_REAL, and dahdi_pvt::subs.

Referenced by __dahdi_exception(), dahdi_fixup(), dahdi_handle_event(), dahdi_hangup(), dahdi_master_slave_unlink(), mkintf(), and native_start().

◆ dahdi_confmute()

static int dahdi_confmute ( struct dahdi_pvt p,
int  muted 
)
inlinestatic

Definition at line 5199 of file chan_dahdi.c.

5200{
5201 int x, res;
5202
5203 x = muted;
5204#if defined(HAVE_PRI) || defined(HAVE_SS7)
5205 switch (p->sig) {
5206#if defined(HAVE_PRI)
5208 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
5209 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */
5210 break;
5211 }
5212 /* Fall through */
5213#endif /* defined(HAVE_PRI) */
5214#if defined(HAVE_SS7)
5215 case SIG_SS7:
5216#endif /* defined(HAVE_SS7) */
5217 {
5218 int y = 1;
5219
5220 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y);
5221 if (res)
5222 ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n",
5223 p->channel, strerror(errno));
5224 }
5225 break;
5226 default:
5227 break;
5228 }
5229#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
5230 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x);
5231 if (res < 0)
5232 ast_log(LOG_WARNING, "DAHDI confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
5233 return res;
5234}

References ast_log, dahdi_pvt::channel, dahdi_subchannel::dfd, errno, LOG_WARNING, dahdi_pvt::sig, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_handle_dtmf(), dahdi_handle_event(), dahdi_hangup(), dahdi_new(), dahdi_read(), my_confmute(), and my_handle_dtmf().

◆ dahdi_create_channel_range()

static int dahdi_create_channel_range ( int  start,
int  end 
)
static

Definition at line 11527 of file chan_dahdi.c.

11528{
11529 struct dahdi_pvt *cur;
11530 struct dahdi_chan_conf default_conf = dahdi_chan_conf_default();
11531 struct dahdi_chan_conf base_conf = dahdi_chan_conf_default();
11533 int ret = RESULT_FAILURE; /* be pessimistic */
11534
11535 ast_debug(1, "channel range caps: %d - %d\n", start, end);
11537 for (cur = iflist; cur; cur = cur->next) {
11538 if (cur->channel >= start && cur->channel <= end) {
11540 "channel range %d-%d is occupied\n",
11541 start, end);
11542 goto out;
11543 }
11544 }
11545#ifdef HAVE_PRI
11546 {
11547 int i, x;
11548 for (x = 0; x < NUM_SPANS; x++) {
11549 struct dahdi_pri *pri = pris + x;
11550
11551 if (!pris[x].pri.pvts[0]) {
11552 break;
11553 }
11554 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
11555 int channo = pri->dchannels[i];
11556
11557 if (!channo) {
11558 break;
11559 }
11560 if (!pri->pri.fds[i]) {
11561 break;
11562 }
11563 if (channo >= start && channo <= end) {
11565 "channel range %d-%d is occupied by span %d\n",
11566 start, end, x + 1);
11567 goto out;
11568 }
11569 }
11570 }
11571 }
11572#endif
11573 if (!default_conf.chan.cc_params || !base_conf.chan.cc_params ||
11574 !conf.chan.cc_params) {
11575 goto out;
11576 }
11577 default_conf.wanted_channels_start = start;
11578 base_conf.wanted_channels_start = start;
11579 conf.wanted_channels_start = start;
11580 default_conf.wanted_channels_end = end;
11581 base_conf.wanted_channels_end = end;
11582 conf.wanted_channels_end = end;
11583 if (setup_dahdi_int(0, &default_conf, &base_conf, &conf) == 0) {
11584 ret = RESULT_SUCCESS;
11585 }
11586out:
11589 ast_cc_config_params_destroy(conf.chan.cc_params);
11591 return ret;
11592}
void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
Free memory from CCSS configuration params.
Definition: ccss.c:692
static int setup_dahdi_int(int reload, struct dahdi_chan_conf *default_conf, struct dahdi_chan_conf *base_conf, struct dahdi_chan_conf *conf)
Definition: chan_dahdi.c:19956
static struct dahdi_chan_conf dahdi_chan_conf_default(void)
Definition: chan_dahdi.c:990
#define RESULT_SUCCESS
Definition: cli.h:40
#define RESULT_FAILURE
Definition: cli.h:42
char * end
Definition: eagi_proxy.c:73
int wanted_channels_end
Don't create channels above this number (infinity by default)
Definition: chan_dahdi.c:986
struct dahdi_pvt chan
Definition: chan_dahdi.c:953
int wanted_channels_start
Don't create channels below this number.
Definition: chan_dahdi.c:980
FILE * out
Definition: utils/frame.c:33

References ast_cc_config_params_destroy(), ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::cc_params, dahdi_chan_conf::chan, dahdi_pvt::channel, dahdi_chan_conf_default(), end, iflist, iflock, LOG_ERROR, dahdi_pvt::next, NUM_SPANS, out, RESULT_FAILURE, RESULT_SUCCESS, setup_dahdi_int(), SIG_PRI_NUM_DCHANS, dahdi_chan_conf::wanted_channels_end, and dahdi_chan_conf::wanted_channels_start.

Referenced by dahdi_create_channels().

◆ dahdi_create_channels()

static char * dahdi_create_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 15764 of file chan_dahdi.c.

15765{
15766 int start;
15767 int end;
15768 int ret;
15769
15770 switch (cmd) {
15771 case CLI_INIT:
15772 e->command = "dahdi create channels";
15773 e->usage = "Usage: dahdi create channels <from> [<to>] - a range of channels\n"
15774 " dahdi create channels new - add channels not yet created\n"
15775 "For ISDN and SS7 the range should include complete spans.\n";
15776 return NULL;
15777 case CLI_GENERATE:
15778 return NULL;
15779 }
15780 if ((a->argc < 4) || a->argc > 5) {
15781 return CLI_SHOWUSAGE;
15782 }
15783 if (a->argc == 4 && !strcmp(a->argv[3], "new")) {
15784 ret = dahdi_create_channel_range(0, 0);
15785 return (RESULT_SUCCESS == ret) ? CLI_SUCCESS : CLI_FAILURE;
15786 }
15787 start = atoi(a->argv[3]);
15788 if (start <= 0) {
15789 ast_cli(a->fd, "Invalid starting channel number '%s'.\n",
15790 a->argv[3]);
15791 return CLI_FAILURE;
15792 }
15793 if (a->argc == 5) {
15794 end = atoi(a->argv[4]);
15795 if (end <= 0) {
15796 ast_cli(a->fd, "Invalid ending channel number '%s'.\n",
15797 a->argv[4]);
15798 return CLI_FAILURE;
15799 }
15800 } else {
15801 end = start;
15802 }
15803 if (end < start) {
15804 ast_cli(a->fd,
15805 "range end (%d) is smaller than range start (%d)\n",
15806 end, start);
15807 return CLI_FAILURE;
15808 }
15809 ret = dahdi_create_channel_range(start, end);
15810 return (RESULT_SUCCESS == ret) ? CLI_SUCCESS : CLI_FAILURE;
15811}
static int dahdi_create_channel_range(int start, int end)
Definition: chan_dahdi.c:11527
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static struct test_val a

References a, ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_create_channel_range(), end, NULL, RESULT_SUCCESS, and ast_cli_entry::usage.

◆ dahdi_destroy_channel_range()

static void dahdi_destroy_channel_range ( int  start,
int  end 
)
static

Definition at line 11445 of file chan_dahdi.c.

11446{
11447 struct dahdi_pvt *cur;
11448 struct dahdi_pvt *next;
11449 int destroyed_first = 0;
11450 int destroyed_last = 0;
11451
11453 ast_debug(1, "range: %d-%d\n", start, end);
11454 for (cur = iflist; cur; cur = next) {
11455 next = cur->next;
11456 if (cur->channel >= start && cur->channel <= end) {
11457 int x = DAHDI_FLASH;
11458
11459 if (cur->channel > destroyed_last) {
11460 destroyed_last = cur->channel;
11461 }
11462 if (destroyed_first < 1 || cur->channel < destroyed_first) {
11463 destroyed_first = cur->channel;
11464 }
11465 ast_debug(3, "Destroying %d\n", cur->channel);
11466 /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */
11467 ioctl(cur->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
11468
11469 destroy_channel(cur, 1);
11471 }
11472 }
11474 if (destroyed_first > start || destroyed_last < end) {
11475 ast_debug(1, "Asked to destroy %d-%d, destroyed %d-%d,\n",
11476 start, end, destroyed_first, destroyed_last);
11477 }
11478}
static void destroy_channel(struct dahdi_pvt *cur, int now)
Definition: chan_dahdi.c:5907
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483
struct ast_module * self
Definition: module.h:356

References ast_debug, ast_module_unref, ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, destroy_channel(), dahdi_subchannel::dfd, end, iflist, iflock, dahdi_pvt::next, ast_module_info::self, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_destroy_channels(), and do_monitor().

◆ dahdi_destroy_channels()

static char * dahdi_destroy_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 15720 of file chan_dahdi.c.

15721{
15722 int start;
15723 int end;
15724 switch (cmd) {
15725 case CLI_INIT:
15726 e->command = "dahdi destroy channels";
15727 e->usage =
15728 "Usage: dahdi destroy channels <from_channel> [<to_channel>]\n"
15729 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n";
15730 return NULL;
15731 case CLI_GENERATE:
15732 return NULL;
15733 }
15734 if ((a->argc < 4) || a->argc > 5) {
15735 return CLI_SHOWUSAGE;
15736 }
15737 start = atoi(a->argv[3]);
15738 if (start < 1) {
15739 ast_cli(a->fd, "Invalid starting channel number %s.\n",
15740 a->argv[4]);
15741 return CLI_FAILURE;
15742 }
15743 if (a->argc == 5) {
15744 end = atoi(a->argv[4]);
15745 if (end < 1) {
15746 ast_cli(a->fd, "Invalid ending channel number %s.\n",
15747 a->argv[4]);
15748 return CLI_FAILURE;
15749 }
15750 } else {
15751 end = start;
15752 }
15753
15754 if (end < start) {
15755 ast_cli(a->fd,
15756 "range end (%d) is smaller than range start (%d)\n",
15757 end, start);
15758 return CLI_FAILURE;
15759 }
15761 return CLI_SUCCESS;
15762}
static void dahdi_destroy_channel_range(int start, int end)
Definition: chan_dahdi.c:11445

References a, ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_destroy_channel_range(), end, NULL, and ast_cli_entry::usage.

◆ dahdi_devicestate()

static int dahdi_devicestate ( const char *  data)
static

Definition at line 14084 of file chan_dahdi.c.

14085{
14086#if defined(HAVE_PRI)
14087 const char *device;
14088 unsigned span;
14089 int res;
14090
14091 device = data;
14092
14093 if (*device != 'I') {
14094 /* The request is not for an ISDN span device. */
14095 return AST_DEVICE_UNKNOWN;
14096 }
14097 res = sscanf(device, "I%30u", &span);
14098 if (res != 1 || !span || NUM_SPANS < span) {
14099 /* Bad format for ISDN span device name. */
14100 return AST_DEVICE_UNKNOWN;
14101 }
14102 device = strchr(device, '/');
14103 if (!device) {
14104 /* Bad format for ISDN span device name. */
14105 return AST_DEVICE_UNKNOWN;
14106 }
14107
14108 /*
14109 * Since there are currently no other span devstate's defined,
14110 * it must be congestion.
14111 */
14112#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
14113 ++device;
14114 if (!strcmp(device, "congestion"))
14115#endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
14116 {
14117 return pris[span - 1].pri.congestion_devstate;
14118 }
14119#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
14120 else if (!strcmp(device, "threshold")) {
14121 return pris[span - 1].pri.threshold_devstate;
14122 }
14123 return AST_DEVICE_UNKNOWN;
14124#endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
14125#else
14126 return AST_DEVICE_UNKNOWN;
14127#endif /* defined(HAVE_PRI) */
14128}
@ AST_DEVICE_UNKNOWN
Definition: devicestate.h:53

References AST_DEVICE_UNKNOWN, and NUM_SPANS.

◆ dahdi_dial_str()

static int dahdi_dial_str ( struct dahdi_pvt pvt,
int  operation,
const char *  dial_str 
)
static

Definition at line 1350 of file chan_dahdi.c.

1351{
1352 int res;
1353 int offset;
1354 const char *pos;
1355 struct dahdi_dialoperation zo = {
1356 .op = operation,
1357 };
1358
1359 /* Convert the W's to ww. */
1360 pos = dial_str;
1361 for (offset = 0; offset < sizeof(zo.dialstr) - 1; ++offset) {
1362 if (!*pos) {
1363 break;
1364 }
1365 if (*pos == 'W') {
1366 /* Convert 'W' to "ww" */
1367 ++pos;
1368 if (offset >= sizeof(zo.dialstr) - 3) {
1369 /* No room to expand */
1370 break;
1371 }
1372 zo.dialstr[offset] = 'w';
1373 ++offset;
1374 zo.dialstr[offset] = 'w';
1375 continue;
1376 }
1377 zo.dialstr[offset] = *pos++;
1378 }
1379 /* The zo initialization has already terminated the dialstr. */
1380
1381 ast_debug(1, "Channel %d: Dial str '%s' expanded to '%s' sent to DAHDI_DIAL.\n",
1382 pvt->channel, dial_str, zo.dialstr);
1383 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo);
1384 if (res) {
1385 ast_log(LOG_WARNING, "Channel %d: Couldn't dial '%s': %s\n",
1386 pvt->channel, dial_str, strerror(errno));
1387 }
1388
1389 return res;
1390}

References ast_debug, ast_log, dahdi_pvt::channel, dahdi_subchannel::dfd, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_digit_begin(), dahdi_handle_event(), dahdi_read(), and my_dial_digits().

◆ dahdi_digit_begin()

static int dahdi_digit_begin ( struct ast_channel ast,
char  digit 
)
static

Definition at line 4497 of file chan_dahdi.c.

4498{
4499 struct dahdi_pvt *pvt;
4500 int idx;
4501 int dtmf;
4502 int res;
4503
4504 pvt = ast_channel_tech_pvt(chan);
4505
4506 ast_mutex_lock(&pvt->lock);
4507
4508 idx = dahdi_get_index(chan, pvt, 0);
4509
4510 if ((idx != SUB_REAL) || !pvt->owner)
4511 goto out;
4512
4513#ifdef HAVE_PRI
4514 switch (pvt->sig) {
4516 res = sig_pri_digit_begin(pvt->sig_pvt, chan, digit);
4517 if (!res)
4518 goto out;
4519 break;
4520 default:
4521 break;
4522 }
4523#endif
4524 dtmf = digit_to_dtmfindex(digit);
4525 if (dtmf == -1) {
4526 /* Not a valid DTMF digit */
4527 goto out;
4528 }
4529
4530 if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) {
4531 char dial_str[] = { 'T', digit, '\0' };
4532
4533 res = dahdi_dial_str(pvt, DAHDI_DIAL_OP_APPEND, dial_str);
4534 if (!res) {
4535 pvt->dialing = 1;
4536 }
4537 } else {
4538 pvt->dialing = 1;
4539 pvt->begindigit = digit;
4540
4541 /* Flush the write buffer in DAHDI to start sending the digit immediately. */
4542 dtmf = DAHDI_FLUSH_WRITE;
4543 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &dtmf);
4544 if (res) {
4545 ast_log(LOG_WARNING, "Unable to flush the DAHDI write buffer to send DTMF on channel %d: %s\n",
4546 pvt->channel, strerror(errno));
4547 }
4548
4549 ast_debug(1, "Channel %s started VLDTMF digit '%c'\n",
4550 ast_channel_name(chan), digit);
4551 }
4552
4553out:
4554 ast_mutex_unlock(&pvt->lock);
4555
4556 return 0;
4557}
char digit
static int digit_to_dtmfindex(char digit)
Definition: chan_dahdi.c:4481
static int dahdi_dial_str(struct dahdi_pvt *pvt, int operation, const char *dial_str)
Definition: chan_dahdi.c:1350
int sig_pri_digit_begin(struct sig_pri_chan *pvt, struct ast_channel *ast, char digit)
unsigned int pulse
TRUE if we will pulse dial.
Definition: chan_dahdi.h:354
char begindigit
DTMF digit in progress. 0 when no digit in progress.
Definition: chan_dahdi.h:761

References ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::begindigit, dahdi_pvt::channel, dahdi_dial_str(), dahdi_get_index, dahdi_subchannel::dfd, dahdi_pvt::dialing, digit, digit_to_dtmfindex(), errno, dahdi_pvt::lock, LOG_WARNING, out, dahdi_pvt::owner, dahdi_pvt::pulse, dahdi_pvt::sig, sig_pri_digit_begin(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SUB_REAL, and dahdi_pvt::subs.

◆ dahdi_digit_end()

static int dahdi_digit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
)
static

Definition at line 4559 of file chan_dahdi.c.

4560{
4561 struct dahdi_pvt *pvt;
4562 int res = 0;
4563 int idx;
4564 int x;
4565
4566 pvt = ast_channel_tech_pvt(chan);
4567
4568 ast_mutex_lock(&pvt->lock);
4569
4570 idx = dahdi_get_index(chan, pvt, 0);
4571
4572 if ((idx != SUB_REAL) || !pvt->owner || pvt->pulse)
4573 goto out;
4574
4575#ifdef HAVE_PRI
4576 /* This means that the digit was already sent via PRI signalling */
4577 if (dahdi_sig_pri_lib_handles(pvt->sig) && !pvt->begindigit) {
4578 goto out;
4579 }
4580#endif
4581
4582 if (pvt->begindigit) {
4583 x = -1;
4584 ast_debug(1, "Channel %s ending VLDTMF digit '%c'\n",
4585 ast_channel_name(chan), digit);
4586 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x);
4587 pvt->dialing = 0;
4588 pvt->begindigit = 0;
4589 }
4590
4591out:
4592 ast_mutex_unlock(&pvt->lock);
4593
4594 return res;
4595}

References ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::begindigit, dahdi_get_index, dahdi_sig_pri_lib_handles(), dahdi_subchannel::dfd, dahdi_pvt::dialing, digit, dahdi_pvt::lock, out, dahdi_pvt::owner, dahdi_pvt::pulse, dahdi_pvt::sig, SUB_REAL, and dahdi_pvt::subs.

◆ dahdi_dnd()

static int dahdi_dnd ( struct dahdi_pvt dahdichan,
int  flag 
)
static

enable or disable the chan_dahdi Do-Not-Disturb mode for a DAHDI channel

Parameters
dahdichan"Physical" DAHDI channel (e.g: DAHDI/5)
flagon 1 to enable, 0 to disable, -1 return dnd value

chan_dahdi has a DND (Do Not Disturb) mode for each dahdichan (physical DAHDI channel). Use this to enable or disable it.

Bug:
the use of the word "channel" for those dahdichans is really confusing.

Definition at line 9843 of file chan_dahdi.c.

9844{
9845 if (dahdi_analog_lib_handles(dahdichan->sig, dahdichan->radio, dahdichan->oprmode)) {
9846 return analog_dnd(dahdichan->sig_pvt, flag);
9847 }
9848
9849 if (flag == -1) {
9850 return dahdichan->dnd;
9851 }
9852
9853 /* Do not disturb */
9854 dahdichan->dnd = flag;
9855 ast_verb(3, "%s DND on channel %d\n",
9856 flag? "Enabled" : "Disabled",
9857 dahdichan->channel);
9858 publish_dnd_state(dahdichan->channel, flag ? "enabled" : "disabled");
9859 return 0;
9860}
static void publish_dnd_state(int channel, const char *status)
Definition: chan_dahdi.c:9814
long int flag
Definition: f2c.h:83
int analog_dnd(struct analog_pvt *p, int flag)
Definition: sig_analog.c:4165
unsigned int dnd
TRUE if Do-Not-Disturb is enabled, present only for non sig_analog.
Definition: chan_dahdi.h:262

References analog_dnd(), ast_verb, dahdi_pvt::channel, dahdi_analog_lib_handles(), dahdi_pvt::dnd, dahdi_pvt::oprmode, publish_dnd_state(), dahdi_pvt::radio, dahdi_pvt::sig, and dahdi_pvt::sig_pvt.

Referenced by action_dahdidndoff(), action_dahdidndon(), action_dahdishowchannels(), analog_ss_thread(), dahdi_set_dnd(), and dahdi_show_channel().

◆ dahdi_dtmf_detect_disable()

void dahdi_dtmf_detect_disable ( struct dahdi_pvt p)

Definition at line 6763 of file chan_dahdi.c.

6764{
6765 int val = 0;
6766
6767 p->ignoredtmf = 1;
6768
6769 ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
6770
6771 if (!p->hardwaredtmf && p->dsp) {
6772 p->dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
6774 }
6775}
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1768
unsigned int ignoredtmf
TRUE if DTMF detection is disabled.
Definition: chan_dahdi.h:310
int dsp_features
DSP feature flags: DSP_FEATURE_xxx.
Definition: chan_dahdi.h:738
Definition: ast_expr2.c:325

References ast_dsp_set_features(), dahdi_subchannel::dfd, dahdi_pvt::dsp, dahdi_pvt::dsp_features, dahdi_pvt::hardwaredtmf, dahdi_pvt::ignoredtmf, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_setoption(), and native_start().

◆ dahdi_dtmf_detect_enable()

void dahdi_dtmf_detect_enable ( struct dahdi_pvt p)

Definition at line 6777 of file chan_dahdi.c.

6778{
6779 int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
6780
6781 if (p->channel == CHAN_PSEUDO)
6782 return;
6783
6784 p->ignoredtmf = 0;
6785
6786 ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
6787
6788 if (!p->hardwaredtmf && p->dsp) {
6791 }
6792}
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28

References ast_dsp_set_features(), CHAN_PSEUDO, dahdi_pvt::channel, dahdi_subchannel::dfd, dahdi_pvt::dsp, DSP_FEATURE_DIGIT_DETECT, dahdi_pvt::dsp_features, dahdi_pvt::hardwaredtmf, dahdi_pvt::ignoredtmf, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_setoption(), and native_stop().

◆ dahdi_ec_disable()

void dahdi_ec_disable ( struct dahdi_pvt p)

Definition at line 4970 of file chan_dahdi.c.

4971{
4972 int res;
4973
4974 if (p->echocanon) {
4975 struct dahdi_echocanparams ecp = { .tap_length = 0 };
4976
4977 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &ecp);
4978
4979 if (res)
4980 ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno));
4981 else
4982 ast_debug(1, "Disabled echo cancellation on channel %d\n", p->channel);
4983 }
4984
4985 p->echocanon = 0;
4986}
unsigned int echocanon
TRUE if echo cancellation is turned on.
Definition: chan_dahdi.h:272

References ast_debug, ast_log, dahdi_pvt::channel, dahdi_subchannel::dfd, dahdi_pvt::echocanon, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.

Referenced by __dahdi_exception(), dahdi_func_write(), dahdi_handle_event(), dahdi_hangup(), dahdi_setoption(), handle_init_event(), my_set_echocanceller(), and native_start().

◆ dahdi_ec_enable()

void dahdi_ec_enable ( struct dahdi_pvt p)

Definition at line 4898 of file chan_dahdi.c.

4899{
4900 int res;
4901 if (!p)
4902 return;
4903 if (p->echocanon) {
4904 ast_debug(1, "Echo cancellation already on\n");
4905 return;
4906 }
4907 if (p->digital) {
4908 ast_debug(1, "Echo cancellation isn't required on digital connection\n");
4909 return;
4910 }
4911 if (p->echocancel.head.tap_length) {
4912#if defined(HAVE_PRI) || defined(HAVE_SS7)
4913 switch (p->sig) {
4914#if defined(HAVE_PRI)
4916 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
4917 /*
4918 * PRI nobch pseudo channel. Does not need ec anyway.
4919 * Does not handle ioctl(DAHDI_AUDIOMODE)
4920 */
4921 return;
4922 }
4923 /* Fall through */
4924#endif /* defined(HAVE_PRI) */
4925#if defined(HAVE_SS7)
4926 case SIG_SS7:
4927#endif /* defined(HAVE_SS7) */
4928 {
4929 int x = 1;
4930
4931 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x);
4932 if (res)
4934 "Unable to enable audio mode on channel %d (%s)\n",
4935 p->channel, strerror(errno));
4936 }
4937 break;
4938 default:
4939 break;
4940 }
4941#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
4942 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &p->echocancel);
4943 if (res) {
4944 ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
4945 } else {
4946 p->echocanon = 1;
4947 ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel);
4948 }
4949 } else
4950 ast_debug(1, "No echo cancellation requested\n");
4951}
struct dahdi_pvt::@115 echocancel
Echo cancel parameters.
struct dahdi_echocanparams head
Definition: chan_dahdi.h:627
unsigned int digital
TRUE if the transfer capability of the call is digital.
Definition: chan_dahdi.h:260

References ast_debug, ast_log, dahdi_pvt::channel, dahdi_subchannel::dfd, dahdi_pvt::digital, dahdi_pvt::echocancel, dahdi_pvt::echocanon, errno, dahdi_pvt::head, LOG_WARNING, dahdi_pvt::sig, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, SUB_REAL, and dahdi_pvt::subs.

Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_func_write(), dahdi_handle_event(), dahdi_setoption(), handle_init_event(), my_set_echocanceller(), and native_stop().

◆ dahdi_exception()

static struct ast_frame * dahdi_exception ( struct ast_channel ast)
static

Definition at line 8773 of file chan_dahdi.c.

8774{
8775 struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
8776 struct ast_frame *f;
8777 ast_mutex_lock(&p->lock);
8778 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
8779 struct analog_pvt *analog_p = p->sig_pvt;
8780 f = analog_exception(analog_p, ast);
8781 } else {
8782 f = __dahdi_exception(ast);
8783 }
8785 return f;
8786}
static struct ast_frame * __dahdi_exception(struct ast_channel *ast)
Definition: chan_dahdi.c:8651
struct ast_frame * analog_exception(struct analog_pvt *p, struct ast_channel *ast)
Definition: sig_analog.c:3673

References __dahdi_exception(), analog_exception(), ast_channel_tech_pvt(), ast_mutex_lock, ast_mutex_unlock, dahdi_analog_lib_handles(), dahdi_pvt::lock, dahdi_pvt::oprmode, dahdi_pvt::radio, dahdi_pvt::sig, and dahdi_pvt::sig_pvt.

◆ dahdi_fake_event()

static int dahdi_fake_event ( struct dahdi_pvt p,
int  mode 
)
static

Definition at line 16739 of file chan_dahdi.c.

16740{
16741 if (p) {
16742 switch (mode) {
16743 case TRANSFER:
16744 p->fake_event = DAHDI_EVENT_WINKFLASH;
16745 break;
16746 case HANGUP:
16747 p->fake_event = DAHDI_EVENT_ONHOOK;
16748 break;
16749 default:
16750 ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, ast_channel_name(p->owner));
16751 }
16752 }
16753 return 0;
16754}

References ast_channel_name(), ast_log, dahdi_pvt::fake_event, HANGUP, LOG_WARNING, dahdi_pvt::owner, and TRANSFER.

Referenced by action_transfer(), and action_transferhangup().

◆ dahdi_fixup()

static int dahdi_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
)
static

Definition at line 7424 of file chan_dahdi.c.

7425{
7426 struct dahdi_pvt *p = ast_channel_tech_pvt(newchan);
7427 int x;
7428
7429 ast_mutex_lock(&p->lock);
7430
7431 ast_debug(1, "New owner for channel %d is %s\n", p->channel, ast_channel_name(newchan));
7432 if (p->owner == oldchan) {
7433 p->owner = newchan;
7434 }
7435 for (x = 0; x < 3; x++) {
7436 if (p->subs[x].owner == oldchan) {
7437 if (!x) {
7439 }
7440 p->subs[x].owner = newchan;
7441 }
7442 }
7443 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
7444 analog_fixup(oldchan, newchan, p->sig_pvt);
7445#if defined(HAVE_PRI)
7446 } else if (dahdi_sig_pri_lib_handles(p->sig)) {
7447 sig_pri_fixup(oldchan, newchan, p->sig_pvt);
7448#endif /* defined(HAVE_PRI) */
7449#if defined(HAVE_SS7)
7450 } else if (p->sig == SIG_SS7) {
7451 sig_ss7_fixup(oldchan, newchan, p->sig_pvt);
7452#endif /* defined(HAVE_SS7) */
7453 }
7455
7457
7458 if (ast_channel_state(newchan) == AST_STATE_RINGING) {
7460 }
7461 return 0;
7462}
static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Definition: chan_dahdi.c:9352
void dahdi_master_slave_unlink(struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
Definition: chan_dahdi.c:7344
@ AST_CONTROL_RINGING
int analog_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, void *newp)
Definition: sig_analog.c:4127
void sig_pri_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan)
void sig_ss7_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_ss7_chan *pchan)

References analog_fixup(), ast_channel_name(), ast_channel_tech_pvt(), AST_CONTROL_RINGING, ast_debug, ast_mutex_lock, ast_mutex_unlock, AST_STATE_RINGING, dahdi_pvt::channel, dahdi_analog_lib_handles(), dahdi_conf_update(), dahdi_indicate(), dahdi_master_slave_unlink(), dahdi_sig_pri_lib_handles(), dahdi_pvt::lock, NULL, dahdi_pvt::oprmode, dahdi_subchannel::owner, dahdi_pvt::owner, dahdi_pvt::radio, dahdi_pvt::sig, sig_pri_fixup(), dahdi_pvt::sig_pvt, SIG_SS7, sig_ss7_fixup(), and dahdi_pvt::subs.

◆ dahdi_func_read()

static int dahdi_func_read ( struct ast_channel chan,
const char *  function,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 7062 of file chan_dahdi.c.

7063{
7064 struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
7065 int res = 0;
7066
7067 if (!p) {
7068 /* No private structure! */
7069 *buf = '\0';
7070 return -1;
7071 }
7072
7073 if (!strcasecmp(data, "rxgain")) {
7074 ast_mutex_lock(&p->lock);
7075 snprintf(buf, len, "%f", p->rxgain);
7077 } else if (!strcasecmp(data, "txgain")) {
7078 ast_mutex_lock(&p->lock);
7079 snprintf(buf, len, "%f", p->txgain);
7081 } else if (!strcasecmp(data, "dahdi_channel")) {
7082 ast_mutex_lock(&p->lock);
7083 snprintf(buf, len, "%d", p->channel);
7085 } else if (!strcasecmp(data, "dahdi_span")) {
7086 ast_mutex_lock(&p->lock);
7087 snprintf(buf, len, "%d", p->span);
7089 } else if (!strcasecmp(data, "dahdi_group")) {
7090 ast_mutex_lock(&p->lock);
7091 snprintf(buf, len, "%llu", p->group);
7093 } else if (!strcasecmp(data, "dahdi_type")) {
7094 ast_mutex_lock(&p->lock);
7095 switch (p->sig) {
7096#if defined(HAVE_OPENR2)
7097 case SIG_MFCR2:
7098 ast_copy_string(buf, "mfc/r2", len);
7099 break;
7100#endif /* defined(HAVE_OPENR2) */
7101#if defined(HAVE_PRI)
7103 ast_copy_string(buf, "pri", len);
7104 break;
7105#endif /* defined(HAVE_PRI) */
7106 case 0:
7107 ast_copy_string(buf, "pseudo", len);
7108 break;
7109#if defined(HAVE_SS7)
7110 case SIG_SS7:
7111 ast_copy_string(buf, "ss7", len);
7112 break;
7113#endif /* defined(HAVE_SS7) */
7114 default:
7115 /* The only thing left is analog ports. */
7116 ast_copy_string(buf, "analog", len);
7117 break;
7118 }
7120#if defined(HAVE_PRI)
7121#if defined(HAVE_PRI_REVERSE_CHARGE)
7122 } else if (!strcasecmp(data, "reversecharge")) {
7123 ast_mutex_lock(&p->lock);
7124 switch (p->sig) {
7126 snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->reverse_charging_indication);
7127 break;
7128 default:
7129 *buf = '\0';
7130 res = -1;
7131 break;
7132 }
7134#endif
7135#if defined(HAVE_PRI_SETUP_KEYPAD)
7136 } else if (!strcasecmp(data, "keypad_digits")) {
7137 ast_mutex_lock(&p->lock);
7138 switch (p->sig) {
7140 ast_copy_string(buf, ((struct sig_pri_chan *) p->sig_pvt)->keypad_digits,
7141 len);
7142 break;
7143 default:
7144 *buf = '\0';
7145 res = -1;
7146 break;
7147 }
7149#endif /* defined(HAVE_PRI_SETUP_KEYPAD) */
7150 } else if (!strcasecmp(data, "no_media_path")) {
7151 ast_mutex_lock(&p->lock);
7152 switch (p->sig) {
7154 /*
7155 * TRUE if the call is on hold or is call waiting because
7156 * there is no media path available.
7157 */
7158 snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel);
7159 break;
7160 default:
7161 *buf = '\0';
7162 res = -1;
7163 break;
7164 }
7166#endif /* defined(HAVE_PRI) */
7167 } else if (!strcasecmp(data, "dialmode")) {
7168 struct analog_pvt *analog_p;
7169 ast_mutex_lock(&p->lock);
7170 analog_p = p->sig_pvt;
7171 /* Hardcode p->radio and p->oprmode as 0 since we're using this to check for analogness, not the handler */
7172 if (dahdi_analog_lib_handles(p->sig, 0, 0) && analog_p) {
7173 switch (analog_p->dialmode) {
7175 ast_copy_string(buf, "both", len);
7176 break;
7178 ast_copy_string(buf, "pulse", len);
7179 break;
7181 ast_copy_string(buf, "dtmf", len);
7182 break;
7184 ast_copy_string(buf, "none", len);
7185 break;
7186 }
7187 } else {
7188 ast_log(LOG_WARNING, "%s only supported on analog channels\n", data);
7189 *buf = '\0';
7190 res = -1;
7191 }
7193 } else {
7194 *buf = '\0';
7195 res = -1;
7196 }
7197
7198 return res;
7199}
@ ANALOG_DIALMODE_DTMF
Definition: sig_analog.h:122
@ ANALOG_DIALMODE_PULSE
Definition: sig_analog.h:121
@ ANALOG_DIALMODE_NONE
Definition: sig_analog.h:123
@ ANALOG_DIALMODE_BOTH
Definition: sig_analog.h:120
enum analog_dialmode dialmode
Definition: sig_analog.h:321

References ANALOG_DIALMODE_BOTH, ANALOG_DIALMODE_DTMF, ANALOG_DIALMODE_NONE, ANALOG_DIALMODE_PULSE, ast_channel_tech_pvt(), ast_copy_string(), ast_log, ast_mutex_lock, ast_mutex_unlock, buf, dahdi_pvt::channel, dahdi_analog_lib_handles(), analog_pvt::dialmode, dahdi_pvt::group, len(), dahdi_pvt::lock, LOG_WARNING, dahdi_pvt::rxgain, dahdi_pvt::sig, SIG_MFCR2, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, dahdi_pvt::span, and dahdi_pvt::txgain.

◆ dahdi_func_write()

static int dahdi_func_write ( struct ast_channel chan,
const char *  function,
char *  data,
const char *  value 
)
static

Definition at line 7231 of file chan_dahdi.c.

7232{
7233 struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
7234 int res = 0;
7235
7236 if (!p) {
7237 /* No private structure! */
7238 return -1;
7239 }
7240
7241 if (!strcasecmp(data, "buffers")) {
7242 int num_bufs, policy;
7243
7244 if (!(parse_buffers_policy(value, &num_bufs, &policy))) {
7245 struct dahdi_bufferinfo bi = {
7246 .txbufpolicy = policy,
7247 .rxbufpolicy = policy,
7248 .bufsize = p->bufsize,
7249 .numbufs = num_bufs,
7250 };
7251 int bpres;
7252
7253 if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
7254 ast_log(LOG_WARNING, "Channel '%d' unable to override buffer policy: %s\n", p->channel, strerror(errno));
7255 } else {
7256 p->bufferoverrideinuse = 1;
7257 }
7258 } else {
7259 res = -1;
7260 }
7261 } else if (!strcasecmp(data, "echocan_mode")) {
7262 if (!strcasecmp(value, "on")) {
7263 ast_mutex_lock(&p->lock);
7264 dahdi_ec_enable(p);
7266 } else if (!strcasecmp(value, "off")) {
7267 ast_mutex_lock(&p->lock);
7270#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
7271 } else if (!strcasecmp(value, "fax")) {
7272 int blah = 1;
7273
7274 ast_mutex_lock(&p->lock);
7275 if (!p->echocanon) {
7276 dahdi_ec_enable(p);
7277 }
7278 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) {
7279 ast_log(LOG_WARNING, "Unable to place echocan into fax mode on channel %d: %s\n", p->channel, strerror(errno));
7280 }
7282 } else if (!strcasecmp(value, "voice")) {
7283 int blah = 0;
7284
7285 ast_mutex_lock(&p->lock);
7286 if (!p->echocanon) {
7287 dahdi_ec_enable(p);
7288 }
7289 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) {
7290 ast_log(LOG_WARNING, "Unable to place echocan into voice mode on channel %d: %s\n", p->channel, strerror(errno));
7291 }
7293#endif
7294 } else {
7295 ast_log(LOG_WARNING, "Unsupported value '%s' provided for '%s' item.\n", value, data);
7296 res = -1;
7297 }
7298 } else if (!strcasecmp(data, "dialmode")) {
7299 struct analog_pvt *analog_p;
7300
7301 ast_mutex_lock(&p->lock);
7302 analog_p = p->sig_pvt;
7303 if (!dahdi_analog_lib_handles(p->sig, 0, 0) || !analog_p) {
7304 ast_log(LOG_WARNING, "%s only supported on analog channels\n", data);
7306 return -1;
7307 }
7308 /* analog pvt is used for pulse dialing, so update both */
7309 if (!strcasecmp(value, "pulse")) {
7310 p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_PULSE;
7311 } else if (!strcasecmp(value, "dtmf") || !strcasecmp(value, "tone")) {
7312 p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_DTMF;
7313 } else if (!strcasecmp(value, "none")) {
7314 p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_NONE;
7315 } else if (!strcasecmp(value, "both")) {
7316 p->dialmode = analog_p->dialmode = ANALOG_DIALMODE_BOTH;
7317 } else {
7318 ast_log(LOG_WARNING, "'%s' is an invalid setting for %s\n", value, data);
7319 res = -1;
7320 }
7322 } else if (!strcasecmp(data, "waitfordialtone")) {
7323 if (ast_strlen_zero(value)) {
7324 ast_log(LOG_WARNING, "waitfordialtone requires a duration in ms\n");
7325 return -1;
7326 }
7327
7328 ast_mutex_lock(&p->lock);
7329 if (!CANPROGRESSDETECT(p)) {
7330 ast_log(LOG_WARNING, "%s only supported on analog trunks\n", data);
7332 return -1;
7333 }
7334 /* Only set the temp waitfordialtone setting, not the permanent one. */
7335 p->waitfordialtonetemp = atoi(value);
7337 } else {
7338 res = -1;
7339 }
7340
7341 return res;
7342}
#define CANPROGRESSDETECT(p)
Definition: chan_dahdi.c:715
static int parse_buffers_policy(const char *parse, int *num_buffers, int *policy)
Definition: chan_dahdi.c:7202
unsigned int bufferoverrideinuse
Definition: chan_dahdi.h:278
int bufsize
Definition: chan_dahdi.h:138
int waitfordialtonetemp
Transient variable. Same as waitfordialtone, but temporarily set for a specific call,...
Definition: chan_dahdi.h:660
int dialmode
Definition: chan_dahdi.h:149

References ANALOG_DIALMODE_BOTH, ANALOG_DIALMODE_DTMF, ANALOG_DIALMODE_NONE, ANALOG_DIALMODE_PULSE, ast_channel_tech_pvt(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), dahdi_pvt::bufferoverrideinuse, dahdi_pvt::bufsize, CANPROGRESSDETECT, dahdi_pvt::channel, dahdi_analog_lib_handles(), dahdi_ec_disable(), dahdi_ec_enable(), dahdi_subchannel::dfd, dahdi_pvt::dialmode, analog_pvt::dialmode, dahdi_pvt::echocanon, errno, dahdi_pvt::lock, LOG_WARNING, parse_buffers_policy(), dahdi_pvt::sig, dahdi_pvt::sig_pvt, SUB_REAL, dahdi_pvt::subs, value, and dahdi_pvt::waitfordialtonetemp.

◆ dahdi_get_event()

static int dahdi_get_event ( int  fd)
inlinestatic

Avoid the silly dahdi_getevent which ignores a bunch of events.

Definition at line 773 of file chan_dahdi.c.

774{
775 int j;
776 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
777 return -1;
778 return j;
779}

Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_handle_event(), do_monitor(), mwi_thread(), my_distinctive_ring(), my_get_callerid(), and my_get_event().

◆ dahdi_handle_dtmf()

static void dahdi_handle_dtmf ( struct ast_channel ast,
int  idx,
struct ast_frame **  dest 
)
static

Definition at line 7594 of file chan_dahdi.c.

7595{
7596 struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
7597 struct ast_frame *f = *dest;
7598
7599 ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
7600 f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
7601 (unsigned)f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
7602
7603 if (p->confirmanswer) {
7604 if (f->frametype == AST_FRAME_DTMF_END) {
7605 ast_debug(1, "Confirm answer on %s!\n", ast_channel_name(ast));
7606 /* Upon receiving a DTMF digit, consider this an answer confirmation instead
7607 of a DTMF digit */
7610 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
7611 p->confirmanswer = 0;
7612 } else {
7613 p->subs[idx].f.frametype = AST_FRAME_NULL;
7614 p->subs[idx].f.subclass.integer = 0;
7615 }
7616 *dest = &p->subs[idx].f;
7617 } else if (p->callwaitcas) {
7618 if (f->frametype == AST_FRAME_DTMF_END) {
7619 if ((f->subclass.integer == 'A') || (f->subclass.integer == 'D')) {
7620 ast_debug(1, "Got some DTMF, but it's for the CAS\n");
7621 ast_free(p->cidspill);
7622 p->cidspill = NULL;
7623 send_cwcidspill(p);
7624 }
7625 p->callwaitcas = 0;
7626 }
7627 p->subs[idx].f.frametype = AST_FRAME_NULL;
7628 p->subs[idx].f.subclass.integer = 0;
7629 *dest = &p->subs[idx].f;
7630 } else if (f->subclass.integer == 'f') {
7631 if (f->frametype == AST_FRAME_DTMF_END) {
7632 /* Fax tone -- Handle and return NULL */
7633 if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
7634 /* If faxbuffers are configured, use them for the fax transmission */
7635 if (p->usefaxbuffers && !p->bufferoverrideinuse) {
7636 struct dahdi_bufferinfo bi = {
7637 .txbufpolicy = p->faxbuf_policy,
7638 .bufsize = p->bufsize,
7639 .numbufs = p->faxbuf_no
7640 };
7641 int res;
7642
7643 if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
7644 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno));
7645 } else {
7646 p->bufferoverrideinuse = 1;
7647 }
7648 }
7649 p->faxhandled = 1;
7650 if (p->dsp) {
7651 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
7653 ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
7654 }
7655 if (strcmp(ast_channel_exten(ast), "fax")) {
7656 const char *target_context = ast_channel_context(ast);
7657
7658 /*
7659 * We need to unlock 'ast' here because ast_exists_extension has the
7660 * potential to start autoservice on the channel. Such action is prone
7661 * to deadlock if the channel is locked.
7662 *
7663 * ast_async_goto() has its own restriction on not holding the
7664 * channel lock.
7665 */
7667 ast_channel_unlock(ast);
7668 if (ast_exists_extension(ast, target_context, "fax", 1,
7669 S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, NULL))) {
7670 ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast));
7671 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
7672 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
7673 if (ast_async_goto(ast, target_context, "fax", 1))
7674 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
7675 } else {
7676 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
7677 }
7678 ast_channel_lock(ast);
7679 ast_mutex_lock(&p->lock);
7680 } else {
7681 ast_debug(1, "Already in a fax extension, not redirecting\n");
7682 }
7683 } else {
7684 ast_debug(1, "Fax already handled\n");
7685 }
7686 dahdi_confmute(p, 0);
7687 }
7688 p->subs[idx].f.frametype = AST_FRAME_NULL;
7689 p->subs[idx].f.subclass.integer = 0;
7690 *dest = &p->subs[idx].f;
7691 }
7692}
static int dahdi_confmute(struct dahdi_pvt *p, int muted)
Definition: chan_dahdi.c:5199
#define CALLPROGRESS_FAX
Definition: chan_dahdi.c:682
static int send_cwcidspill(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5277
const char * ast_channel_exten(const struct ast_channel *chan)
@ AST_FRAME_DTMF_END
@ AST_FRAME_DTMF_BEGIN
@ AST_FRAME_CONTROL
@ AST_CONTROL_ANSWER
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:6969
int faxbuf_policy
Definition: chan_dahdi.h:142
unsigned int confirmanswer
TRUE if to wait for a DTMF digit to confirm answer.
Definition: chan_dahdi.h:245
int callprogress
Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
Definition: chan_dahdi.h:651
int faxbuf_no
Definition: chan_dahdi.h:141
unsigned int faxhandled
TRUE if a fax tone has already been handled.
Definition: chan_dahdi.h:274
unsigned int usefaxbuffers
Definition: chan_dahdi.h:276

References ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_name(), ast_channel_tech_pvt(), ast_channel_unlock, AST_CONTROL_ANSWER, ast_debug, ast_dsp_set_features(), ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_free, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_verb, dahdi_pvt::bufferoverrideinuse, dahdi_pvt::bufsize, dahdi_pvt::callprogress, CALLPROGRESS_FAX, dahdi_pvt::callwaitcas, dahdi_pvt::cidspill, dahdi_pvt::confirmanswer, dahdi_confmute(), dahdi_subchannel::dfd, dahdi_pvt::dsp, dahdi_pvt::dsp_features, errno, dahdi_subchannel::f, dahdi_pvt::faxbuf_no, dahdi_pvt::faxbuf_policy, dahdi_pvt::faxhandled, ast_frame::frametype, ast_frame_subclass::integer, dahdi_pvt::lock, LOG_NOTICE, LOG_WARNING, NULL, pbx_builtin_setvar_helper(), S_COR, send_cwcidspill(), ast_frame::subclass, dahdi_pvt::subs, and dahdi_pvt::usefaxbuffers.

Referenced by dahdi_handle_event(), and dahdi_read().

◆ dahdi_handle_event()

static struct ast_frame * dahdi_handle_event ( struct ast_channel ast)
static

Definition at line 7749 of file chan_dahdi.c.

7750{
7751 int res, x;
7752 int idx, mysig;
7753 char *c;
7754 struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
7755 pthread_t threadid;
7756 struct ast_channel *chan;
7757 struct ast_frame *f;
7758
7759 idx = dahdi_get_index(ast, p, 0);
7760 if (idx < 0) {
7761 return &ast_null_frame;
7762 }
7763 mysig = p->sig;
7764 if (p->outsigmod > -1)
7765 mysig = p->outsigmod;
7766 p->subs[idx].f.frametype = AST_FRAME_NULL;
7767 p->subs[idx].f.subclass.integer = 0;
7768 p->subs[idx].f.datalen = 0;
7769 p->subs[idx].f.samples = 0;
7770 p->subs[idx].f.mallocd = 0;
7771 p->subs[idx].f.offset = 0;
7772 p->subs[idx].f.src = "dahdi_handle_event";
7773 p->subs[idx].f.data.ptr = NULL;
7774 f = &p->subs[idx].f;
7775
7776 if (p->fake_event) {
7777 res = p->fake_event;
7778 p->fake_event = 0;
7779 } else
7780 res = dahdi_get_event(p->subs[idx].dfd);
7781
7782 ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, idx);
7783
7784 if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) {
7785 p->pulsedial = (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0;
7786 ast_debug(1, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
7787#if defined(HAVE_PRI)
7789 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING
7790 && p->pri
7791 && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
7792 /* absorb event */
7793 } else
7794#endif /* defined(HAVE_PRI) */
7795 {
7796 /* Unmute conference */
7797 dahdi_confmute(p, 0);
7799 p->subs[idx].f.subclass.integer = res & 0xff;
7800 dahdi_handle_dtmf(ast, idx, &f);
7801 }
7802 return f;
7803 }
7804
7805 if (res & DAHDI_EVENT_DTMFDOWN) {
7806 ast_debug(1, "DTMF Down '%c'\n", res & 0xff);
7807#if defined(HAVE_PRI)
7809 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING
7810 && p->pri
7811 && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
7812 /* absorb event */
7813 } else
7814#endif /* defined(HAVE_PRI) */
7815 {
7816 /* Mute conference */
7817 dahdi_confmute(p, 1);
7819 p->subs[idx].f.subclass.integer = res & 0xff;
7820 dahdi_handle_dtmf(ast, idx, &f);
7821 }
7822 return &p->subs[idx].f;
7823 }
7824
7825 switch (res) {
7826 case DAHDI_EVENT_EC_DISABLED:
7827 ast_verb(3, "Channel %d echo canceler disabled.\n", p->channel);
7828 p->echocanon = 0;
7829 break;
7830#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
7831 case DAHDI_EVENT_TX_CED_DETECTED:
7832 ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel);
7833 break;
7834 case DAHDI_EVENT_RX_CED_DETECTED:
7835 ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel);
7836 break;
7837 case DAHDI_EVENT_EC_NLP_DISABLED:
7838 ast_verb(3, "Channel %d echo canceler disabled its NLP.\n", p->channel);
7839 break;
7840 case DAHDI_EVENT_EC_NLP_ENABLED:
7841 ast_verb(3, "Channel %d echo canceler enabled its NLP.\n", p->channel);
7842 break;
7843#endif
7844 case DAHDI_EVENT_BITSCHANGED:
7845#ifdef HAVE_OPENR2
7846 if (p->sig != SIG_MFCR2) {
7847 ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig));
7848 } else {
7849 ast_debug(1, "bits changed in chan %d\n", p->channel);
7850 openr2_chan_handle_cas(p->r2chan);
7851 }
7852#else
7853 ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig));
7854#endif
7855 break;
7856 case DAHDI_EVENT_PULSE_START:
7857 /* Stop tone if there's a pulse start and the PBX isn't started */
7858 if (!ast_channel_pbx(ast))
7859 tone_zone_play_tone(p->subs[idx].dfd, -1);
7860 break;
7861 case DAHDI_EVENT_DIALCOMPLETE:
7862 /* DAHDI has completed dialing all digits sent using DAHDI_DIAL. */
7863#if defined(HAVE_PRI)
7865 if (p->inalarm) {
7866 break;
7867 }
7868 if (ioctl(p->subs[idx].dfd, DAHDI_DIALING, &x) == -1) {
7869 ast_debug(1, "DAHDI_DIALING ioctl failed on %s: %s\n",
7870 ast_channel_name(ast), strerror(errno));
7871 return NULL;
7872 }
7873 if (x) {
7874 /* Still dialing in DAHDI driver */
7875 break;
7876 }
7877 /*
7878 * The ast channel is locked and the private may be locked more
7879 * than once.
7880 */
7882 break;
7883 }
7884#endif /* defined(HAVE_PRI) */
7885#ifdef HAVE_OPENR2
7886 if ((p->sig & SIG_MFCR2) && p->r2chan && ast_channel_state(ast) != AST_STATE_UP) {
7887 /* we don't need to do anything for this event for R2 signaling
7888 if the call is being setup */
7889 break;
7890 }
7891#endif
7892 if (p->inalarm) break;
7893 if ((p->radio || (p->oprmode < 0))) break;
7894 if (ioctl(p->subs[idx].dfd,DAHDI_DIALING,&x) == -1) {
7895 ast_debug(1, "DAHDI_DIALING ioctl failed on %s: %s\n",ast_channel_name(ast), strerror(errno));
7896 return NULL;
7897 }
7898 if (!x) { /* if not still dialing in driver */
7899 dahdi_ec_enable(p);
7900 if (p->echobreak) {
7901 dahdi_train_ec(p);
7902 ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
7903 p->dop.op = DAHDI_DIAL_OP_REPLACE;
7904 res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
7905 p->echobreak = 0;
7906 } else {
7907 p->dialing = 0;
7908 if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
7909 /* if thru with dialing after offhook */
7914 break;
7915 } else { /* if to state wait for offhook to dial rest */
7916 /* we now wait for off hook */
7918 }
7919 }
7921 if ((p->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
7922 ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n");
7923 } else if (p->confirmanswer || (!p->dialednone
7924 && ((mysig == SIG_EM) || (mysig == SIG_EM_E1)
7925 || (mysig == SIG_EMWINK) || (mysig == SIG_FEATD)
7926 || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF)
7927 || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA)
7928 || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB)
7929 || (mysig == SIG_SF) || (mysig == SIG_SFWINK)
7930 || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF)
7931 || (mysig == SIG_SF_FEATB)))) {
7933 } else if (!p->answeronpolarityswitch) {
7937 /* If aops=0 and hops=1, this is necessary */
7939 } else {
7940 /* Start clean, so we can catch the change to REV polarity when party answers */
7942 }
7943 }
7944 }
7945 }
7946 break;
7947 case DAHDI_EVENT_ALARM:
7948 switch (p->sig) {
7949#if defined(HAVE_PRI)
7952 break;
7953#endif /* defined(HAVE_PRI) */
7954#if defined(HAVE_SS7)
7955 case SIG_SS7:
7957 break;
7958#endif /* defined(HAVE_SS7) */
7959 default:
7960 p->inalarm = 1;
7961 break;
7962 }
7963 res = get_alarms(p);
7964 handle_alarms(p, res);
7965#ifdef HAVE_PRI
7966 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
7967 /* fall through intentionally */
7968 } else {
7969 break;
7970 }
7971#endif
7972#if defined(HAVE_SS7)
7973 if (p->sig == SIG_SS7)
7974 break;
7975#endif /* defined(HAVE_SS7) */
7976#ifdef HAVE_OPENR2
7977 if (p->sig == SIG_MFCR2)
7978 break;
7979#endif
7980 case DAHDI_EVENT_ONHOOK:
7981 if (p->radio) {
7984 break;
7985 }
7986 if (p->oprmode < 0)
7987 {
7988 if (p->oprmode != -1) { /* Operator flash recall */
7989 ast_verb(4, "Operator mode enabled on channel %d, holding line for channel %d\n", p->channel, p->oprpeer->channel);
7990 break;
7991 }
7992 /* Otherwise, immediate recall */
7993 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
7994 {
7995 /* Make sure it starts ringing */
7996 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
7997 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RING);
7999 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
8000 ast_verb(4, "Operator recall, channel %d ringing back channel %d\n", p->oprpeer->channel, p->channel);
8001 }
8002 break;
8003 }
8004 switch (p->sig) {
8005 case SIG_FXOLS:
8006 case SIG_FXOGS:
8007 case SIG_FXOKS:
8008 /* Check for some special conditions regarding call waiting */
8009 if (idx == SUB_REAL) {
8010 /* The normal line was hung up */
8011 if (p->subs[SUB_CALLWAIT].owner) {
8012 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
8014 ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel);
8016#if 0
8017 p->subs[idx].needanswer = 0;
8018 p->subs[idx].needringing = 0;
8019#endif
8020 p->callwaitingrepeat = 0;
8021 p->cidcwexpire = 0;
8022 p->cid_suppress_expire = 0;
8023 p->owner = NULL;
8024 /* Don't start streaming audio yet if the incoming call isn't up yet */
8026 p->dialing = 1;
8028 } else if (p->subs[SUB_THREEWAY].owner) {
8029 unsigned int mssinceflash;
8030 /* Here we have to retain the lock on both the main channel, the 3-way channel, and
8031 the private structure -- not especially easy or clean */
8033 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
8034 DLA_UNLOCK(&p->lock);
8036 /* We can grab ast and p in that order, without worry. We should make sure
8037 nothing seriously bad has happened though like some sort of bizarre double
8038 masquerade! */
8039 DLA_LOCK(&p->lock);
8040 if (p->owner != ast) {
8041 ast_log(LOG_WARNING, "This isn't good...\n");
8042 return NULL;
8043 }
8044 }
8045 if (!p->subs[SUB_THREEWAY].owner) {
8046 ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
8047 return NULL;
8048 }
8049 mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
8050 ast_debug(1, "Last flash was %u ms ago\n", mssinceflash);
8051 if (mssinceflash < MIN_MS_SINCE_FLASH) {
8052 /* It hasn't been long enough since the last flashook. This is probably a bounce on
8053 hanging up. Hangup both channels now */
8054 if (p->subs[SUB_THREEWAY].owner)
8057 ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
8059 } else if ((ast_channel_pbx(ast)) || (ast_channel_state(ast) == AST_STATE_UP)) {
8060 if (p->transfer) {
8061 /* In any case this isn't a threeway call anymore */
8062 p->subs[SUB_REAL].inthreeway = 0;
8064 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
8065 if (!p->transfertobusy && ast_channel_state(ast) == AST_STATE_BUSY) {
8067 /* Swap subs and dis-own channel */
8069 p->owner = NULL;
8070 /* Ring the phone */
8072 } else if (!attempt_transfer(p)) {
8073 /*
8074 * Transfer successful. Don't actually hang up at this point.
8075 * Let our channel legs of the calls die off as the transfer
8076 * percolates through the core.
8077 */
8078 break;
8079 }
8080 } else {
8082 if (p->subs[SUB_THREEWAY].owner)
8084 }
8085 } else {
8087 /* Swap subs and dis-own channel */
8089 p->owner = NULL;
8090 /* Ring the phone */
8092 }
8093 }
8094 } else {
8095 ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", idx);
8096 }
8097 /* Fall through */
8098 default:
8100 return NULL;
8101 }
8102 break;
8103 case DAHDI_EVENT_RINGOFFHOOK:
8104 if (p->inalarm) break;
8105 if (p->oprmode < 0)
8106 {
8107 if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
8108 {
8109 /* Make sure it stops ringing */
8110 dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
8111 tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, -1);
8113 ast_debug(1, "Operator recall by channel %d for channel %d complete\n", p->oprpeer->channel, p->channel);
8114 }
8115 break;
8116 }
8117 if (p->radio)
8118 {
8121 break;
8122 }
8123 /* for E911, its supposed to wait for offhook then dial
8124 the second half of the dial string */
8125 if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast_channel_state(ast) == AST_STATE_DIALING_OFFHOOK)) {
8126 c = strchr(p->dialdest, '/');
8127 if (c)
8128 c++;
8129 else
8130 c = p->dialdest;
8131
8132 if (*c) {
8133 int numchars = snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
8134 if (numchars >= sizeof(p->dop.dialstr)) {
8135 ast_log(LOG_WARNING, "Dial string '%s' truncated\n", c);
8136 }
8137 } else {
8138 ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
8139 }
8140
8141 if (strlen(p->dop.dialstr) > 4) {
8142 memset(p->echorest, 'w', sizeof(p->echorest) - 1);
8143 strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
8144 p->echorest[sizeof(p->echorest) - 1] = '\0';
8145 p->echobreak = 1;
8146 p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
8147 } else
8148 p->echobreak = 0;
8149 if (dahdi_dial_str(p, p->dop.op, p->dop.dialstr)) {
8150 x = DAHDI_ONHOOK;
8151 ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
8152 return NULL;
8153 }
8154 p->dialing = 1;
8155 return &p->subs[idx].f;
8156 }
8157 switch (p->sig) {
8158 case SIG_FXOLS:
8159 case SIG_FXOGS:
8160 case SIG_FXOKS:
8161 switch (ast_channel_state(ast)) {
8162 case AST_STATE_RINGING:
8163 dahdi_ec_enable(p);
8164 dahdi_train_ec(p);
8167 /* Make sure it stops ringing */
8168 p->subs[SUB_REAL].needringing = 0;
8169 dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
8170 ast_debug(1, "channel %d answered\n", p->channel);
8171
8172 /* Cancel any running CallerID spill */
8173 ast_free(p->cidspill);
8174 p->cidspill = NULL;
8176
8177 p->dialing = 0;
8178 p->callwaitcas = 0;
8179 if (p->confirmanswer) {
8180 /* Ignore answer if "confirm answer" is enabled */
8181 p->subs[idx].f.frametype = AST_FRAME_NULL;
8182 p->subs[idx].f.subclass.integer = 0;
8183 } else if (!ast_strlen_zero(p->dop.dialstr)) {
8184 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
8185 res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
8186 if (res) {
8187 p->dop.dialstr[0] = '\0';
8188 return NULL;
8189 } else {
8190 ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
8191 p->subs[idx].f.frametype = AST_FRAME_NULL;
8192 p->subs[idx].f.subclass.integer = 0;
8193 p->dialing = 1;
8194 }
8195 p->dop.dialstr[0] = '\0';
8197 } else
8199 return &p->subs[idx].f;
8200 case AST_STATE_DOWN:
8202 ast_channel_rings_set(ast, 1);
8205 ast_debug(1, "channel %d picked up\n", p->channel);
8206 return &p->subs[idx].f;
8207 case AST_STATE_UP:
8208 /* Make sure it stops ringing */
8209 dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
8210 /* Okay -- probably call waiting*/
8212 p->subs[idx].needunhold = 1;
8213 break;
8214 case AST_STATE_RESERVED:
8215 /* Start up dialtone */
8216 if (has_voicemail(p))
8217 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
8218 else
8219 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
8220 break;
8221 default:
8222 ast_log(LOG_WARNING, "FXO phone off hook in weird state %u??\n", ast_channel_state(ast));
8223 }
8224 break;
8225 case SIG_FXSLS:
8226 case SIG_FXSGS:
8227 case SIG_FXSKS:
8228 if (ast_channel_state(ast) == AST_STATE_RING) {
8229 p->ringt = p->ringt_base;
8230 }
8231
8232 /* If we get a ring then we cannot be in
8233 * reversed polarity. So we reset to idle */
8234 ast_debug(1, "Setting IDLE polarity due "
8235 "to ring. Old polarity was %d\n",
8236 p->polarity);
8238
8239 /* Fall through */
8240 case SIG_EM:
8241 case SIG_EM_E1:
8242 case SIG_EMWINK:
8243 case SIG_FEATD:
8244 case SIG_FEATDMF:
8245 case SIG_FEATDMF_TA:
8246 case SIG_E911:
8247 case SIG_FGC_CAMA:
8248 case SIG_FGC_CAMAMF:
8249 case SIG_FEATB:
8250 case SIG_SF:
8251 case SIG_SFWINK:
8252 case SIG_SF_FEATD:
8253 case SIG_SF_FEATDMF:
8254 case SIG_SF_FEATB:
8258 ast_debug(1, "Ring detected\n");
8261 } else if (p->outgoing && ((ast_channel_state(ast) == AST_STATE_RINGING) || (ast_channel_state(ast) == AST_STATE_DIALING))) {
8262 ast_debug(1, "Line answered\n");
8263 if (p->confirmanswer) {
8264 p->subs[idx].f.frametype = AST_FRAME_NULL;
8265 p->subs[idx].f.subclass.integer = 0;
8266 } else {
8270 }
8271 } else if (ast_channel_state(ast) != AST_STATE_RING)
8272 ast_log(LOG_WARNING, "Ring/Off-hook in strange state %u on channel %d\n", ast_channel_state(ast), p->channel);
8273 break;
8274 default:
8275 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
8276 }
8277 break;
8278 case DAHDI_EVENT_RINGBEGIN:
8279 switch (p->sig) {
8280 case SIG_FXSLS:
8281 case SIG_FXSGS:
8282 case SIG_FXSKS:
8283 if (ast_channel_state(ast) == AST_STATE_RING) {
8284 p->ringt = p->ringt_base;
8285 }
8286 break;
8287 }
8288 break;
8289 case DAHDI_EVENT_RINGERON:
8290 break;
8291 case DAHDI_EVENT_NOALARM:
8292 switch (p->sig) {
8293#if defined(HAVE_PRI)
8296 break;
8297#endif /* defined(HAVE_PRI) */
8298#if defined(HAVE_SS7)
8299 case SIG_SS7:
8301 break;
8302#endif /* defined(HAVE_SS7) */
8303 default:
8304 p->inalarm = 0;
8305 break;
8306 }
8308 break;
8309 case DAHDI_EVENT_WINKFLASH:
8310 if (p->inalarm) break;
8311 if (p->radio) break;
8312 if (p->oprmode < 0) break;
8313 if (p->oprmode > 1)
8314 {
8315 struct dahdi_params par;
8316
8317 memset(&par, 0, sizeof(par));
8318 if (ioctl(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par) != -1)
8319 {
8320 if (!par.rxisoffhook)
8321 {
8322 /* Make sure it stops ringing */
8323 dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
8324 dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RING);
8325 save_conference(p);
8326 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
8327 ast_verb(4, "Operator flash recall, channel %d ringing back channel %d\n", p->oprpeer->channel, p->channel);
8328 }
8329 }
8330 break;
8331 }
8332 /* Remember last time we got a flash-hook */
8333 p->flashtime = ast_tvnow();
8334 switch (mysig) {
8335 case SIG_FXOLS:
8336 case SIG_FXOGS:
8337 case SIG_FXOKS:
8338 ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
8340
8341 /* Cancel any running CallerID spill */
8342 ast_free(p->cidspill);
8343 p->cidspill = NULL;
8345 p->callwaitcas = 0;
8346
8347 if (idx != SUB_REAL) {
8348 ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", idx, p->channel);
8349 goto winkflashdone;
8350 }
8351
8352 if (p->subs[SUB_CALLWAIT].owner) {
8353 /* Swap to call-wait */
8355 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
8356 p->owner = p->subs[SUB_REAL].owner;
8357 ast_debug(1, "Making %s the new owner\n", ast_channel_name(p->owner));
8360 p->subs[SUB_REAL].needanswer = 1;
8361 }
8362 p->callwaitingrepeat = 0;
8363 p->cidcwexpire = 0;
8364 p->cid_suppress_expire = 0;
8365 /* Start music on hold if appropriate */
8366 if (!p->subs[SUB_CALLWAIT].inthreeway) {
8368 }
8369 p->subs[SUB_CALLWAIT].needhold = 1;
8371 p->subs[SUB_REAL].needunhold = 1;
8372 } else if (!p->subs[SUB_THREEWAY].owner) {
8373 if (!p->threewaycalling) {
8374 /* Just send a flash if no 3-way calling */
8375 p->subs[SUB_REAL].needflash = 1;
8376 goto winkflashdone;
8377 } else if (!check_for_conference(p)) {
8378 ast_callid callid = 0;
8379 int callid_created;
8380 char cid_num[256];
8381 char cid_name[256];
8382
8383 cid_num[0] = 0;
8384 cid_name[0] = 0;
8385 if (p->dahditrcallerid && p->owner) {
8389 sizeof(cid_num));
8390 }
8394 sizeof(cid_name));
8395 }
8396 }
8397 /* XXX This section needs much more error checking!!! XXX */
8398 /* Start a 3-way call if feasible */
8399 if (!((ast_channel_pbx(ast)) ||
8400 (ast_channel_state(ast) == AST_STATE_UP) ||
8401 (ast_channel_state(ast) == AST_STATE_RING))) {
8402 ast_debug(1, "Flash when call not up or ringing\n");
8403 goto winkflashdone;
8404 }
8405 if (alloc_sub(p, SUB_THREEWAY)) {
8406 ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
8407 goto winkflashdone;
8408 }
8409 callid_created = ast_callid_threadstorage_auto(&callid);
8410 /*
8411 * Make new channel
8412 *
8413 * We cannot hold the p or ast locks while creating a new
8414 * channel.
8415 */
8417 ast_channel_unlock(ast);
8418 chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, NULL, NULL, callid);
8419 ast_channel_lock(ast);
8420 ast_mutex_lock(&p->lock);
8421 if (p->dahditrcallerid) {
8422 if (!p->origcid_num)
8424 if (!p->origcid_name)
8426 ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
8427 ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
8428 }
8429 /* Swap things around between the three-way and real call */
8431 /* Disable echo canceller for better dialing */
8433 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALRECALL);
8434 if (res)
8435 ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
8436 p->owner = chan;
8437 if (!chan) {
8438 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
8439 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
8440 ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
8441 res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
8442 dahdi_ec_enable(p);
8443 ast_hangup(chan);
8444 } else {
8445 ast_verb(3, "Started three way call on channel %d\n", p->channel);
8446
8447 /* Start music on hold */
8449 p->subs[SUB_THREEWAY].needhold = 1;
8450 }
8451 ast_callid_threadstorage_auto_clean(callid, callid_created);
8452 }
8453 } else {
8454 /* Already have a 3 way call */
8455 if (p->subs[SUB_THREEWAY].inthreeway) {
8456 /* Call is already up, drop the last person */
8457 ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel);
8458 /* If the primary call isn't answered yet, use it */
8460 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
8462 p->owner = p->subs[SUB_REAL].owner;
8463 }
8464 /* Drop the last call and stop the conference */
8465 ast_verb(3, "Dropping three-way call on %s\n", ast_channel_name(p->subs[SUB_THREEWAY].owner));
8467 p->subs[SUB_REAL].inthreeway = 0;
8469 } else {
8470 /* Lets see what we're up to */
8471 if (((ast_channel_pbx(ast)) || (ast_channel_state(ast) == AST_STATE_UP)) &&
8473 int otherindex = SUB_THREEWAY;
8474
8475 ast_verb(3, "Building conference call with %s and %s\n",
8478 /* Put them in the threeway, and flip */
8480 p->subs[SUB_REAL].inthreeway = 1;
8481 if (ast_channel_state(ast) == AST_STATE_UP) {
8483 otherindex = SUB_REAL;
8484 }
8485 if (p->subs[otherindex].owner) {
8486 ast_queue_unhold(p->subs[otherindex].owner);
8487 }
8488 p->subs[otherindex].needunhold = 1;
8489 p->owner = p->subs[SUB_REAL].owner;
8490 } else {
8491 ast_verb(3, "Dumping incomplete call on %s\n", ast_channel_name(p->subs[SUB_THREEWAY].owner));
8494 p->owner = p->subs[SUB_REAL].owner;
8495 if (p->subs[SUB_REAL].owner) {
8497 }
8498 p->subs[SUB_REAL].needunhold = 1;
8499 dahdi_ec_enable(p);
8500 }
8501 }
8502 }
8503winkflashdone:
8505 break;
8506 case SIG_EM:
8507 case SIG_EM_E1:
8508 case SIG_FEATD:
8509 case SIG_SF:
8510 case SIG_SFWINK:
8511 case SIG_SF_FEATD:
8512 case SIG_FXSLS:
8513 case SIG_FXSGS:
8514 if (p->dialing)
8515 ast_debug(1, "Ignoring wink on channel %d\n", p->channel);
8516 else
8517 ast_debug(1, "Got wink in weird state %u on channel %d\n", ast_channel_state(ast), p->channel);
8518 break;
8519 case SIG_FEATDMF_TA:
8520 switch (p->whichwink) {
8521 case 0:
8522 ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", ast_channel_caller(p->owner)->ani2,
8525 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#",
8529 break;
8530 case 1:
8531 ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
8532 break;
8533 case 2:
8534 ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
8535 return NULL;
8536 }
8537 p->whichwink++;
8538 /* Fall through */
8539 case SIG_FEATDMF:
8540 case SIG_E911:
8541 case SIG_FGC_CAMAMF:
8542 case SIG_FGC_CAMA:
8543 case SIG_FEATB:
8544 case SIG_SF_FEATDMF:
8545 case SIG_SF_FEATB:
8546 case SIG_EMWINK:
8547 /* FGD MF and EMWINK *Must* wait for wink */
8548 if (!ast_strlen_zero(p->dop.dialstr)) {
8549 res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
8550 if (res) {
8551 p->dop.dialstr[0] = '\0';
8552 return NULL;
8553 } else
8554 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
8555 }
8556 p->dop.dialstr[0] = '\0';
8557 break;
8558 default:
8559 ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
8560 }
8561 break;
8562 case DAHDI_EVENT_HOOKCOMPLETE:
8563 if (p->inalarm) break;
8564 if ((p->radio || (p->oprmode < 0))) break;
8565 if (p->waitingfordt.tv_sec) break;
8566 switch (mysig) {
8567 case SIG_FXSLS: /* only interesting for FXS */
8568 case SIG_FXSGS:
8569 case SIG_FXSKS:
8570 case SIG_EM:
8571 case SIG_EM_E1:
8572 case SIG_EMWINK:
8573 case SIG_FEATD:
8574 case SIG_SF:
8575 case SIG_SFWINK:
8576 case SIG_SF_FEATD:
8577 if (!ast_strlen_zero(p->dop.dialstr)) {
8578 res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
8579 if (res) {
8580 p->dop.dialstr[0] = '\0';
8581 return NULL;
8582 } else
8583 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
8584 }
8585 p->dop.dialstr[0] = '\0';
8586 p->dop.op = DAHDI_DIAL_OP_REPLACE;
8587 break;
8588 case SIG_FEATDMF:
8589 case SIG_FEATDMF_TA:
8590 case SIG_E911:
8591 case SIG_FGC_CAMA:
8592 case SIG_FGC_CAMAMF:
8593 case SIG_FEATB:
8594 case SIG_SF_FEATDMF:
8595 case SIG_SF_FEATB:
8596 ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
8597 break;
8598 default:
8599 break;
8600 }
8601 break;
8602 case DAHDI_EVENT_POLARITY:
8603 /*
8604 * If we get a Polarity Switch event, check to see
8605 * if we should change the polarity state and
8606 * mark the channel as UP or if this is an indication
8607 * of remote end disconnect.
8608 */
8609 if (p->polarity == POLARITY_IDLE) {
8611 if (p->answeronpolarityswitch &&
8614 ast_debug(1, "Answering on polarity switch!\n");
8616 if (p->hanguponpolarityswitch) {
8618 }
8619 } else
8620 ast_debug(1, "Ignore switch to REVERSED Polarity on channel %d, state %u\n", p->channel, ast_channel_state(ast));
8621 }
8622 /* Removed else statement from here as it was preventing hangups from ever happening*/
8623 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
8624 if (p->hanguponpolarityswitch &&
8625 (p->polarityonanswerdelay > 0) &&
8626 (p->polarity == POLARITY_REV) &&
8628 /* Added log_debug information below to provide a better indication of what is going on */
8629 ast_debug(1, "Polarity Reversal event occured - DEBUG 1: channel %d, state %u, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %" PRIi64 "\n", p->channel, ast_channel_state(ast), p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
8630
8632 ast_debug(1, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
8635 } else
8636 ast_debug(1, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %u\n", p->channel, ast_channel_state(ast));
8637
8638 } else {
8640 ast_debug(1, "Ignoring Polarity switch to IDLE on channel %d, state %u\n", p->channel, ast_channel_state(ast));
8641 }
8642 /* Added more log_debug information below to provide a better indication of what is going on */
8643 ast_debug(1, "Polarity Reversal event occured - DEBUG 2: channel %d, state %u, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %" PRIi64 "\n", p->channel, ast_channel_state(ast), p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
8644 break;
8645 default:
8646 ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel);
8647 }
8648 return &p->subs[idx].f;
8649}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:109
static int restore_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5262
static void dahdi_train_ec(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4953
static int attempt_transfer(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7508
static void * analog_ss_thread(void *data)
Definition: chan_dahdi.c:9889
static void handle_clear_alarms(struct dahdi_pvt *p)
Definition: chan_dahdi.c:3796
static int check_for_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7541
static int has_voicemail(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5293
#define CALLPROGRESS_PROGRESS
Definition: chan_dahdi.c:679
static void handle_alarms(struct dahdi_pvt *p, int alms)
Definition: chan_dahdi.c:7727
static void dahdi_handle_dtmf(struct ast_channel *ast, int idx, struct ast_frame **dest)
Definition: chan_dahdi.c:7594
static struct ast_channel * dahdi_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)
Definition: chan_dahdi.c:9530
#define MIN_MS_SINCE_FLASH
Definition: chan_dahdi.c:803
#define ast_channel_trylock(chan)
Definition: channel.h:2924
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1191
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
@ AST_SOFTHANGUP_EXPLICIT
Definition: channel.h:1148
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
@ AST_STATE_DIALING_OFFHOOK
Definition: channelstate.h:44
@ AST_CONTROL_RING
@ AST_CONTROL_OFFHOOK
@ AST_CONTROL_RADIO_UNKEY
@ AST_CONTROL_RADIO_KEY
struct ast_frame ast_null_frame
Definition: main/frame.c:79
void ast_callid_threadstorage_auto_clean(ast_callid callid, int callid_created)
Use in conjunction with ast_callid_threadstorage_auto. Cleans up the references and if the callid was...
Definition: logger.c:2378
unsigned int ast_callid
int ast_callid_threadstorage_auto(ast_callid *callid)
Checks thread storage for a callid and stores a reference if it exists. If not, then a new one will b...
Definition: logger.c:2356
#define DLA_LOCK(lock)
Definition: lock.h:492
#define DLA_UNLOCK(lock)
Definition: lock.h:490
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
Definition: lock.h:474
void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm)
@ SIG_PRI_CALL_LEVEL_PROCEEDING
Definition: sig_pri.h:143
#define DAHDI_OVERLAPDIAL_INCOMING
Definition: sig_pri.h:253
void sig_pri_dial_complete(struct sig_pri_chan *pvt, struct ast_channel *ast)
void sig_ss7_set_alarm(struct sig_ss7_chan *p, int in_alarm)
struct ast_party_id id
Caller party ID.
Definition: channel.h:420
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:433
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:427
struct ast_party_name name
Subscriber name.
Definition: channel.h:340
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:279
char * str
Subscriber name (Malloced)
Definition: channel.h:264
unsigned int dahditrcallerid
TRUE if we should use the callerid from incoming call on dahdi transfer.
Definition: chan_dahdi.h:408
int polarityonanswerdelay
Minimal time period (ms) between the answer polarity switch and hangup polarity switch.
Definition: chan_dahdi.h:727
struct dahdi_pvt * oprpeer
Definition: chan_dahdi.h:152
char * origcid_name
Definition: chan_dahdi.h:539
int whichwink
Definition: chan_dahdi.h:697
char * origcid_num
Definition: chan_dahdi.h:538
unsigned int answeronpolarityswitch
TRUE if we can use a polarity reversal to mark when an outgoing call is answered by the remote party.
Definition: chan_dahdi.h:184
unsigned int threewaycalling
TRUE if three way calling is enabled.
Definition: chan_dahdi.h:368
int echotraining
Echo training time. 0 = disabled.
Definition: chan_dahdi.h:634
struct timeval polaritydelaytv
Start delay time if polarityonanswerdelay is nonzero.
Definition: chan_dahdi.h:729
unsigned int echobreak
XXX BOOLEAN Purpose???
Definition: chan_dahdi.h:264
char echorest[20]
Filled with 'w'. XXX Purpose??
Definition: chan_dahdi.h:636
char finaldial[64]
Second part of SIG_FEATDMF_TA wink operation.
Definition: chan_dahdi.h:699
unsigned int transfertobusy
TRUE if allowed to flash-transfer to busy channels.
Definition: chan_dahdi.h:413
unsigned int pulsedial
TRUE if a pulsed digit was detected. (Pulse dial phone detected)
Definition: chan_dahdi.h:356
char mohsuggest[MAX_MUSICCLASS]
Suggested music-on-hold class for peer channel to use for calls.
Definition: chan_dahdi.h:517
unsigned int needringing
Definition: chan_dahdi.h:83
unsigned int needhold
Definition: chan_dahdi.h:88
unsigned int needflash
Definition: chan_dahdi.h:87
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:588

References alloc_sub(), analog_ss_thread(), ast_party_caller::ani, ast_party_caller::ani2, dahdi_pvt::answeronpolarityswitch, ast_callid_threadstorage_auto(), ast_callid_threadstorage_auto_clean(), AST_CAUSE_NO_ANSWER, ast_channel_caller(), ast_channel_lock, ast_channel_name(), ast_channel_pbx(), ast_channel_rings_set(), ast_channel_softhangup_internal_flag_add(), ast_channel_tech_pvt(), ast_channel_trylock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_OFFHOOK, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, ast_copy_string(), ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_free, ast_hangup(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_null_frame, ast_pthread_create_detached, ast_queue_hangup_with_cause(), ast_queue_hold(), ast_queue_unhold(), ast_setstate(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_SOFTHANGUP_EXPLICIT, AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdup, ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, attempt_transfer(), c, dahdi_pvt::callprogress, CALLPROGRESS_PROGRESS, dahdi_pvt::callwaitcas, dahdi_pvt::callwaitingrepeat, CANPROGRESSDETECT, dahdi_pvt::channel, CHANNEL_DEADLOCK_AVOIDANCE, check_for_conference(), dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cidcwexpire, dahdi_pvt::cidspill, dahdi_pvt::confirmanswer, dahdi_conf_update(), dahdi_confmute(), dahdi_dial_str(), dahdi_ec_disable(), dahdi_ec_enable(), dahdi_get_event(), dahdi_get_index, dahdi_handle_dtmf(), dahdi_new(), DAHDI_OVERLAPDIAL_INCOMING, dahdi_ring_phone(), dahdi_set_hook(), dahdi_sig_pri_lib_handles(), dahdi_train_ec(), dahdi_pvt::dahditrcallerid, ast_frame::data, ast_frame::datalen, dahdi_subchannel::dfd, dahdi_pvt::dialdest, dahdi_pvt::dialednone, dahdi_pvt::dialing, DLA_LOCK, DLA_UNLOCK, dahdi_pvt::dop, dahdi_pvt::dsp, dahdi_pvt::echobreak, dahdi_pvt::echocanon, dahdi_pvt::echorest, dahdi_pvt::echotraining, errno, event2str(), dahdi_subchannel::f, dahdi_pvt::fake_event, dahdi_pvt::finaldial, dahdi_pvt::flashtime, ast_frame::frametype, get_alarms(), handle_alarms(), handle_clear_alarms(), dahdi_pvt::hanguponpolarityswitch, has_voicemail(), ast_party_caller::id, dahdi_pvt::inalarm, ast_frame_subclass::integer, dahdi_subchannel::inthreeway, dahdi_pvt::lock, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, MIN_MS_SINCE_FLASH, dahdi_pvt::mohsuggest, ast_party_id::name, dahdi_subchannel::needanswer, dahdi_subchannel::needflash, dahdi_subchannel::needhold, dahdi_subchannel::needringing, dahdi_subchannel::needunhold, NULL, ast_party_id::number, ast_frame::offset, dahdi_pvt::oprmode, dahdi_pvt::oprpeer, dahdi_pvt::origcid_name, dahdi_pvt::origcid_num, dahdi_pvt::outgoing, dahdi_pvt::outsigmod, dahdi_subchannel::owner, dahdi_pvt::owner, dahdi_pvt::polarity, POLARITY_IDLE, POLARITY_REV, dahdi_pvt::polaritydelaytv, dahdi_pvt::polarityonanswerdelay, ast_frame::ptr, dahdi_pvt::pulsedial, dahdi_pvt::radio, restore_conference(), dahdi_pvt::ringt, dahdi_pvt::ringt_base, S_COR, ast_frame::samples, save_conference(), dahdi_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_MFCR2, SIG_PRI_CALL_LEVEL_PROCEEDING, sig_pri_chan_alarm_notify(), sig_pri_dial_complete(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, SIG_SS7, sig_ss7_set_alarm(), ast_frame::src, ast_party_name::str, ast_party_number::str, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, ast_frame::subclass, dahdi_pvt::subs, swap_subs(), dahdi_pvt::threewaycalling, dahdi_pvt::transfer, dahdi_pvt::transfertobusy, unalloc_sub(), ast_party_name::valid, ast_party_number::valid, dahdi_pvt::waitingfordt, and dahdi_pvt::whichwink.

Referenced by __dahdi_exception().

◆ dahdi_hangup()

static int dahdi_hangup ( struct ast_channel ast)
static

Definition at line 6250 of file chan_dahdi.c.

6251{
6252 int res = 0;
6253 int idx,x;
6254 int law;
6255 /*static int restore_gains(struct dahdi_pvt *p);*/
6256 struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
6257 struct dahdi_params par;
6258
6259 ast_debug(1, "dahdi_hangup(%s)\n", ast_channel_name(ast));
6260 if (!ast_channel_tech_pvt(ast)) {
6261 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
6262 return 0;
6263 }
6264
6265 ast_mutex_lock(&p->lock);
6266 p->exten[0] = '\0';
6267 /* Always use sig_analog hangup handling for operator mode */
6268 if (dahdi_analog_lib_handles(p->sig, p->radio, 0)) {
6269 p->oprmode = 0;
6270 dahdi_confmute(p, 0);
6271 restore_gains(p);
6272 p->ignoredtmf = 0;
6273 p->waitingfordt.tv_sec = 0;
6274
6275 res = analog_hangup(p->sig_pvt, ast);
6276 revert_fax_buffers(p, ast);
6277
6278 goto hangup_out;
6279 } else {
6280 p->cid_num[0] = '\0';
6281 p->cid_name[0] = '\0';
6282 p->cid_subaddr[0] = '\0';
6283 }
6284
6285#if defined(HAVE_PRI)
6287 x = 1;
6288 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
6289
6290 dahdi_confmute(p, 0);
6291 p->muting = 0;
6292 restore_gains(p);
6293 if (p->dsp) {
6294 ast_dsp_free(p->dsp);
6295 p->dsp = NULL;
6296 }
6297 p->ignoredtmf = 0;
6298
6299 /* Real channel, do some fixup */
6300 p->subs[SUB_REAL].owner = NULL;
6301 p->subs[SUB_REAL].needbusy = 0;
6303
6304 p->owner = NULL;
6305 p->cid_tag[0] = '\0';
6306 p->ringt = 0;/* Probably not used in this mode. Reset anyway. */
6307 p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */
6308 p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */
6309 p->outgoing = 0;
6310 p->digital = 0;
6311 p->faxhandled = 0;
6312 p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */
6313
6314 revert_fax_buffers(p, ast);
6315
6316 p->law = p->law_default;
6317 law = p->law_default;
6318 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
6319 if (res < 0) {
6320 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n",
6321 p->channel, strerror(errno));
6322 }
6323
6324 sig_pri_hangup(p->sig_pvt, ast);
6325
6326 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
6328
6329 x = 0;
6330 ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0);
6331 p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */
6332
6333 p->rdnis[0] = '\0';
6335 reset_conf(p);
6336
6337 /* Restore data mode */
6338 x = 0;
6339 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
6340
6341 if (num_restart_pending == 0) {
6343 }
6344 goto hangup_out;
6345 }
6346#endif /* defined(HAVE_PRI) */
6347
6348#if defined(HAVE_SS7)
6349 if (p->sig == SIG_SS7) {
6350 x = 1;
6351 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
6352
6353 dahdi_confmute(p, 0);
6354 p->muting = 0;
6355 restore_gains(p);
6356 if (p->dsp) {
6357 ast_dsp_free(p->dsp);
6358 p->dsp = NULL;
6359 }
6360 p->ignoredtmf = 0;
6361
6362 /* Real channel, do some fixup */
6363 p->subs[SUB_REAL].owner = NULL;
6364 p->subs[SUB_REAL].needbusy = 0;
6366
6367 p->owner = NULL;
6368 p->ringt = 0;/* Probably not used in this mode. Reset anyway. */
6369 p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */
6370 p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */
6371 p->outgoing = 0;
6372 p->digital = 0;
6373 p->faxhandled = 0;
6374 p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */
6375
6376 revert_fax_buffers(p, ast);
6377
6378 p->law = p->law_default;
6379 law = p->law_default;
6380 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
6381 if (res < 0) {
6382 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n",
6383 p->channel, strerror(errno));
6384 }
6385
6386 sig_ss7_hangup(p->sig_pvt, ast);
6387
6388 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
6390
6391 x = 0;
6392 ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0);
6393 p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */
6394
6396 reset_conf(p);
6397
6398 /* Restore data mode */
6399 x = 0;
6400 ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
6401
6402 if (num_restart_pending == 0) {
6404 }
6405 goto hangup_out;
6406 }
6407#endif /* defined(HAVE_SS7) */
6408
6409 idx = dahdi_get_index(ast, p, 1);
6410
6411 dahdi_confmute(p, 0);
6412 p->muting = 0;
6413 restore_gains(p);
6414 if (p->origcid_num) {
6415 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
6417 p->origcid_num = NULL;
6418 }
6419 if (p->origcid_name) {
6420 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
6422 p->origcid_name = NULL;
6423 }
6424 if (p->dsp)
6426
6427 ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
6428 p->channel, idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
6429 p->ignoredtmf = 0;
6430
6431 if (idx > -1) {
6432 /* Real channel, do some fixup */
6433 p->subs[idx].owner = NULL;
6434 p->subs[idx].needanswer = 0;
6435 p->subs[idx].needflash = 0;
6436 p->subs[idx].needringing = 0;
6437 p->subs[idx].needbusy = 0;
6438 p->subs[idx].needcongestion = 0;
6439 p->subs[idx].linear = 0;
6441 dahdi_setlinear(p->subs[idx].dfd, 0);
6442 if (idx == SUB_REAL) {
6443 if ((p->subs[SUB_CALLWAIT].dfd > -1) && (p->subs[SUB_THREEWAY].dfd > -1)) {
6444 ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n");
6445 if (p->subs[SUB_CALLWAIT].inthreeway) {
6446 /* We had flipped over to answer a callwait and now it's gone */
6447 ast_debug(1, "We were flipped over to the callwait, moving back and not owning.\n");
6448 /* Move to the call-wait, but un-own us until they flip back. */
6451 p->owner = NULL;
6452 } else {
6453 /* The three way hung up, but we still have a call wait */
6454 ast_debug(1, "We were in the threeway and have a callwait still. Ditching the threeway.\n");
6457 if (p->subs[SUB_REAL].inthreeway) {
6458 /* This was part of a three way call. Immediately make way for
6459 another call */
6460 ast_debug(1, "Call was complete, setting owner to former third call\n");
6461 p->owner = p->subs[SUB_REAL].owner;
6462 } else {
6463 /* This call hasn't been completed yet... Set owner to NULL */
6464 ast_debug(1, "Call was incomplete, setting owner to NULL\n");
6465 p->owner = NULL;
6466 }
6467 p->subs[SUB_REAL].inthreeway = 0;
6468 }
6469 } else if (p->subs[SUB_CALLWAIT].dfd > -1) {
6470 /* Move to the call-wait and switch back to them. */
6473 p->owner = p->subs[SUB_REAL].owner;
6475 p->subs[SUB_REAL].needanswer = 1;
6477 } else if (p->subs[SUB_THREEWAY].dfd > -1) {
6480 if (p->subs[SUB_REAL].inthreeway) {
6481 /* This was part of a three way call. Immediately make way for
6482 another call */
6483 ast_debug(1, "Call was complete, setting owner to former third call\n");
6484 p->owner = p->subs[SUB_REAL].owner;
6485 } else {
6486 /* This call hasn't been completed yet... Set owner to NULL */
6487 ast_debug(1, "Call was incomplete, setting owner to NULL\n");
6488 p->owner = NULL;
6489 }
6490 p->subs[SUB_REAL].inthreeway = 0;
6491 }
6492 } else if (idx == SUB_CALLWAIT) {
6493 /* Ditch the holding callwait call, and immediately make it availabe */
6494 if (p->subs[SUB_CALLWAIT].inthreeway) {
6495 /* This is actually part of a three way, placed on hold. Place the third part
6496 on music on hold now */
6497 if (p->subs[SUB_THREEWAY].owner) {
6499 }
6501 /* Make it the call wait now */
6504 } else
6506 } else if (idx == SUB_THREEWAY) {
6507 if (p->subs[SUB_CALLWAIT].inthreeway) {
6508 /* The other party of the three way call is currently in a call-wait state.
6509 Start music on hold for them, and take the main guy out of the third call */
6510 if (p->subs[SUB_CALLWAIT].owner) {
6512 }
6514 }
6515 p->subs[SUB_REAL].inthreeway = 0;
6516 /* If this was part of a three way call index, let us make
6517 another three way call */
6519 } else {
6520 /* This wasn't any sort of call, but how are we an index? */
6521 ast_log(LOG_WARNING, "Index found but not any type of call?\n");
6522 }
6523 }
6524
6525 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
6526 p->owner = NULL;
6527 p->ringt = 0;
6528 p->distinctivering = 0;
6529 p->confirmanswer = 0;
6530 p->outgoing = 0;
6531 p->digital = 0;
6532 p->faxhandled = 0;
6533 p->pulsedial = 0;
6534 if (p->dsp) {
6535 ast_dsp_free(p->dsp);
6536 p->dsp = NULL;
6537 }
6538
6539 revert_fax_buffers(p, ast);
6540
6541 p->law = p->law_default;
6542 law = p->law_default;
6543 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
6544 if (res < 0)
6545 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
6546 /* Perform low level hangup if no owner left */
6547#ifdef HAVE_OPENR2
6548 if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) {
6549 ast_debug(1, "disconnecting MFC/R2 call on chan %d\n", p->channel);
6550 /* If it's an incoming call, check the mfcr2_forced_release setting */
6551 if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) {
6552 dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE);
6553 } else {
6554 const char *r2causestr = pbx_builtin_getvar_helper(ast, "MFCR2_CAUSE");
6555 int r2cause_user = r2causestr ? atoi(r2causestr) : 0;
6556 openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user)
6557 : dahdi_ast_cause_to_r2_cause(ast_channel_hangupcause(ast));
6558 dahdi_r2_disconnect_call(p, r2cause);
6559 }
6560 } else if (p->mfcr2call) {
6561 ast_debug(1, "Clearing call request on channel %d\n", p->channel);
6562 /* since ast_request() was called but not ast_call() we have not yet dialed
6563 and the openr2 stack will not call on_call_end callback, we need to unset
6564 the mfcr2call flag and bump the monitor count so the monitor thread can take
6565 care of this channel events from now on */
6566 p->mfcr2call = 0;
6567 }
6568#endif
6569 switch (p->sig) {
6570 case SIG_SS7:
6571 case SIG_MFCR2:
6573 case 0:
6574 break;
6575 default:
6576 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
6577 break;
6578 }
6579 if (res < 0) {
6580 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast_channel_name(ast));
6581 }
6582 switch (p->sig) {
6583 case SIG_FXOGS:
6584 case SIG_FXOLS:
6585 case SIG_FXOKS:
6586 memset(&par, 0, sizeof(par));
6587 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
6588 if (!res) {
6589 struct analog_pvt *analog_p = p->sig_pvt;
6590#if 0
6591 ast_debug(1, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
6592#endif
6593 /* If they're off hook, try playing congestion */
6594 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
6595 tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
6596 else
6597 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
6598 analog_p->fxsoffhookstate = par.rxisoffhook;
6599 }
6600 break;
6601 case SIG_FXSGS:
6602 case SIG_FXSLS:
6603 case SIG_FXSKS:
6604 /* Make sure we're not made available for at least two seconds assuming
6605 we were actually used for an inbound or outbound call. */
6607 time(&p->guardtime);
6608 p->guardtime += 2;
6609 }
6610 break;
6611 default:
6612 tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
6613 break;
6614 }
6615 if (p->sig)
6617 x = 0;
6618 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
6619 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
6620 p->didtdd = 0;
6621 p->callwaitcas = 0;
6624 p->waitingfordt.tv_sec = 0;
6625 p->dialing = 0;
6626 p->rdnis[0] = '\0';
6628 reset_conf(p);
6629 /* Restore data mode */
6630 switch (p->sig) {
6632 case SIG_SS7:
6633 x = 0;
6634 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
6635 break;
6636 default:
6637 break;
6638 }
6639 if (num_restart_pending == 0)
6641 }
6642
6643 p->callwaitingrepeat = 0;
6644 p->cidcwexpire = 0;
6645 p->cid_suppress_expire = 0;
6646 p->oprmode = 0;
6647hangup_out:
6649 ast_free(p->cidspill);
6650 p->cidspill = NULL;
6651
6652 if (p->reoriginate && p->sig == SIG_FXOKS && dahdi_analog_lib_handles(p->sig, p->radio, 0)) {
6653 /* Automatic reorigination: if all calls towards a user have hung up,
6654 * give dial tone again, so user doesn't need to cycle the hook state manually. */
6655 if (my_is_off_hook(p) && !p->owner) {
6656 /* 2 important criteria: channel must be off-hook, with no calls remaining (no owner) */
6657 ast_debug(1, "Queuing reorigination for channel %d\n", p->channel);
6658 my_play_tone(p, SUB_REAL, -1); /* Stop any congestion tone that may be present. */
6659 /* Must wait for the loop disconnect to end.
6660 * Sadly, these definitions are in dahdi/kernel.h, not dahdi/user.h
6661 * Calling usleep on an active DAHDI channel is a no-no, but this is okay.
6662 */
6663 usleep(800000); /* DAHDI_KEWLTIME + DAHDI_AFTERKEWLTIME */
6664 /* If the line is still off-hook and ownerless, actually queue the reorigination.
6665 * do_monitor will actually go ahead and do it. */
6666 if (!p->owner && my_is_off_hook(p)) {
6667 p->doreoriginate = 1; /* Tell do_monitor to reoriginate this channel */
6668 /* Note, my_off_hook will fail if called before the loop disconnect has finished
6669 * (important for FXOKS signaled channels). This is because DAHDI will reject
6670 * DAHDI_OFFHOOK while the channel is in TXSTATE_KEWL or TXSTATE_AFTERKEWL,
6671 * so we have to wait for that to finish (see comment above).
6672 * do_monitor itself cannot block, so make the blocking usleep call
6673 * here in the channel thread instead.
6674 */
6675 my_off_hook(p); /* Now, go ahead and take the channel back off hook (sig_analog put it on hook) */
6676 } else {
6677 ast_debug(1, "Channel %d is no longer eligible for reorigination (went back on hook or became in use)\n", p->channel);
6678 }
6679 }
6680 }
6681
6683 ast_verb(3, "Hungup '%s'\n", ast_channel_name(ast));
6684
6686 if (p->restartpending) {
6688 }
6689
6690 if (p->destroy) {
6691 destroy_channel(p, 0);
6692 }
6694
6696 return 0;
6697}
static int reset_conf(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4829
static int num_restart_pending
Definition: chan_dahdi.c:766
static int my_is_off_hook(void *pvt)
Definition: chan_dahdi.c:2724
static int restart_monitor(void)
Definition: chan_dahdi.c:12168
static int my_play_tone(void *pvt, enum analog_sub sub, enum analog_tone tone)
Definition: chan_dahdi.c:2596
static int my_off_hook(void *pvt)
Definition: chan_dahdi.c:2783
static int revert_fax_buffers(struct dahdi_pvt *p, struct ast_channel *ast)
Definition: chan_dahdi.c:6228
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
int ast_channel_hangupcause(const struct ast_channel *chan)
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Definition: channel.c:7422
#define AST_OPTION_TONE_VERIFY
#define AST_OPTION_TDD
#define AST_OPTION_AUDIO_MODE
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
Definition: sig_analog.c:1277
int sig_pri_hangup(struct sig_pri_chan *p, struct ast_channel *ast)
int sig_ss7_hangup(struct sig_ss7_chan *p, struct ast_channel *ast)
int fxsoffhookstate
Definition: sig_analog.h:282
unsigned int permcallwaiting
TRUE if busy extensions will hear the call-waiting tone and can use hook-flash to switch between call...
Definition: chan_dahdi.h:334
unsigned int doreoriginate
Internal flag for if we should actually process a reorigination.
Definition: chan_dahdi.h:293
unsigned int permhidecallerid
TRUE if the outgoing caller ID is blocked/restricted/hidden.
Definition: chan_dahdi.h:339
unsigned int restartpending
Definition: chan_dahdi.h:357
int distinctivering
Definition: chan_dahdi.h:719
time_t guardtime
Definition: chan_dahdi.h:587
char rdnis[AST_MAX_EXTENSION]
Redirecting Directory Number Information Service (RDNIS) number.
Definition: chan_dahdi.h:545
int law_default
Default call PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:554
unsigned int didtdd
Definition: chan_dahdi.h:251
unsigned int destroy
TRUE if the channel is to be destroyed on hangup. (Used by pseudo channels.)
Definition: chan_dahdi.h:250
unsigned int reoriginate
TRUE if FXS (FXO-signalled) channel should reoriginate for user to make a new call.
Definition: chan_dahdi.h:289
int muting
TRUE if confrence is muted.
Definition: chan_dahdi.h:763
char cid_tag[AST_MAX_EXTENSION]
Caller ID tag from incoming call.
Definition: chan_dahdi.h:531
unsigned int needcongestion
Definition: chan_dahdi.h:85

References analog_hangup(), ast_channel_hangupcause(), ast_channel_name(), ast_channel_setoption(), ast_channel_tech_pvt(), ast_channel_tech_pvt_set(), ast_copy_string(), ast_debug, ast_dsp_free(), ast_dsp_set_digitmode(), ast_free, ast_log, ast_module_unref, ast_mutex_lock, ast_mutex_unlock, AST_OPTION_AUDIO_MODE, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, ast_queue_hold(), ast_queue_unhold(), AST_STATE_RESERVED, AST_STATE_UP, ast_verb, dahdi_pvt::callwaitcas, dahdi_pvt::callwaiting, dahdi_pvt::callwaitingrepeat, dahdi_pvt::channel, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_subaddr, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cid_tag, dahdi_pvt::cidcwexpire, dahdi_pvt::cidspill, dahdi_pvt::confirmanswer, dahdi_analog_lib_handles(), dahdi_conf_update(), dahdi_confmute(), dahdi_ec_disable(), dahdi_get_index, dahdi_set_hook(), dahdi_setlinear(), dahdi_sig_pri_lib_handles(), dahdi_pvt::destroy, destroy_channel(), dahdi_subchannel::dfd, dahdi_pvt::dialing, dahdi_pvt::didtdd, dahdi_pvt::digital, dahdi_pvt::distinctivering, dahdi_pvt::doreoriginate, dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, dahdi_pvt::dtmfrelax, errno, dahdi_pvt::exten, dahdi_pvt::faxhandled, analog_pvt::fxsoffhookstate, dahdi_pvt::guardtime, dahdi_pvt::hidecallerid, iflock, dahdi_pvt::ignoredtmf, dahdi_subchannel::inthreeway, dahdi_pvt::law, dahdi_pvt::law_default, dahdi_subchannel::linear, dahdi_pvt::lock, LOG_WARNING, dahdi_pvt::mohsuggest, dahdi_pvt::muting, my_is_off_hook(), my_off_hook(), my_play_tone(), dahdi_subchannel::needanswer, dahdi_subchannel::needbusy, dahdi_subchannel::needcongestion, dahdi_subchannel::needflash, dahdi_subchannel::needringing, NULL, num_restart_pending, dahdi_pvt::oprmode, dahdi_pvt::origcid_name, dahdi_pvt::origcid_num, dahdi_pvt::outgoing, dahdi_subchannel::owner, dahdi_pvt::owner, pbx_builtin_getvar_helper(), dahdi_pvt::permcallwaiting, dahdi_pvt::permhidecallerid, dahdi_pvt::polarity, POLARITY_IDLE, dahdi_pvt::pulsedial, dahdi_pvt::radio, dahdi_pvt::rdnis, dahdi_pvt::reoriginate, reset_conf(), restart_monitor(), dahdi_pvt::restartpending, restore_gains(), revert_fax_buffers(), dahdi_pvt::ringt, ast_module_info::self, dahdi_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_MFCR2, sig_pri_hangup(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, sig_ss7_hangup(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, dahdi_pvt::subs, swap_subs(), unalloc_sub(), and dahdi_pvt::waitingfordt.

◆ dahdi_iflist_extract()

static void dahdi_iflist_extract ( struct dahdi_pvt pvt)
static

Definition at line 5600 of file chan_dahdi.c.

5601{
5602 /* Extract from the forward chain. */
5603 if (pvt->prev) {
5604 pvt->prev->next = pvt->next;
5605 } else if (iflist == pvt) {
5606 /* Node is at the head of the list. */
5607 iflist = pvt->next;
5608 }
5609
5610 /* Extract from the reverse chain. */
5611 if (pvt->next) {
5612 pvt->next->prev = pvt->prev;
5613 } else if (ifend == pvt) {
5614 /* Node is at the end of the list. */
5615 ifend = pvt->prev;
5616 }
5617
5618 /* Node is no longer in the list. */
5620 pvt->prev = NULL;
5621 pvt->next = NULL;
5622}
@ DAHDI_IFLIST_NONE
Definition: chan_dahdi.h:117
enum DAHDI_IFLIST which_iflist
Definition: chan_dahdi.h:168

References DAHDI_IFLIST_NONE, ifend, iflist, dahdi_pvt::next, NULL, dahdi_pvt::prev, and dahdi_pvt::which_iflist.

Referenced by destroy_dahdi_pvt().

◆ dahdi_iflist_insert()

static void dahdi_iflist_insert ( struct dahdi_pvt pvt)
static

Definition at line 5552 of file chan_dahdi.c.

5553{
5554 struct dahdi_pvt *cur;
5555
5557
5558 /* Find place in middle of list for the new interface. */
5559 for (cur = iflist; cur; cur = cur->next) {
5560 if (pvt->channel < cur->channel) {
5561 /* New interface goes before the current interface. */
5562 pvt->prev = cur->prev;
5563 pvt->next = cur;
5564 if (cur->prev) {
5565 /* Insert into the middle of the list. */
5566 cur->prev->next = pvt;
5567 } else {
5568 /* Insert at head of list. */
5569 iflist = pvt;
5570 }
5571 cur->prev = pvt;
5572 return;
5573 }
5574 }
5575
5576 /* New interface goes onto the end of the list */
5577 pvt->prev = ifend;
5578 pvt->next = NULL;
5579 if (ifend) {
5580 ifend->next = pvt;
5581 }
5582 ifend = pvt;
5583 if (!iflist) {
5584 /* List was empty */
5585 iflist = pvt;
5586 }
5587}
@ DAHDI_IFLIST_MAIN
Definition: chan_dahdi.h:118

References dahdi_pvt::channel, DAHDI_IFLIST_MAIN, ifend, iflist, dahdi_pvt::next, NULL, dahdi_pvt::prev, and dahdi_pvt::which_iflist.

Referenced by duplicate_pseudo(), and mkintf().

◆ dahdi_indicate()

static int dahdi_indicate ( struct ast_channel chan,
int  condition,
const void *  data,
size_t  datalen 
)
static

Definition at line 9352 of file chan_dahdi.c.

9353{
9354 struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
9355 int res=-1;
9356 int idx;
9357 int func = DAHDI_FLASH;
9358
9359 ast_mutex_lock(&p->lock);
9360 ast_debug(1, "Requested indication %d on channel %s\n", condition, ast_channel_name(chan));
9361 switch (p->sig) {
9362#if defined(HAVE_PRI)
9364 res = sig_pri_indicate(p->sig_pvt, chan, condition, data, datalen);
9366 return res;
9367#endif /* defined(HAVE_PRI) */
9368#if defined(HAVE_SS7)
9369 case SIG_SS7:
9370 res = sig_ss7_indicate(p->sig_pvt, chan, condition, data, datalen);
9372 return res;
9373#endif /* defined(HAVE_SS7) */
9374 default:
9375 break;
9376 }
9377#ifdef HAVE_OPENR2
9378 if (p->mfcr2 && !p->mfcr2_call_accepted) {
9380 /* if this is an R2 call and the call is not yet accepted, we don't want the
9381 tone indications to mess up with the MF tones */
9382 return 0;
9383 }
9384#endif
9385 idx = dahdi_get_index(chan, p, 0);
9386 if (idx == SUB_REAL) {
9387 switch (condition) {
9388 case AST_CONTROL_BUSY:
9389 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_BUSY);
9390 break;
9392 res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_RINGTONE);
9393
9394 if (ast_channel_state(chan) != AST_STATE_UP) {
9395 if ((ast_channel_state(chan) != AST_STATE_RING) ||
9396 ((p->sig != SIG_FXSKS) &&
9397 (p->sig != SIG_FXSLS) &&
9398 (p->sig != SIG_FXSGS)))
9400 }
9401 break;
9403 ast_debug(1, "Received AST_CONTROL_INCOMPLETE on %s\n", ast_channel_name(chan));
9404 /* act as a progress or proceeding, allowing the caller to enter additional numbers */
9405 res = 0;
9406 break;
9408 ast_debug(1, "Received AST_CONTROL_PROCEEDING on %s\n", ast_channel_name(chan));
9409 /* don't continue in ast_indicate */
9410 res = 0;
9411 break;
9413 ast_debug(1, "Received AST_CONTROL_PROGRESS on %s\n", ast_channel_name(chan));
9414 /* don't continue in ast_indicate */
9415 res = 0;
9416 break;
9418 /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
9419 switch (ast_channel_hangupcause(chan)) {
9422 case 0:/* Cause has not been set. */
9423 /* Supply a more appropriate cause. */
9425 break;
9426 default:
9427 break;
9428 }
9429 break;
9430 case AST_CONTROL_HOLD:
9431 ast_moh_start(chan, data, p->mohinterpret);
9432 break;
9433 case AST_CONTROL_UNHOLD:
9434 ast_moh_stop(chan);
9435 break;
9437 if (p->radio)
9438 res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
9439 res = 0;
9440 break;
9442 if (p->radio)
9443 res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_RINGOFF);
9444 res = 0;
9445 break;
9446 case AST_CONTROL_FLASH:
9447 /* flash hookswitch */
9448 if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
9449 /* Clear out the dial buffer */
9450 p->dop.dialstr[0] = '\0';
9451 if ((ioctl(p->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
9452 ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
9453 ast_channel_name(chan), strerror(errno));
9454 } else
9455 res = 0;
9456 } else
9457 res = 0;
9458 break;
9460 res = 0;
9461 break;
9462 case -1:
9463 res = tone_zone_play_tone(p->subs[idx].dfd, -1);
9464 break;
9465 }
9466 } else {
9467 res = 0;
9468 }
9470 return res;
9471}
#define AST_CAUSE_CONGESTION
Definition: causes.h:153
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
#define AST_CAUSE_USER_BUSY
Definition: causes.h:107
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_BUSY
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_HOLD
@ AST_CONTROL_FLASH
@ AST_CONTROL_INCOMPLETE
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7766
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7776
int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
int sig_ss7_indicate(struct sig_ss7_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
char mohinterpret[MAX_MUSICCLASS]
The configured music-on-hold class to use for calls.
Definition: chan_dahdi.h:512

References AST_CAUSE_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_USER_BUSY, ast_channel_hangupcause(), ast_channel_hangupcause_set(), ast_channel_name(), ast_channel_tech_pvt(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_log, ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, dahdi_get_index, dahdi_set_hook(), dahdi_subchannel::dfd, dahdi_pvt::dop, errno, ISTRUNK, dahdi_pvt::lock, LOG_WARNING, dahdi_pvt::mohinterpret, dahdi_pvt::radio, dahdi_pvt::sig, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_PRI, sig_pri_indicate(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, sig_ss7_indicate(), SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_fixup().

◆ dahdi_lock_sub_owner()

static void dahdi_lock_sub_owner ( struct dahdi_pvt pvt,
int  sub_idx 
)
static

Definition at line 3724 of file chan_dahdi.c.

3725{
3726 for (;;) {
3727 if (!pvt->subs[sub_idx].owner) {
3728 /* No subchannel owner pointer */
3729 break;
3730 }
3731 if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) {
3732 /* Got subchannel owner lock */
3733 break;
3734 }
3735 /* We must unlock the private to avoid the possibility of a deadlock */
3736 DEADLOCK_AVOIDANCE(&pvt->lock);
3737 }
3738}
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:479

References ast_channel_trylock, DEADLOCK_AVOIDANCE, dahdi_pvt::lock, dahdi_subchannel::owner, and dahdi_pvt::subs.

Referenced by wakeup_sub().

◆ dahdi_master_slave_link()

void dahdi_master_slave_link ( struct dahdi_pvt slave,
struct dahdi_pvt master 
)

Definition at line 7400 of file chan_dahdi.c.

7401{
7402 int x;
7403 if (!slave || !master) {
7404 ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
7405 return;
7406 }
7407 for (x = 0; x < MAX_SLAVES; x++) {
7408 if (!master->slaves[x]) {
7409 master->slaves[x] = slave;
7410 break;
7411 }
7412 }
7413 if (x >= MAX_SLAVES) {
7414 ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
7415 master->slaves[MAX_SLAVES - 1] = slave;
7416 }
7417 if (slave->master)
7418 ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
7419 slave->master = master;
7420
7421 ast_debug(1, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
7422}

References ast_debug, ast_log, dahdi_pvt::channel, LOG_WARNING, dahdi_pvt::master, MAX_SLAVES, and dahdi_pvt::slaves.

Referenced by native_start().

◆ dahdi_master_slave_unlink()

void dahdi_master_slave_unlink ( struct dahdi_pvt slave,
struct dahdi_pvt master,
int  needlock 
)

Definition at line 7344 of file chan_dahdi.c.

7345{
7346 /* Unlink a specific slave or all slaves/masters from a given master */
7347 int x;
7348 int hasslaves;
7349 if (!master)
7350 return;
7351 if (needlock) {
7352 ast_mutex_lock(&master->lock);
7353 if (slave) {
7354 while (ast_mutex_trylock(&slave->lock)) {
7355 DEADLOCK_AVOIDANCE(&master->lock);
7356 }
7357 }
7358 }
7359 hasslaves = 0;
7360 for (x = 0; x < MAX_SLAVES; x++) {
7361 if (master->slaves[x]) {
7362 if (!slave || (master->slaves[x] == slave)) {
7363 /* Take slave out of the conference */
7364 ast_debug(1, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
7365 conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
7366 conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
7367 master->slaves[x]->master = NULL;
7368 master->slaves[x] = NULL;
7369 } else
7370 hasslaves = 1;
7371 }
7372 if (!hasslaves)
7373 master->inconference = 0;
7374 }
7375 if (!slave) {
7376 if (master->master) {
7377 /* Take master out of the conference */
7378 conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
7379 conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
7380 hasslaves = 0;
7381 for (x = 0; x < MAX_SLAVES; x++) {
7382 if (master->master->slaves[x] == master)
7383 master->master->slaves[x] = NULL;
7384 else if (master->master->slaves[x])
7385 hasslaves = 1;
7386 }
7387 if (!hasslaves)
7388 master->master->inconference = 0;
7389 }
7390 master->master = NULL;
7391 }
7392 dahdi_conf_update(master);
7393 if (needlock) {
7394 if (slave)
7395 ast_mutex_unlock(&slave->lock);
7396 ast_mutex_unlock(&master->lock);
7397 }
7398}
#define ast_mutex_trylock(a)
Definition: lock.h:191

References ast_debug, ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, dahdi_pvt::channel, conf_del(), dahdi_conf_update(), DEADLOCK_AVOIDANCE, dahdi_pvt::inconference, dahdi_pvt::lock, dahdi_pvt::master, MAX_SLAVES, NULL, dahdi_pvt::slaves, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_fixup(), and native_stop().

◆ dahdi_new()

static struct ast_channel * dahdi_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

Definition at line 9530 of file chan_dahdi.c.

9531{
9532 struct ast_channel *tmp;
9533 struct ast_format_cap *caps;
9534 struct ast_format *deflaw;
9535 int x;
9536 int features;
9537 struct ast_str *chan_name;
9538 struct ast_variable *v;
9539 char *dashptr;
9540 char device_name[AST_CHANNEL_NAME];
9541
9542 if (i->subs[idx].owner) {
9543 ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[idx]);
9544 return NULL;
9545 }
9546
9547#if defined(HAVE_PRI)
9548 /*
9549 * The dnid has been stuffed with the called-number[:subaddress]
9550 * by dahdi_request() for outgoing calls.
9551 */
9552 chan_name = create_channel_name(i, i->outgoing, i->dnid);
9553#else
9554 chan_name = create_channel_name(i);
9555#endif /* defined(HAVE_PRI) */
9556 if (!chan_name) {
9557 return NULL;
9558 }
9559
9561 if (!caps) {
9562 ast_free(chan_name);
9563 return NULL;
9564 }
9565
9566 tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name));
9567 ast_free(chan_name);
9568 if (!tmp) {
9569 ao2_ref(caps, -1);
9570 return NULL;
9571 }
9572
9574
9575 if (callid) {
9576 ast_channel_callid_set(tmp, callid);
9577 }
9578
9580#if defined(HAVE_PRI)
9581 if (i->pri) {
9583 }
9584#endif /* defined(HAVE_PRI) */
9586 if (law) {
9587 i->law = law;
9588 if (law == DAHDI_LAW_ALAW) {
9589 deflaw = ast_format_alaw;
9590 } else {
9591 deflaw = ast_format_ulaw;
9592 }
9593 } else {
9594 switch (i->sig) {
9596 /* Make sure companding law is known. */
9597 i->law = (i->law_default == DAHDI_LAW_ALAW)
9598 ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW;
9599 break;
9600 default:
9601 i->law = i->law_default;
9602 break;
9603 }
9604 if (i->law_default == DAHDI_LAW_ALAW) {
9605 deflaw = ast_format_alaw;
9606 } else {
9607 deflaw = ast_format_ulaw;
9608 }
9609 }
9610 ast_channel_set_fd(tmp, 0, i->subs[idx].dfd);
9611 ast_format_cap_append(caps, deflaw, 0);
9613 ao2_ref(caps, -1);
9614 /* Start out assuming ulaw since it's smaller :) */
9619 i->subs[idx].linear = 0;
9620 dahdi_setlinear(i->subs[idx].dfd, i->subs[idx].linear);
9621 features = 0;
9622 if (idx == SUB_REAL) {
9623 if (i->busydetect && CANBUSYDETECT(i))
9624 features |= DSP_FEATURE_BUSY_DETECT;
9626 features |= DSP_FEATURE_CALL_PROGRESS;
9628 features |= DSP_FEATURE_WAITDIALTONE;
9629 if ((!i->outgoing && (i->callprogress & CALLPROGRESS_FAX_INCOMING)) ||
9631 features |= DSP_FEATURE_FAX_DETECT;
9632 }
9633 x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
9634 if (ioctl(i->subs[idx].dfd, DAHDI_TONEDETECT, &x)) {
9635 i->hardwaredtmf = 0;
9636 features |= DSP_FEATURE_DIGIT_DETECT;
9637 } else if (NEED_MFDETECT(i)) {
9638 i->hardwaredtmf = 1;
9639 features |= DSP_FEATURE_DIGIT_DETECT;
9640 }
9641 }
9642 if (features) {
9643 if (i->dsp) {
9644 ast_debug(1, "Already have a dsp on %s?\n", ast_channel_name(tmp));
9645 } else {
9646 if (i->channel != CHAN_PSEUDO)
9647 i->dsp = ast_dsp_new();
9648 else
9649 i->dsp = NULL;
9650 if (i->dsp) {
9651 i->dsp_features = features;
9652#if defined(HAVE_PRI) || defined(HAVE_SS7)
9653 /* We cannot do progress detection until receive PROGRESS message */
9654 if (i->outgoing && (dahdi_sig_pri_lib_handles(i->sig) || (i->sig == SIG_SS7))) {
9655 /* Remember requested DSP features, don't treat
9656 talking as ANSWER */
9657 i->dsp_features = features & ~DSP_PROGRESS_TALK;
9658 features = 0;
9659 }
9660#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
9661 ast_dsp_set_features(i->dsp, features);
9665 if (i->busydetect && CANBUSYDETECT(i)) {
9668 }
9669 }
9670 }
9671 }
9672
9674
9675 if (state == AST_STATE_RING)
9678 if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
9679 /* Only FXO signalled stuff can be picked up */
9684 }
9685 if (!ast_strlen_zero(i->parkinglot))
9686 ast_channel_parkinglot_set(tmp, i->parkinglot);
9687 if (!ast_strlen_zero(i->language))
9688 ast_channel_language_set(tmp, i->language);
9689 if (!i->owner)
9690 i->owner = tmp;
9692 ast_channel_accountcode_set(tmp, i->accountcode);
9693 if (i->amaflags)
9695 i->subs[idx].owner = tmp;
9697 if (!dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
9698 ast_channel_call_forward_set(tmp, i->call_forward);
9699 }
9700 /* If we've been told "no ADSI" then enforce it */
9701 if (!i->adsi)
9703 if (!ast_strlen_zero(i->exten))
9705 if (!ast_strlen_zero(i->rdnis)) {
9708 }
9709 if (!ast_strlen_zero(i->dnid)) {
9711 }
9712
9713 /* Don't use ast_set_callerid() here because it will
9714 * generate a needless NewCallerID event */
9715#if defined(HAVE_PRI) || defined(HAVE_SS7)
9716 if (!ast_strlen_zero(i->cid_ani)) {
9719 } else if (!ast_strlen_zero(i->cid_num)) {
9722 }
9723#else
9724 if (!ast_strlen_zero(i->cid_num)) {
9727 }
9728#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
9734 /* clear the fake event in case we posted one before we had ast_channel */
9735 i->fake_event = 0;
9736 /* Assure there is no confmute on this channel */
9737 dahdi_confmute(i, 0);
9738 i->muting = 0;
9739 /* Configure the new channel jb */
9741
9742 /* Set initial device state */
9743 ast_copy_string(device_name, ast_channel_name(tmp), sizeof(device_name));
9744 dashptr = strrchr(device_name, '-');
9745 if (dashptr) {
9746 *dashptr = '\0';
9747 }
9750
9751 for (v = i->vars ; v ; v = v->next)
9753
9755
9757
9759
9761 if (startpbx) {
9762#ifdef HAVE_OPENR2
9763 if (i->mfcr2call) {
9764 pbx_builtin_setvar_helper(tmp, "MFCR2_CATEGORY", openr2_proto_get_category_string(i->mfcr2_recvd_category));
9765 }
9766#endif
9767 if (ast_pbx_start(tmp)) {
9768 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
9769 ast_hangup(tmp);
9770 return NULL;
9771 }
9772 }
9773 return tmp;
9774}
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:593
void ast_cc_copy_config_params(struct ast_cc_config_params *dest, const struct ast_cc_config_params *src)
copy CCSS configuration parameters from one structure to another
Definition: ccss.c:854
#define CALLPROGRESS_FAX_INCOMING
Definition: chan_dahdi.c:681
#define CALLPROGRESS_FAX_OUTGOING
Definition: chan_dahdi.c:680
static void dahdi_ami_channel_event(struct dahdi_pvt *p, struct ast_channel *chan)
Definition: chan_dahdi.c:1968
static struct ast_jb_conf global_jbconf
Definition: chan_dahdi.c:626
static char progzone[10]
Definition: chan_dahdi.c:726
#define CANBUSYDETECT(p)
Definition: chan_dahdi.c:714
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1258
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
int ast_channel_cc_params_init(struct ast_channel *chan, const struct ast_cc_config_params *base_params)
Set up datastore with CCSS parameters for a channel.
Definition: channel.c:10451
@ AST_ADSI_UNAVAILABLE
Definition: channel.h:871
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2426
@ AST_FLAG_DISABLE_DEVSTATE_CACHE
Definition: channel.h:1029
void ast_channel_callid_set(struct ast_channel *chan, ast_callid value)
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
@ AST_DEVSTATE_NOT_CACHABLE
Definition: devicestate.h:69
int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:471
#define DSP_FEATURE_WAITDIALTONE
Definition: dsp.h:44
#define DSP_FEATURE_BUSY_DETECT
Definition: dsp.h:27
void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, const struct ast_dsp_busy_pattern *cadence)
Set expected lengths of the busy tone.
Definition: dsp.c:1804
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
#define DSP_FEATURE_CALL_PROGRESS
Definition: dsp.h:43
void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
Set number of required cadences for busy.
Definition: dsp.c:1793
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1758
int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
Set zone for doing progress detection.
Definition: dsp.c:1892
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:457
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4708
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Definition of a media format.
Definition: format.c:43
struct ast_party_dialed::@208 number
Dialed/Called number.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:386
char * tag
User-set "tag".
Definition: channel.h:354
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:277
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:295
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:293
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:527
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
struct ast_variable * vars
Channel variable list with associated values to set when a channel is created.
Definition: chan_dahdi.h:584
int busycount
Number of times to see "busy" tone before hanging up.
Definition: chan_dahdi.h:641
int waitfordialtone
Number of milliseconds to wait for dialtone.
Definition: chan_dahdi.h:656
unsigned int adsi
TRUE if ADSI (Analog Display Services Interface) available.
Definition: chan_dahdi.h:178
int dialtone_scanning_time_elapsed
Definition: chan_dahdi.h:670
char dnid[AST_MAX_EXTENSION]
Dialed Number Identifier.
Definition: chan_dahdi.h:547
struct ast_namedgroups * named_pickupgroups
Named pickup groups this belongs to.
Definition: chan_dahdi.h:579
int cid_ani2
Automatic Number Identification code from PRI.
Definition: chan_dahdi.h:524
struct ast_namedgroups * named_callgroups
Named call groups this belongs to.
Definition: chan_dahdi.h:574
unsigned int busydetect
TRUE if busy detection is enabled. (Listens for the beep-beep busy pattern.)
Definition: chan_dahdi.h:206
ast_group_t pickupgroup
Bitmapped pickup groups this belongs to.
Definition: chan_dahdi.h:569
int callingpres
Definition: chan_dahdi.h:592
char parkinglot[AST_MAX_EXTENSION]
Definition: chan_dahdi.h:518
int amaflags
Definition: chan_dahdi.h:701
char language[MAX_LANGUAGE]
Language configured for calls.
Definition: chan_dahdi.h:507
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_dahdi.h:700
struct ast_dsp_busy_pattern busy_cadence
Busy cadence pattern description.
Definition: chan_dahdi.h:646
ast_group_t callgroup
Bitmapped call groups this belongs to.
Definition: chan_dahdi.h:564
int dialtone_detect
Number of frames to watch for dialtone in incoming calls.
Definition: chan_dahdi.h:669
int cid_ton
Caller ID Q.931 TON/NPI field values. Set by PRI. Zero otherwise.
Definition: chan_dahdi.h:533

References dahdi_pvt::accountcode, dahdi_pvt::adsi, dahdi_pvt::amaflags, ast_party_caller::ani, ast_party_caller::ani2, ao2_ref, AST_ADSI_UNAVAILABLE, ast_cc_copy_config_params(), ast_channel_adsicpe_set(), ast_channel_alloc, ast_channel_amaflags_set(), ast_channel_caller(), ast_channel_callgroup_set(), ast_channel_callid_set(), ast_channel_cc_params_init(), ast_channel_context_set(), ast_channel_dialed(), ast_channel_exten_set(), ast_channel_flags(), AST_CHANNEL_NAME, ast_channel_name(), ast_channel_named_callgroups_set(), ast_channel_named_pickupgroups_set(), ast_channel_nativeformats_set(), ast_channel_pickupgroup_set(), ast_channel_redirecting(), ast_channel_rings_set(), ast_channel_set_fd(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_unlock, ast_copy_string(), ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), AST_DEVSTATE_NOT_CACHABLE, ast_dsp_new(), ast_dsp_set_busy_count(), ast_dsp_set_busy_pattern(), ast_dsp_set_call_progress_zone(), ast_dsp_set_digitmode(), ast_dsp_set_features(), AST_FLAG_DISABLE_DEVSTATE_CACHE, ast_format_alaw, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_ulaw, ast_free, ast_hangup(), ast_jb_configure(), ast_log, ast_module_ref, ast_pbx_start(), ast_set_flag, AST_STATE_RING, ast_str_buffer(), ast_strdup, ast_strlen_zero(), dahdi_pvt::busy_cadence, dahdi_pvt::busycount, dahdi_pvt::busydetect, dahdi_pvt::call_forward, dahdi_pvt::callgroup, dahdi_pvt::callingpres, dahdi_pvt::callprogress, CALLPROGRESS_FAX_INCOMING, CALLPROGRESS_FAX_OUTGOING, CALLPROGRESS_PROGRESS, CANBUSYDETECT, CANPROGRESSDETECT, dahdi_pvt::cc_params, CHAN_PSEUDO, dahdi_pvt::channel, dahdi_pvt::cid_ani2, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_tag, dahdi_pvt::cid_ton, dahdi_pvt::context, create_channel_name(), dahdi_ami_channel_event(), dahdi_analog_lib_handles(), dahdi_confmute(), dahdi_setlinear(), dahdi_sig_pri_lib_handles(), dahdi_tech, dahdi_subchannel::dfd, dahdi_pvt::dialtone_detect, dahdi_pvt::dialtone_scanning_time_elapsed, dahdi_pvt::dnid, dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, DSP_FEATURE_WAITDIALTONE, dahdi_pvt::dsp_features, dahdi_pvt::dtmfrelax, dahdi_pvt::exten, dahdi_pvt::fake_event, ast_party_redirecting::from, global_jbconf, dahdi_pvt::hardwaredtmf, ast_party_caller::id, dahdi_pvt::language, dahdi_pvt::law, dahdi_pvt::law_default, dahdi_subchannel::linear, LOG_WARNING, dahdi_pvt::muting, ast_party_id::name, ast_variable::name, dahdi_pvt::named_callgroups, dahdi_pvt::named_pickupgroups, NEED_MFDETECT, ast_variable::next, NULL, ast_party_id::number, ast_party_dialed::number, dahdi_pvt::oprmode, dahdi_pvt::outgoing, dahdi_subchannel::owner, dahdi_pvt::owner, dahdi_pvt::parkinglot, pbx_builtin_setvar_helper(), dahdi_pvt::pickupgroup, ast_party_number::plan, ast_party_name::presentation, ast_party_number::presentation, progzone, dahdi_pvt::radio, dahdi_pvt::rdnis, ast_module_info::self, dahdi_pvt::sig, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_PRI_LIB_HANDLE_CASES, SIG_SS7, ast_party_number::str, ast_party_dialed::str, SUB_REAL, subnames, dahdi_pvt::subs, ast_party_id::tag, tmp(), ast_party_number::valid, ast_variable::value, dahdi_pvt::vars, and dahdi_pvt::waitfordialtone.

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

◆ dahdi_new_callid_clean()

static struct ast_channel * dahdi_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

Definition at line 9521 of file chan_dahdi.c.

9522{
9523 struct ast_channel *new_channel = dahdi_new(i, state, startpbx, idx, law, assignedids, requestor, callid);
9524
9526
9527 return new_channel;
9528}

References ast_callid_threadstorage_auto_clean(), ast_channel::callid, and dahdi_new().

Referenced by my_new_analog_ast_channel().

◆ dahdi_open()

static int dahdi_open ( char *  fn)
static

Definition at line 4346 of file chan_dahdi.c.

4347{
4348 int fd;
4349 int isnum;
4350 int chan = 0;
4351 int bs;
4352 int x;
4353 isnum = 1;
4354 for (x = 0; x < strlen(fn); x++) {
4355 if (!isdigit(fn[x])) {
4356 isnum = 0;
4357 break;
4358 }
4359 }
4360 if (isnum) {
4361 chan = atoi(fn);
4362 if (chan < 1) {
4363 ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
4364 return -1;
4365 }
4366 fn = "/dev/dahdi/channel";
4367 }
4368 fd = open(fn, O_RDWR | O_NONBLOCK);
4369 if (fd < 0) {
4370 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
4371 return -1;
4372 }
4373 if (chan) {
4374 if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
4375 x = errno;
4376 close(fd);
4377 errno = x;
4378 ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
4379 return -1;
4380 }
4381 }
4382 bs = READ_SIZE;
4383 if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) {
4384 ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno));
4385 x = errno;
4386 close(fd);
4387 errno = x;
4388 return -1;
4389 }
4390 return fd;
4391}
char * bs
Definition: eagi_proxy.c:73

References ast_log, bs, errno, LOG_WARNING, READ_SIZE, and ast_channel::x.

Referenced by alloc_sub(), duplicate_pseudo(), and mkintf().

◆ dahdi_queryoption()

static int dahdi_queryoption ( struct ast_channel chan,
int  option,
void *  data,
int *  datalen 
)
static

Definition at line 6794 of file chan_dahdi.c.

6795{
6796 char *cp;
6797 struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
6798
6799 /* all supported options require data */
6800 if (!p || !data || (*datalen < 1)) {
6801 errno = EINVAL;
6802 return -1;
6803 }
6804
6805 switch (option) {
6806 case AST_OPTION_TDD:
6807 cp = (char *) data;
6808 if (p->mate) {
6809 *cp = 2;
6810 } else {
6811 *cp = p->tdd ? 1 : 0;
6812 }
6813 break;
6815 cp = (char *) data;
6816 *cp = p->ignoredtmf ? 0 : 1;
6817 ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", ast_channel_name(chan));
6818 break;
6820 cp = (char *) data;
6821 *cp = (p->dsp_features & DSP_FEATURE_FAX_DETECT) ? 0 : 1;
6822 ast_debug(1, "Reporting fax tone detection %sabled on %s\n", *cp ? "en" : "dis", ast_channel_name(chan));
6823 break;
6825#if defined(HAVE_PRI)
6826#if defined(HAVE_PRI_CCSS)
6828 ast_copy_string((char *) data, dahdi_pri_cc_type, *datalen);
6829 break;
6830 }
6831#endif /* defined(HAVE_PRI_CCSS) */
6832#endif /* defined(HAVE_PRI) */
6833 return -1;
6834 default:
6835 return -1;
6836 }
6837
6838 errno = 0;
6839
6840 return 0;
6841}
#define AST_OPTION_DIGIT_DETECT
#define AST_OPTION_CC_AGENT_TYPE
#define AST_OPTION_FAX_DETECT
struct tdd_state * tdd
Definition: chan_dahdi.h:702
unsigned int mate
TRUE if TDD in MATE mode.
Definition: chan_dahdi.h:326

References ast_channel_name(), ast_channel_tech_pvt(), ast_copy_string(), ast_debug, AST_OPTION_CC_AGENT_TYPE, AST_OPTION_DIGIT_DETECT, AST_OPTION_FAX_DETECT, AST_OPTION_TDD, dahdi_sig_pri_lib_handles(), DSP_FEATURE_FAX_DETECT, dahdi_pvt::dsp_features, errno, dahdi_pvt::ignoredtmf, dahdi_pvt::mate, dahdi_pvt::sig, and dahdi_pvt::tdd.

◆ dahdi_queue_frame()

static void dahdi_queue_frame ( struct dahdi_pvt p,
struct ast_frame f 
)
static

Definition at line 3749 of file chan_dahdi.c.

3750{
3751 for (;;) {
3752 if (p->owner) {
3753 if (ast_channel_trylock(p->owner)) {
3755 } else {
3756 ast_queue_frame(p->owner, f);
3758 break;
3759 }
3760 } else
3761 break;
3762 }
3763}
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1139

References ast_channel_trylock, ast_channel_unlock, ast_queue_frame(), DEADLOCK_AVOIDANCE, dahdi_pvt::lock, and dahdi_pvt::owner.

Referenced by action_dahdidialoffhook().

◆ dahdi_read()

static struct ast_frame * dahdi_read ( struct ast_channel ast)
static

Definition at line 8788 of file chan_dahdi.c.

8789{
8790 struct dahdi_pvt *p;
8791 int res;
8792 int idx;
8793 void *readbuf;
8794 struct ast_frame *f;
8795
8796 /*
8797 * For analog channels, we must do deadlock avoidance because
8798 * analog ports can have more than one Asterisk channel using
8799 * the same private structure.
8800 */
8801 p = ast_channel_tech_pvt(ast);
8802 while (ast_mutex_trylock(&p->lock)) {
8804
8805 /*
8806 * Check to see if the channel is still associated with the same
8807 * private structure. While the Asterisk channel was unlocked
8808 * the following events may have occured:
8809 *
8810 * 1) A masquerade may have associated the channel with another
8811 * technology or private structure.
8812 *
8813 * 2) For PRI calls, call signaling could change the channel
8814 * association to another B channel (private structure).
8815 */
8816 if (ast_channel_tech_pvt(ast) != p) {
8817 /* The channel is no longer associated. Quit gracefully. */
8818 return &ast_null_frame;
8819 }
8820 }
8821
8822 idx = dahdi_get_index(ast, p, 0);
8823
8824 /* Hang up if we don't really exist */
8825 if (idx < 0) {
8826 ast_log(LOG_WARNING, "We don't exist?\n");
8828 return NULL;
8829 }
8830
8831 if ((p->radio || (p->oprmode < 0)) && p->inalarm) {
8833 return NULL;
8834 }
8835
8836 p->subs[idx].f.frametype = AST_FRAME_NULL;
8837 p->subs[idx].f.datalen = 0;
8838 p->subs[idx].f.samples = 0;
8839 p->subs[idx].f.mallocd = 0;
8840 p->subs[idx].f.offset = 0;
8841 p->subs[idx].f.subclass.integer = 0;
8842 p->subs[idx].f.delivery = ast_tv(0,0);
8843 p->subs[idx].f.src = "dahdi_read";
8844 p->subs[idx].f.data.ptr = NULL;
8845
8846 /* make sure it sends initial key state as first frame */
8847 if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
8848 {
8849 struct dahdi_params ps;
8850
8851 memset(&ps, 0, sizeof(ps));
8852 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
8854 return NULL;
8855 }
8856 p->firstradio = 1;
8858 if (ps.rxisoffhook)
8859 {
8861 }
8862 else
8863 {
8865 }
8867 return &p->subs[idx].f;
8868 }
8869 if (p->ringt > 0) {
8870 if (!(--p->ringt)) {
8872 return NULL;
8873 }
8874 }
8875
8876#ifdef HAVE_OPENR2
8877 if (p->mfcr2) {
8878 openr2_chan_process_event(p->r2chan);
8879 if (OR2_DIR_FORWARD == openr2_chan_get_direction(p->r2chan)) {
8881 /* if the call is already accepted and we already delivered AST_CONTROL_RINGING
8882 * now enqueue a progress frame to bridge the media up */
8883 if (p->mfcr2_call_accepted &&
8884 !p->mfcr2_progress_sent &&
8886 ast_debug(1, "Enqueuing progress frame after R2 accept in chan %d\n", p->channel);
8887 ast_queue_frame(p->owner, &fr);
8888 p->mfcr2_progress_sent = 1;
8889 }
8890 }
8891 }
8892#endif
8893
8894 if (p->subs[idx].needringing) {
8895 /* Send ringing frame if requested */
8896 p->subs[idx].needringing = 0;
8901 return &p->subs[idx].f;
8902 }
8903
8904 if (p->subs[idx].needbusy) {
8905 /* Send busy frame if requested */
8906 p->subs[idx].needbusy = 0;
8910 return &p->subs[idx].f;
8911 }
8912
8913 if (p->subs[idx].needcongestion) {
8914 /* Send congestion frame if requested */
8915 p->subs[idx].needcongestion = 0;
8919 return &p->subs[idx].f;
8920 }
8921
8922 if (p->subs[idx].needanswer) {
8923 /* Send answer frame if requested */
8924 p->subs[idx].needanswer = 0;
8928 return &p->subs[idx].f;
8929 }
8930#ifdef HAVE_OPENR2
8931 if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) {
8932 /* openr2 took care of reading and handling any event
8933 (needanswer, needbusy etc), if we continue we will read()
8934 twice, lets just return a null frame. This should only
8935 happen when openr2 is dialing out */
8937 return &ast_null_frame;
8938 }
8939#endif
8940
8941 if (p->subs[idx].needflash) {
8942 /* Send answer frame if requested */
8943 p->subs[idx].needflash = 0;
8947 return &p->subs[idx].f;
8948 }
8949
8950 if (p->subs[idx].needhold) {
8951 /* Send answer frame if requested */
8952 p->subs[idx].needhold = 0;
8956 ast_debug(1, "Sending hold on '%s'\n", ast_channel_name(ast));
8957 return &p->subs[idx].f;
8958 }
8959
8960 if (p->subs[idx].needunhold) {
8961 /* Send answer frame if requested */
8962 p->subs[idx].needunhold = 0;
8966 ast_debug(1, "Sending unhold on '%s'\n", ast_channel_name(ast));
8967 return &p->subs[idx].f;
8968 }
8969
8970 /*
8971 * If we have a fake_event, fake an exception to handle it only
8972 * if this channel owns the private.
8973 */
8974 if (p->fake_event && p->owner == ast) {
8975 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
8976 struct analog_pvt *analog_p = p->sig_pvt;
8977
8978 f = analog_exception(analog_p, ast);
8979 } else {
8980 f = __dahdi_exception(ast);
8981 }
8983 return f;
8984 }
8985
8987 if (!p->subs[idx].linear) {
8988 p->subs[idx].linear = 1;
8989 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8990 if (res)
8991 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, idx);
8992 }
8993 } else {
8994 if (p->subs[idx].linear) {
8995 p->subs[idx].linear = 0;
8996 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8997 if (res)
8998 ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, idx);
8999 }
9000 }
9001 readbuf = ((unsigned char *)p->subs[idx].buffer) + AST_FRIENDLY_OFFSET;
9002 CHECK_BLOCKING(ast);
9003 res = read(p->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
9005 /* Check for hangup */
9006 if (res < 0) {
9007 f = NULL;
9008 if (res == -1) {
9009 if (errno == EAGAIN) {
9010 /* Return "NULL" frame if there is nobody there */
9012 return &p->subs[idx].f;
9013 } else if (errno == ELAST) {
9014 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
9015 struct analog_pvt *analog_p = p->sig_pvt;
9016 f = analog_exception(analog_p, ast);
9017 } else {
9018 f = __dahdi_exception(ast);
9019 }
9020 } else
9021 ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno));
9022 }
9024 return f;
9025 }
9026 if (res != (p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE)) {
9027 ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
9028 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
9029 struct analog_pvt *analog_p = p->sig_pvt;
9030 f = analog_exception(analog_p, ast);
9031 } else {
9032 f = __dahdi_exception(ast);
9033 }
9035 return f;
9036 }
9037 if (p->tdd) { /* if in TDD mode, see if we receive that */
9038 int c;
9039
9040 c = tdd_feed(p->tdd,readbuf,READ_SIZE);
9041 if (c < 0) {
9042 ast_debug(1,"tdd_feed failed\n");
9044 return NULL;
9045 }
9046 if (c) { /* if a char to return */
9047 p->subs[idx].f.subclass.integer = 0;
9048 p->subs[idx].f.frametype = AST_FRAME_TEXT;
9049 p->subs[idx].f.mallocd = 0;
9050 p->subs[idx].f.offset = AST_FRIENDLY_OFFSET;
9051 p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET;
9052 p->subs[idx].f.datalen = 1;
9053 *((char *) p->subs[idx].f.data.ptr) = c;
9055 return &p->subs[idx].f;
9056 }
9057 }
9058 if (idx == SUB_REAL) {
9059 /* Ensure the CW timers decrement only on a single subchannel */
9060 if (p->cidcwexpire) {
9061 if (!--p->cidcwexpire) {
9062 /* Expired CID/CW */
9063 ast_verb(3, "CPE does not support Call Waiting Caller*ID.\n");
9065 }
9066 }
9067 if (p->cid_suppress_expire) {
9069 }
9070 if (p->callwaitingrepeat) {
9071 if (!--p->callwaitingrepeat) {
9072 /* Expired, Repeat callwaiting tone */
9073 ++p->callwaitrings;
9074 dahdi_callwait(ast);
9075 }
9076 }
9077 }
9078 if (p->subs[idx].linear) {
9079 p->subs[idx].f.datalen = READ_SIZE * 2;
9080 } else
9081 p->subs[idx].f.datalen = READ_SIZE;
9082
9083 /* Handle CallerID Transmission */
9084 if ((p->owner == ast) && p->cidspill) {
9085 send_callerid(p);
9086 }
9087
9088 p->subs[idx].f.frametype = AST_FRAME_VOICE;
9090 p->subs[idx].f.samples = READ_SIZE;
9091 p->subs[idx].f.mallocd = 0;
9092 p->subs[idx].f.offset = AST_FRIENDLY_OFFSET;
9093 p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[idx].buffer[0]);
9094#if 0
9095 ast_debug(1, "Read %d of voice on %s\n", p->subs[idx].f.datalen, ast->name);
9096#endif
9097 if ((p->dialing && !p->waitingfordt.tv_sec) || p->radio || /* Transmitting something */
9098 (idx && (ast_channel_state(ast) != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
9099 ((idx == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
9100 ) {
9101 /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
9102 don't send anything */
9103 p->subs[idx].f.frametype = AST_FRAME_NULL;
9104 p->subs[idx].f.subclass.integer = 0;
9105 p->subs[idx].f.samples = 0;
9106 p->subs[idx].f.mallocd = 0;
9107 p->subs[idx].f.offset = 0;
9108 p->subs[idx].f.data.ptr = NULL;
9109 p->subs[idx].f.datalen= 0;
9110 }
9111 if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress || p->waitingfordt.tv_sec || p->dialtone_detect) && !idx) {
9112 /* Perform busy detection etc on the dahdi line */
9113 int mute;
9114
9116 && p->faxdetect_timeout
9118 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
9120 ast_debug(1, "Channel driver fax CNG detection timeout on %s\n",
9121 ast_channel_name(ast));
9122 }
9123
9124 f = ast_dsp_process(ast, p->dsp, &p->subs[idx].f);
9125
9126 /* Check if DSP code thinks we should be muting this frame and mute the conference if so */
9127 mute = ast_dsp_was_muted(p->dsp);
9128 if (p->muting != mute) {
9129 p->muting = mute;
9130 dahdi_confmute(p, mute);
9131 }
9132
9133 if (f) {
9135 && !p->outgoing && ast_channel_state(ast) == AST_STATE_UP) {
9137 p->dsp_features &= ~DSP_FEATURE_WAITDIALTONE;
9139 }
9140 }
9142 if ((ast_channel_state(ast) == AST_STATE_UP) && !p->outgoing) {
9143 /*
9144 * Treat this as a "hangup" instead of a "busy" on the
9145 * assumption that a busy means the incoming call went away.
9146 */
9147 ast_frfree(f);
9148 f = NULL;
9149 }
9150 } else if (p->dialtone_detect && !p->outgoing && f->frametype == AST_FRAME_VOICE) {
9152 /* Dialtone detected on inbound call; hangup the channel */
9153 ast_frfree(f);
9154 f = NULL;
9155 }
9156 } else if (f->frametype == AST_FRAME_DTMF_BEGIN
9157 || f->frametype == AST_FRAME_DTMF_END) {
9158#ifdef HAVE_PRI
9160 && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING
9161 && p->pri
9162 && ((!p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING))
9163 || (p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)))) {
9164 /* Don't accept in-band DTMF when in overlap dial mode */
9165 ast_debug(1, "Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n",
9166 f->frametype == AST_FRAME_DTMF_BEGIN ? "begin" : "end",
9167 (unsigned)f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
9168
9170 f->subclass.integer = 0;
9171 }
9172#endif
9173 /* DSP clears us of being pulse */
9174 p->pulsedial = 0;
9175 } else if (p->waitingfordt.tv_sec) {
9177 p->waitingfordt.tv_sec = 0;
9178 ast_log(LOG_NOTICE, "Never saw dialtone on channel %d\n", p->channel);
9179 ast_frfree(f);
9180 f = NULL;
9181 } else if (f->frametype == AST_FRAME_VOICE) {
9183 f->subclass.integer = 0;
9185 p->waitingfordt.tv_sec = 0;
9186 p->dsp_features &= ~DSP_FEATURE_WAITDIALTONE;
9188 ast_debug(1, "Got 10 samples of dialtone!\n");
9189 if (!ast_strlen_zero(p->dop.dialstr)) { /* Dial deferred digits */
9190 res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
9191 if (res) {
9192 p->dop.dialstr[0] = '\0';
9194 ast_frfree(f);
9195 return NULL;
9196 } else {
9197 ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
9198 p->dialing = 1;
9199 p->dop.dialstr[0] = '\0';
9200 p->dop.op = DAHDI_DIAL_OP_REPLACE;
9202 }
9203 }
9204 }
9205 }
9206 }
9207 }
9208 } else
9209 f = &p->subs[idx].f;
9210
9211 if (f) {
9212 switch (f->frametype) {
9214 case AST_FRAME_DTMF_END:
9215 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
9216 analog_handle_dtmf(p->sig_pvt, ast, idx, &f);
9217 } else {
9218 dahdi_handle_dtmf(ast, idx, &f);
9219 }
9221 if (f->frametype == AST_FRAME_DTMF_END) { /* only show this message when the key is let go of */
9222 ast_debug(1, "Dropping DTMF digit '%c' because tone dialing is disabled\n", f->subclass.integer);
9223 }
9225 f->subclass.integer = 0;
9226 }
9227 break;
9228 case AST_FRAME_VOICE:
9229 if (p->cidspill || p->cid_suppress_expire) {
9230 /* We are/were sending a caller id spill. Suppress any echo. */
9231 p->subs[idx].f.frametype = AST_FRAME_NULL;
9232 p->subs[idx].f.subclass.integer = 0;
9233 p->subs[idx].f.samples = 0;
9234 p->subs[idx].f.mallocd = 0;
9235 p->subs[idx].f.offset = 0;
9236 p->subs[idx].f.data.ptr = NULL;
9237 p->subs[idx].f.datalen= 0;
9238 }
9239 break;
9240 default:
9241 break;
9242 }
9243 }
9244
9246 return f;
9247}
static int dahdi_callwait(struct ast_channel *ast)
Definition: chan_dahdi.c:5359
struct ast_format * ast_channel_rawreadformat(struct ast_channel *chan)
#define CHECK_BLOCKING(c)
Set the blocking indication on the channel.
Definition: channel.h:2871
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
Definition: channel.c:2845
@ AST_FLAG_BLOCKING
Definition: channel.h:985
int ast_dsp_get_tcount(struct ast_dsp *dsp)
Get tcount (Threshold counter)
Definition: dsp.c:1916
#define DSP_TONE_STATE_DIALTONE
Definition: dsp.h:54
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress,...
Definition: dsp.c:1499
int ast_dsp_get_tstate(struct ast_dsp *dsp)
Get tstate (Tone State)
Definition: dsp.c:1911
int ast_dsp_was_muted(struct ast_dsp *dsp)
Returns true if DSP code was muting any fragment of the last processed frame. Muting (squelching) hap...
Definition: dsp.c:1906
#define DSP_TONE_STATE_RINGING
Definition: dsp.h:53
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
@ AST_FRAME_VOICE
@ AST_FRAME_TEXT
void analog_handle_dtmf(struct analog_pvt *p, struct ast_channel *ast, enum analog_sub idx, struct ast_frame **dest)
Definition: sig_analog.c:1593
#define DAHDI_OVERLAPDIAL_OUTGOING
Definition: sig_pri.h:252
const ast_string_field name
struct ast_format * format
unsigned int faxdetect_timeout
The number of seconds into call to disable fax detection. (0 = disabled)
Definition: chan_dahdi.h:675
int waitfordialtoneduration
Transient variable. Stored off waitfordialtone duration at runtime.
Definition: chan_dahdi.h:664
unsigned int firstradio
TRUE if over a radio and dahdi_read() has been called.
Definition: chan_dahdi.h:280
short buffer[AST_FRIENDLY_OFFSET/2+READ_SIZE]
Definition: chan_dahdi.h:81
int tdd_feed(struct tdd_state *tdd, unsigned char *ubuf, int samples)
Definition: tdd.c:161

References __dahdi_exception(), ANALOG_DIALMODE_BOTH, ANALOG_DIALMODE_DTMF, analog_exception(), analog_handle_dtmf(), ast_channel_flags(), ast_channel_get_up_time(), ast_channel_name(), ast_channel_rawreadformat(), ast_channel_tech_pvt(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_debug, ast_dsp_get_tcount(), ast_dsp_get_tstate(), ast_dsp_process(), ast_dsp_set_features(), ast_dsp_was_muted(), AST_FLAG_BLOCKING, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_slin, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, ast_log, ast_mutex_trylock, ast_mutex_unlock, ast_null_frame, ast_queue_frame(), ast_setstate(), AST_STATE_DIALING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_tv(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, dahdi_subchannel::buffer, dahdi_pvt::busydetect, c, dahdi_pvt::callprogress, dahdi_pvt::callwaitcas, dahdi_pvt::callwaitingrepeat, dahdi_pvt::callwaitrings, dahdi_pvt::channel, CHANNEL_DEADLOCK_AVOIDANCE, CHECK_BLOCKING, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cidcwexpire, dahdi_pvt::cidspill, dahdi_analog_lib_handles(), dahdi_callwait(), dahdi_confmute(), dahdi_dial_str(), dahdi_get_index, dahdi_handle_dtmf(), DAHDI_OVERLAPDIAL_INCOMING, DAHDI_OVERLAPDIAL_OUTGOING, dahdi_setlinear(), dahdi_sig_pri_lib_handles(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, dahdi_subchannel::dfd, dahdi_pvt::dialing, dahdi_pvt::dialmode, dahdi_pvt::dialtone_detect, dahdi_pvt::dialtone_scanning_time_elapsed, dahdi_pvt::dop, dahdi_pvt::dsp, DSP_FEATURE_FAX_DETECT, DSP_FEATURE_WAITDIALTONE, dahdi_pvt::dsp_features, DSP_TONE_STATE_DIALTONE, DSP_TONE_STATE_RINGING, errno, dahdi_subchannel::f, dahdi_pvt::fake_event, dahdi_pvt::faxdetect_timeout, dahdi_pvt::firstradio, ast_frame_subclass::format, ast_frame::frametype, dahdi_pvt::ignoredtmf, dahdi_pvt::inalarm, ast_frame_subclass::integer, dahdi_subchannel::inthreeway, dahdi_subchannel::linear, dahdi_pvt::lock, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, dahdi_pvt::muting, ast_channel::name, dahdi_subchannel::needanswer, dahdi_subchannel::needbusy, dahdi_subchannel::needcongestion, dahdi_subchannel::needflash, dahdi_subchannel::needhold, dahdi_subchannel::needringing, dahdi_subchannel::needunhold, NULL, ast_frame::offset, dahdi_pvt::oprmode, dahdi_pvt::outgoing, dahdi_pvt::owner, ast_frame::ptr, dahdi_pvt::pulsedial, dahdi_pvt::radio, READ_SIZE, restore_conference(), dahdi_pvt::ringt, ast_frame::samples, send_callerid(), dahdi_pvt::sig, SIG_PRI_CALL_LEVEL_PROCEEDING, dahdi_pvt::sig_pvt, ast_frame::src, SUB_CALLWAIT, SUB_REAL, ast_frame::subclass, dahdi_pvt::subs, dahdi_pvt::tdd, tdd_feed(), dahdi_pvt::waitfordialtoneduration, and dahdi_pvt::waitingfordt.

◆ dahdi_request()

static struct ast_channel * dahdi_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

Definition at line 13903 of file chan_dahdi.c.

13906{
13907 int callwait = 0;
13908 struct dahdi_pvt *p;
13909 struct ast_channel *tmp = NULL;
13910 struct dahdi_pvt *exitpvt;
13911 int channelmatched = 0;
13912 int foundowner = 0;
13913 int groupmatched = 0;
13914#if defined(HAVE_PRI) || defined(HAVE_SS7)
13915 int transcapdigital = 0;
13916#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
13917 struct dahdi_starting_point start;
13918 ast_callid callid = 0;
13919 int callid_created = ast_callid_threadstorage_auto(&callid);
13920
13922 p = determine_starting_point(data, &start);
13923 if (!p) {
13924 /* We couldn't determine a starting point, which likely means badly-formatted channel name. Abort! */
13926 ast_callid_threadstorage_auto_clean(callid, callid_created);
13927 return NULL;
13928 }
13929
13930 /* Search for an unowned channel */
13931 exitpvt = p;
13932 while (p && !tmp) {
13933 if (start.roundrobin)
13934 round_robin[start.rr_starting_point] = p;
13935
13936 if (p->owner) {
13937 foundowner++;
13938 }
13939
13940 if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)
13941 && available(&p, channelmatched)) {
13942 ast_debug(1, "Using channel %d\n", p->channel);
13943
13944 callwait = (p->owner != NULL);
13945#ifdef HAVE_OPENR2
13946 if (p->mfcr2) {
13947 ast_mutex_lock(&p->lock);
13948 if (p->mfcr2call) {
13950 ast_debug(1, "Yay!, someone just beat us in the race for channel %d.\n", p->channel);
13951 goto next;
13952 }
13953 p->mfcr2call = 1;
13955 }
13956#endif
13957 if (p->channel == CHAN_PSEUDO) {
13958 p = duplicate_pseudo(p);
13959 if (!p) {
13960 break;
13961 }
13962 }
13963
13964 p->distinctivering = 0;
13965 /* Make special notes */
13966 switch (start.opt) {
13967 case '\0':
13968 /* No option present. */
13969 break;
13970 case 'c':
13971 /* Confirm answer */
13972 p->confirmanswer = 1;
13973 break;
13974 case 'r':
13975 /* Distinctive ring */
13976 p->distinctivering = start.cadence;
13977 break;
13978 case 'd':
13979#if defined(HAVE_PRI) || defined(HAVE_SS7)
13980 /* If this is an ISDN call, make it digital */
13981 transcapdigital = AST_TRANS_CAP_DIGITAL;
13982#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
13983 break;
13984 default:
13985 ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", start.opt, data);
13986 break;
13987 }
13988
13989 p->outgoing = 1;
13990 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
13991 tmp = analog_request(p->sig_pvt, &callwait, requestor);
13992#ifdef HAVE_PRI
13993 } else if (dahdi_sig_pri_lib_handles(p->sig)) {
13994 /*
13995 * We already have the B channel reserved for this call. We
13996 * just need to make sure that dahdi_hangup() has completed
13997 * cleaning up before continuing.
13998 */
13999 ast_mutex_lock(&p->lock);
14001
14003 sizeof(p->dnid));
14004 tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW, assignedids, requestor, transcapdigital);
14005#endif
14006#if defined(HAVE_SS7)
14007 } else if (p->sig == SIG_SS7) {
14008 tmp = sig_ss7_request(p->sig_pvt, SIG_SS7_DEFLAW, assignedids, requestor, transcapdigital);
14009#endif /* defined(HAVE_SS7) */
14010 } else {
14011 tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, assignedids, requestor, callid);
14012 }
14013 if (!tmp) {
14014 p->outgoing = 0;
14015#if defined(HAVE_PRI)
14016 switch (p->sig) {
14018#if defined(HAVE_PRI_CALL_WAITING)
14019 if (((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting) {
14020 ((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting = 0;
14021 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1);
14022 }
14023#endif /* defined(HAVE_PRI_CALL_WAITING) */
14024 /*
14025 * This should be the last thing to clear when we are done with
14026 * the channel.
14027 */
14028 ((struct sig_pri_chan *) p->sig_pvt)->allocated = 0;
14029 break;
14030 default:
14031 break;
14032 }
14033#endif /* defined(HAVE_PRI) */
14034 } else {
14035 snprintf(p->dialstring, sizeof(p->dialstring), "DAHDI/%s", data);
14036 }
14037 break;
14038 }
14039#ifdef HAVE_OPENR2
14040next:
14041#endif
14042 if (start.backwards) {
14043 p = p->prev;
14044 if (!p)
14045 p = ifend;
14046 } else {
14047 p = p->next;
14048 if (!p)
14049 p = iflist;
14050 }
14051 /* stop when you roll to the one that we started from */
14052 if (p == exitpvt)
14053 break;
14054 }
14057 if (cause && !tmp) {
14058 if (callwait || (channelmatched && foundowner)) {
14059 *cause = AST_CAUSE_BUSY;
14060 } else if (groupmatched) {
14061 *cause = AST_CAUSE_CONGESTION;
14062 } else {
14063 /*
14064 * We did not match any channel requested.
14065 * Dialplan error requesting non-existant channel?
14066 */
14067 }
14068 }
14069
14070 ast_callid_threadstorage_auto_clean(callid, callid_created);
14071 return tmp;
14072}
#define AST_CAUSE_BUSY
Definition: causes.h:149
static struct dahdi_pvt * round_robin[64]
Definition: chan_dahdi.c:3690
static int available(struct dahdi_pvt **pvt, int is_specific_channel)
Definition: chan_dahdi.c:13472
static struct dahdi_pvt * duplicate_pseudo(struct dahdi_pvt *src)
Definition: chan_dahdi.c:13678
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:757
struct ast_channel * analog_request(struct analog_pvt *p, int *callwait, const struct ast_channel *requestor)
Definition: sig_analog.c:770
@ SIG_PRI_DEFLAW
Definition: sig_pri.h:68
struct ast_channel * sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int transfercapability)
struct ast_channel * sig_ss7_request(struct sig_ss7_chan *p, enum sig_ss7_law law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int transfercapability)
@ SIG_SS7_DEFLAW
Definition: sig_ss7.h:89
char dialstring[AST_CHANNEL_NAME]
Definition: chan_dahdi.h:772
#define AST_TRANS_CAP_DIGITAL
Definition: transcap.h:36

References analog_request(), ast_atomic_fetchadd_int(), ast_callid_threadstorage_auto(), ast_callid_threadstorage_auto_clean(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, AST_STATE_RESERVED, AST_TRANS_CAP_DIGITAL, available(), dahdi_starting_point::backwards, dahdi_starting_point::cadence, CHAN_PSEUDO, dahdi_pvt::channel, dahdi_starting_point::channelmatch, dahdi_pvt::confirmanswer, dahdi_analog_lib_handles(), dahdi_new(), dahdi_sig_pri_lib_handles(), determine_starting_point(), dahdi_pvt::dialstring, dahdi_pvt::distinctivering, dahdi_pvt::dnid, duplicate_pseudo(), dahdi_starting_point::groupmatch, ifend, iflist, iflock, is_group_or_channel_match(), dahdi_pvt::lock, LOG_WARNING, dahdi_pvt::next, NULL, dahdi_pvt::oprmode, dahdi_starting_point::opt, dahdi_pvt::outgoing, dahdi_pvt::owner, dahdi_pvt::prev, dahdi_pvt::radio, restart_monitor(), round_robin, dahdi_starting_point::roundrobin, dahdi_starting_point::rr_starting_point, dahdi_pvt::sig, SIG_PRI_DEFLAW, sig_pri_extract_called_num_subaddr(), SIG_PRI_LIB_HANDLE_CASES, sig_pri_request(), dahdi_pvt::sig_pvt, SIG_SS7, SIG_SS7_DEFLAW, sig_ss7_request(), dahdi_starting_point::span, SUB_CALLWAIT, SUB_REAL, and tmp().

◆ dahdi_restart()

static int dahdi_restart ( void  )
static

Definition at line 15841 of file chan_dahdi.c.

15842{
15843#if defined(HAVE_PRI) || defined(HAVE_SS7)
15844 int i, j;
15845#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
15846 int cancel_code;
15847 struct dahdi_pvt *p;
15848
15850 ast_verb(1, "Destroying channels and reloading DAHDI configuration.\n");
15852 ast_verb(4, "Initial softhangup of all DAHDI channels complete.\n");
15853#ifdef HAVE_OPENR2
15854 dahdi_r2_destroy_links();
15855#endif
15856
15857#if defined(HAVE_PRI)
15858 for (i = 0; i < NUM_SPANS; i++) {
15859 if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) {
15860 cancel_code = pthread_cancel(pris[i].pri.master);
15861 pthread_kill(pris[i].pri.master, SIGURG);
15862 ast_debug(4, "Waiting to join thread of span %d with pid=%p, cancel_code=%d\n", i, (void *) pris[i].pri.master, cancel_code);
15863 pthread_join(pris[i].pri.master, NULL);
15864 ast_debug(4, "Joined thread of span %d\n", i);
15865 }
15866 }
15867#endif
15868
15869#if defined(HAVE_SS7)
15870 for (i = 0; i < NUM_SPANS; i++) {
15871 if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) {
15872 cancel_code = pthread_cancel(linksets[i].ss7.master);
15873 pthread_kill(linksets[i].ss7.master, SIGURG);
15874 ast_debug(4, "Waiting to join thread of span %d with pid=%p, cancel_code=%d\n", i, (void *) linksets[i].ss7.master, cancel_code);
15875 pthread_join(linksets[i].ss7.master, NULL);
15876 ast_debug(4, "Joined thread of span %d\n", i);
15877 }
15878 }
15879#endif /* defined(HAVE_SS7) */
15880
15883 cancel_code = pthread_cancel(monitor_thread);
15884 pthread_kill(monitor_thread, SIGURG);
15885 ast_debug(4, "Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (void *) monitor_thread, cancel_code);
15886 pthread_join(monitor_thread, NULL);
15887 ast_debug(4, "Joined monitor thread\n");
15888 }
15889 monitor_thread = AST_PTHREADT_NULL; /* prepare to restart thread in setup_dahdi once channels are reconfigured */
15890
15892 while (ss_thread_count > 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */
15893 int x = DAHDI_FLASH;
15894 ast_debug(3, "Waiting on %d analog_ss_thread(s) to finish\n", ss_thread_count);
15895
15897 for (p = iflist; p; p = p->next) {
15898 if (p->owner) {
15899 /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */
15900 ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
15901 }
15902 }
15905 }
15906
15907 /* ensure any created channels before monitor threads were stopped are hungup */
15909 ast_verb(4, "Final softhangup of all DAHDI channels complete.\n");
15911 memset(round_robin, 0, sizeof(round_robin));
15912 ast_debug(1, "Channels destroyed. Now re-reading config. %d active channels remaining.\n", ast_active_channels());
15913
15915
15916#ifdef HAVE_PRI
15917 for (i = 0; i < NUM_SPANS; i++) {
15918 for (j = 0; j < SIG_PRI_NUM_DCHANS; j++)
15919 dahdi_close_pri_fd(&(pris[i]), j);
15920 }
15921
15922 memset(pris, 0, sizeof(pris));
15923 for (i = 0; i < NUM_SPANS; i++) {
15924 sig_pri_init_pri(&pris[i].pri);
15925 }
15926 pri_set_error(dahdi_pri_error);
15927 pri_set_message(dahdi_pri_message);
15928#endif
15929#if defined(HAVE_SS7)
15930 for (i = 0; i < NUM_SPANS; i++) {
15931 for (j = 0; j < SIG_SS7_NUM_DCHANS; j++)
15932 dahdi_close_ss7_fd(&(linksets[i]), j);
15933 }
15934
15935 memset(linksets, 0, sizeof(linksets));
15936 for (i = 0; i < NUM_SPANS; i++) {
15937 sig_ss7_init_linkset(&linksets[i].ss7);
15938 }
15939 ss7_set_error(dahdi_ss7_error);
15940 ss7_set_message(dahdi_ss7_message);
15941 ss7_set_hangup(sig_ss7_cb_hangup);
15942 ss7_set_notinservice(sig_ss7_cb_notinservice);
15943 ss7_set_call_null(sig_ss7_cb_call_null);
15944#endif /* defined(HAVE_SS7) */
15945
15946 if (setup_dahdi(2) != 0) {
15947 ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n");
15949 return 1;
15950 }
15953 return 0;
15954}
static void dahdi_softhangup_all(void)
Definition: chan_dahdi.c:15813
static int setup_dahdi(int reload)
Definition: chan_dahdi.c:20250
static ast_mutex_t restart_lock
Definition: chan_dahdi.c:764
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:499
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
void sig_pri_init_pri(struct sig_pri_span *pri)
void sig_ss7_cb_call_null(struct ss7 *ss7, struct isup_call *c, int lock)
void sig_ss7_init_linkset(struct sig_ss7_linkset *ss7)
void sig_ss7_cb_notinservice(struct ss7 *ss7, int cic, unsigned int dpc)
int sig_ss7_cb_hangup(struct ss7 *ss7, int cic, unsigned int dpc, int cause, int do_hangup)

References ast_active_channels(), ast_cond_wait, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_verb, dahdi_softhangup_all(), destroy_all_channels(), dahdi_subchannel::dfd, iflist, iflock, LOG_WARNING, sig_pri_span::master, monitor_thread, monlock, dahdi_pvt::next, NULL, NUM_SPANS, dahdi_pvt::owner, restart_lock, round_robin, setup_dahdi(), sig_pri_init_pri(), SIG_PRI_NUM_DCHANS, sig_ss7_cb_call_null(), sig_ss7_cb_hangup(), sig_ss7_cb_notinservice(), sig_ss7_init_linkset(), SIG_SS7_NUM_DCHANS, ss_thread_complete, ss_thread_count, ss_thread_lock, SUB_REAL, and dahdi_pvt::subs.

Referenced by action_dahdirestart(), and dahdi_restart_cmd().

◆ dahdi_restart_cmd()

static char * dahdi_restart_cmd ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 15956 of file chan_dahdi.c.

15957{
15958 switch (cmd) {
15959 case CLI_INIT:
15960 e->command = "dahdi restart";
15961 e->usage =
15962 "Usage: dahdi restart\n"
15963 " Restarts the DAHDI channels: destroys them all and then\n"
15964 " re-reads them from chan_dahdi.conf.\n"
15965 " Note that this will STOP any running CALL on DAHDI channels.\n"
15966 "";
15967 return NULL;
15968 case CLI_GENERATE:
15969 return NULL;
15970 }
15971 if (a->argc != 2)
15972 return CLI_SHOWUSAGE;
15973
15974 if (dahdi_restart() != 0)
15975 return CLI_FAILURE;
15976 return CLI_SUCCESS;
15977}

References a, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_restart(), NULL, and ast_cli_entry::usage.

◆ dahdi_ring_phone()

static int dahdi_ring_phone ( struct dahdi_pvt p)
static

Definition at line 7464 of file chan_dahdi.c.

7465{
7466 int x;
7467 int res;
7468 /* Make sure our transmit state is on hook */
7469 x = 0;
7470 x = DAHDI_ONHOOK;
7471 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
7472 do {
7473 x = DAHDI_RING;
7474 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
7475 if (res) {
7476 switch (errno) {
7477 case EBUSY:
7478 case EINTR:
7479 /* Wait just in case */
7480 usleep(10000);
7481 continue;
7482 case EINPROGRESS:
7483 res = 0;
7484 break;
7485 default:
7486 ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
7487 res = 0;
7488 }
7489 }
7490 } while (res);
7491 return res;
7492}

References ast_log, dahdi_subchannel::dfd, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.

Referenced by __dahdi_exception(), dahdi_handle_event(), and my_ring().

◆ dahdi_sendtext()

static int dahdi_sendtext ( struct ast_channel c,
const char *  text 
)
static

Definition at line 20388 of file chan_dahdi.c.

20389{
20390#define END_SILENCE_LEN 400
20391#define HEADER_MS 50
20392#define TRAILER_MS 5
20393#define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
20394#define ASCII_BYTES_PER_CHAR 80
20395
20396 unsigned char *buf,*mybuf;
20397 struct dahdi_pvt *p = ast_channel_tech_pvt(c);
20398 struct pollfd fds[1];
20399 int size,res,fd,len,x;
20400 int bytes=0;
20401 int idx;
20402
20403 /*
20404 * Initial carrier (imaginary)
20405 *
20406 * Note: The following float variables are used by the
20407 * PUT_CLID_MARKMS and PUT_CLID() macros.
20408 */
20409 float cr = 1.0;
20410 float ci = 0.0;
20411 float scont = 0.0;
20412
20413 if (!text[0]) {
20414 return(0); /* if nothing to send, don't */
20415 }
20416 idx = dahdi_get_index(c, p, 0);
20417 if (idx < 0) {
20418 ast_log(LOG_WARNING, "Huh? I don't exist?\n");
20419 return -1;
20420 }
20421 if ((!p->tdd) && (!p->mate)) {
20422#if defined(HAVE_PRI)
20423#if defined(HAVE_PRI_DISPLAY_TEXT)
20424 ast_mutex_lock(&p->lock);
20426 sig_pri_sendtext(p->sig_pvt, text);
20427 }
20429#endif /* defined(HAVE_PRI_DISPLAY_TEXT) */
20430#endif /* defined(HAVE_PRI) */
20431 return(0); /* if not in TDD mode, just return */
20432 }
20433 if (p->mate)
20435 else
20436 buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
20437 if (!buf)
20438 return -1;
20439 mybuf = buf;
20440 if (p->mate) {
20441 /* PUT_CLI_MARKMS is a macro and requires a format ptr called codec to be present */
20442 struct ast_format *codec = AST_LAW(p);
20443
20444 for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */
20446 }
20447 /* Put actual message */
20448 for (x = 0; text[x]; x++) {
20449 PUT_CLID(text[x]);
20450 }
20451 for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */
20453 }
20454 len = bytes;
20455 buf = mybuf;
20456 } else {
20457 len = tdd_generate(p->tdd, buf, text);
20458 if (len < 1) {
20459 ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
20460 ast_free(mybuf);
20461 return -1;
20462 }
20463 }
20464 memset(buf + len, 0x7f, END_SILENCE_LEN);
20466 fd = p->subs[idx].dfd;
20467 while (len) {
20468 if (ast_check_hangup(c)) {
20469 ast_free(mybuf);
20470 return -1;
20471 }
20472 size = len;
20473 if (size > READ_SIZE)
20474 size = READ_SIZE;
20475 fds[0].fd = fd;
20476 fds[0].events = POLLOUT | POLLPRI;
20477 fds[0].revents = 0;
20478 res = poll(fds, 1, -1);
20479 if (!res) {
20480 ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel);
20481 continue;
20482 }
20483 /* if got exception */
20484 if (fds[0].revents & POLLPRI) {
20485 ast_free(mybuf);
20486 return -1;
20487 }
20488 if (!(fds[0].revents & POLLOUT)) {
20489 ast_debug(1, "write fd not ready on channel %d\n", p->channel);
20490 continue;
20491 }
20492 res = write(fd, buf, size);
20493 if (res != size) {
20494 if (res == -1) {
20495 ast_free(mybuf);
20496 return -1;
20497 }
20498 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
20499 break;
20500 }
20501 len -= size;
20502 buf += size;
20503 }
20504 ast_free(mybuf);
20505 return(0);
20506}
char * text
Definition: app_queue.c:1639
#define PUT_CLID(byte)
Definition: callerid.h:412
#define PUT_CLID_MARKMS
Definition: callerid.h:397
#define HEADER_MS
#define END_SILENCE_LEN
#define TRAILER_MS
#define ASCII_BYTES_PER_CHAR
#define HEADER_LEN
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
struct ast_codec * codec
Pointer to the codec in use for this format.
Definition: format.c:47
#define TDD_BYTES_PER_CHAR
Definition: tdd.h:27
int tdd_generate(struct tdd_state *tdd, unsigned char *buf, const char *string)
Definition: tdd.c:296

References ASCII_BYTES_PER_CHAR, ast_channel_tech_pvt(), ast_check_hangup(), ast_debug, ast_free, AST_LAW, ast_log, ast_malloc, ast_mutex_lock, ast_mutex_unlock, buf, c, dahdi_pvt::channel, ast_format::codec, dahdi_get_index, dahdi_sig_pri_lib_handles(), dahdi_subchannel::dfd, END_SILENCE_LEN, errno, HEADER_LEN, HEADER_MS, len(), dahdi_pvt::lock, LOG_ERROR, LOG_WARNING, dahdi_pvt::mate, PUT_CLID, PUT_CLID_MARKMS, READ_SIZE, dahdi_pvt::sig, dahdi_pvt::sig_pvt, dahdi_pvt::subs, dahdi_pvt::tdd, TDD_BYTES_PER_CHAR, tdd_generate(), text, and TRAILER_MS.

◆ dahdi_set_dnd()

static char * dahdi_set_dnd ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 16595 of file chan_dahdi.c.

16596{
16597 int channel;
16598 int on;
16599 struct dahdi_pvt *dahdi_chan = NULL;
16600
16601 switch (cmd) {
16602 case CLI_INIT:
16603 e->command = "dahdi set dnd";
16604 e->usage =
16605 "Usage: dahdi set dnd <chan#> <on|off>\n"
16606 " Sets/resets DND (Do Not Disturb) mode on a channel.\n"
16607 " Changes take effect immediately.\n"
16608 " <chan num> is the channel number\n"
16609 " <on|off> Enable or disable DND mode?\n"
16610 ;
16611 return NULL;
16612 case CLI_GENERATE:
16613 return NULL;
16614 }
16615
16616 if (a->argc != 5)
16617 return CLI_SHOWUSAGE;
16618
16619 if ((channel = atoi(a->argv[3])) <= 0) {
16620 ast_cli(a->fd, "Expected channel number, got '%s'\n", a->argv[3]);
16621 return CLI_SHOWUSAGE;
16622 }
16623
16624 if (ast_true(a->argv[4]))
16625 on = 1;
16626 else if (ast_false(a->argv[4]))
16627 on = 0;
16628 else {
16629 ast_cli(a->fd, "Expected 'on' or 'off', got '%s'\n", a->argv[4]);
16630 return CLI_SHOWUSAGE;
16631 }
16632
16634 for (dahdi_chan = iflist; dahdi_chan; dahdi_chan = dahdi_chan->next) {
16635 if (dahdi_chan->channel != channel)
16636 continue;
16637
16638 /* Found the channel. Actually set it */
16639 dahdi_dnd(dahdi_chan, on);
16640 break;
16641 }
16643
16644 if (!dahdi_chan) {
16645 ast_cli(a->fd, "Unable to find given channel %d\n", channel);
16646 return CLI_FAILURE;
16647 }
16648
16649 return CLI_SUCCESS;
16650}
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
Definition: utils.c:2216

References a, ast_cli(), ast_false(), ast_mutex_lock, ast_mutex_unlock, ast_true(), dahdi_pvt::channel, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_dnd(), iflist, iflock, dahdi_pvt::next, NULL, and ast_cli_entry::usage.

◆ dahdi_set_hook()

static int dahdi_set_hook ( int  fd,
int  hs 
)
inlinestatic

Definition at line 5182 of file chan_dahdi.c.

5183{
5184 int x, res;
5185
5186 x = hs;
5187 res = ioctl(fd, DAHDI_HOOK, &x);
5188
5189 if (res < 0) {
5190 if (errno == EINPROGRESS)
5191 return 0;
5192 ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno));
5193 /* will expectedly fail if phone is off hook during operation, such as during a restart */
5194 }
5195
5196 return res;
5197}

References ast_log, errno, and LOG_WARNING.

Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_handle_event(), dahdi_hangup(), dahdi_indicate(), dahdi_wink(), handle_init_event(), mkintf(), mwi_send_process_buffer(), mwi_send_process_event(), my_off_hook(), and my_on_hook().

◆ dahdi_set_hwgain()

static char * dahdi_set_hwgain ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 16438 of file chan_dahdi.c.

16439{
16440 int channel;
16441 float gain;
16442 int tx;
16443 struct dahdi_pvt *tmp = NULL;
16444
16445 switch (cmd) {
16446 case CLI_INIT:
16447 e->command = "dahdi set hwgain {rx|tx}";
16448 e->usage =
16449 "Usage: dahdi set hwgain <rx|tx> <chan#> <gain>\n"
16450 " Sets the hardware gain on a given channel and overrides the\n"
16451 " value provided at module loadtime. Changes take effect\n"
16452 " immediately whether the channel is in use or not.\n"
16453 "\n"
16454 " <rx|tx> which direction do you want to change (relative to our module)\n"
16455 " <chan num> is the channel number relative to the device\n"
16456 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"
16457 "\n"
16458 " Please note:\n"
16459 " * hwgain is only supportable by hardware with analog ports because\n"
16460 " hwgain works on the analog side of an analog-digital conversion.\n";
16461 return NULL;
16462 case CLI_GENERATE:
16463 return NULL;
16464 }
16465
16466 if (a->argc != 6)
16467 return CLI_SHOWUSAGE;
16468
16469 if (!strcasecmp("rx", a->argv[3]))
16470 tx = 0; /* rx */
16471 else if (!strcasecmp("tx", a->argv[3]))
16472 tx = 1; /* tx */
16473 else
16474 return CLI_SHOWUSAGE;
16475
16476 channel = atoi(a->argv[4]);
16477 gain = atof(a->argv[5]);
16478
16480
16481 for (tmp = iflist; tmp; tmp = tmp->next) {
16482
16483 if (tmp->channel != channel)
16484 continue;
16485
16486 if (tmp->subs[SUB_REAL].dfd == -1)
16487 break;
16488
16489 if (set_hwgain(tmp->subs[SUB_REAL].dfd, gain, tx)) {
16490 ast_cli(a->fd, "Unable to set the hardware gain for channel %d: %s\n", channel, strerror(errno));
16492 return CLI_FAILURE;
16493 }
16494 ast_cli(a->fd, "Hardware %s gain set to %.1f dB on channel %d.\n",
16495 tx ? "tx" : "rx", gain, channel);
16496
16497 if (tx) {
16498 tmp->hwtxgain_enabled = 1;
16499 tmp->hwtxgain = gain;
16500 } else {
16501 tmp->hwrxgain_enabled = 1;
16502 tmp->hwrxgain = gain;
16503 }
16504 break;
16505 }
16506
16508
16509 if (tmp)
16510 return CLI_SUCCESS;
16511
16512 ast_cli(a->fd, "Unable to find given channel %d\n", channel);
16513 return CLI_FAILURE;
16514
16515}
static int set_hwgain(int fd, float gain, int tx_direction)
Definition: chan_dahdi.c:4988

References a, ast_cli(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, errno, iflist, iflock, NULL, set_hwgain(), SUB_REAL, tmp(), and ast_cli_entry::usage.

◆ dahdi_set_mwi()

static char * dahdi_set_mwi ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 16652 of file chan_dahdi.c.

16653{
16654 int channel;
16655 int on;
16656 int override = 1;
16657 struct dahdi_pvt *dahdi_chan = NULL;
16658
16659 switch (cmd) {
16660 case CLI_INIT:
16661 e->command = "dahdi set mwi";
16662 e->usage =
16663 "Usage: dahdi set mwi <chan#> <on|off|reset>\n"
16664 " Sets/unsets MWI (Message Waiting Indicator) manually on a channel.\n"
16665 " This may be used regardless of whether the channel is assigned any mailboxes.\n"
16666 " When active, this setting will override the voicemail status to set MWI.\n"
16667 " Once cleared, the voicemail status will resume control of MWI.\n"
16668 " Changes are queued for when the channel is idle and persist until cleared.\n"
16669 " <chan num> is the channel number\n"
16670 " <on|off|reset> Enable, disable, or reset Message Waiting Indicator override?\n"
16671 ;
16672 return NULL;
16673 case CLI_GENERATE:
16674 return NULL;
16675 }
16676
16677 if (a->argc != 5)
16678 return CLI_SHOWUSAGE;
16679
16680 if ((channel = atoi(a->argv[3])) <= 0) {
16681 ast_cli(a->fd, "Expected channel number, got '%s'\n", a->argv[3]);
16682 return CLI_SHOWUSAGE;
16683 }
16684
16685 if (ast_true(a->argv[4])) {
16686 on = 1;
16687 } else if (ast_false(a->argv[4])) {
16688 on = 0;
16689 } else if (!strcmp(a->argv[4], "reset")) {
16690 override = 0;
16691 } else {
16692 ast_cli(a->fd, "Expected 'on' or 'off' or 'reset', got '%s'\n", a->argv[4]);
16693 return CLI_SHOWUSAGE;
16694 }
16695
16697 for (dahdi_chan = iflist; dahdi_chan; dahdi_chan = dahdi_chan->next) {
16698 if (dahdi_chan->channel != channel)
16699 continue;
16700
16701 /* Found the channel. Actually set it */
16702 if (override) {
16703 dahdi_chan->mwioverride_disposition = on;
16704 ast_cli(a->fd, "MWI '%s' queued for channel %d\n", on ? "enable" : "disable", channel);
16705 }
16706 dahdi_chan->mwioverride_active = override;
16707 /* The do_monitor thread will take care of actually sending the MWI
16708 * at an appropriate time for the channel. */
16709 break;
16710 }
16712
16713 if (!dahdi_chan) {
16714 ast_cli(a->fd, "Unable to find given channel %d\n", channel);
16715 return CLI_FAILURE;
16716 }
16717
16718 return CLI_SUCCESS;
16719}
unsigned int mwioverride_active
TRUE if a manual MWI override is active for a channel.
Definition: chan_dahdi.h:435
unsigned int mwioverride_disposition
Manual MWI disposition (on/off)
Definition: chan_dahdi.h:437

References a, ast_cli(), ast_false(), ast_mutex_lock, ast_mutex_unlock, ast_true(), dahdi_pvt::channel, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iflist, iflock, dahdi_pvt::mwioverride_active, dahdi_pvt::mwioverride_disposition, dahdi_pvt::next, NULL, and ast_cli_entry::usage.

◆ dahdi_set_swgain()

static char * dahdi_set_swgain ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 16517 of file chan_dahdi.c.

16518{
16519 int channel;
16520 float gain;
16521 int tx;
16522 int res;
16523 struct dahdi_pvt *tmp = NULL;
16524
16525 switch (cmd) {
16526 case CLI_INIT:
16527 e->command = "dahdi set swgain {rx|tx}";
16528 e->usage =
16529 "Usage: dahdi set swgain <rx|tx> <chan#> <gain>\n"
16530 " Sets the software gain on a given channel and overrides the\n"
16531 " value provided at module loadtime. Changes take effect\n"
16532 " immediately whether the channel is in use or not.\n"
16533 "\n"
16534 " <rx|tx> which direction do you want to change (relative to our module)\n"
16535 " <chan num> is the channel number relative to the device\n"
16536 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n";
16537 return NULL;
16538 case CLI_GENERATE:
16539 return NULL;
16540 }
16541
16542 if (a->argc != 6)
16543 return CLI_SHOWUSAGE;
16544
16545 if (!strcasecmp("rx", a->argv[3]))
16546 tx = 0; /* rx */
16547 else if (!strcasecmp("tx", a->argv[3]))
16548 tx = 1; /* tx */
16549 else
16550 return CLI_SHOWUSAGE;
16551
16552 channel = atoi(a->argv[4]);
16553 gain = atof(a->argv[5]);
16554
16556 for (tmp = iflist; tmp; tmp = tmp->next) {
16557
16558 if (tmp->channel != channel)
16559 continue;
16560
16561 if (tmp->subs[SUB_REAL].dfd == -1)
16562 break;
16563
16564 if (tx)
16565 res = set_actual_txgain(tmp->subs[SUB_REAL].dfd, gain, tmp->txdrc, tmp->law);
16566 else
16567 res = set_actual_rxgain(tmp->subs[SUB_REAL].dfd, gain, tmp->rxdrc, tmp->law);
16568
16569 if (res) {
16570 ast_cli(a->fd, "Unable to set the software gain for channel %d\n", channel);
16572 return CLI_FAILURE;
16573 }
16574
16575 ast_cli(a->fd, "Software %s gain set to %.2f dB on channel %d.\n",
16576 tx ? "tx" : "rx", gain, channel);
16577
16578 if (tx) {
16579 tmp->txgain = gain;
16580 } else {
16581 tmp->rxgain = gain;
16582 }
16583 break;
16584 }
16586
16587 if (tmp)
16588 return CLI_SUCCESS;
16589
16590 ast_cli(a->fd, "Unable to find given channel %d\n", channel);
16591 return CLI_FAILURE;
16592
16593}
static int set_actual_txgain(int fd, float gain, float drc, int law)
Definition: chan_dahdi.c:5116
static int set_actual_rxgain(int fd, float gain, float drc, int law)
Definition: chan_dahdi.c:5133

References a, ast_cli(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iflist, iflock, NULL, set_actual_rxgain(), set_actual_txgain(), SUB_REAL, tmp(), and ast_cli_entry::usage.

◆ dahdi_setlinear()

static int dahdi_setlinear ( int  dfd,
int  linear 
)
static

Definition at line 4421 of file chan_dahdi.c.

4422{
4423 return ioctl(dfd, DAHDI_SETLINEAR, &linear);
4424}

Referenced by analog_ss_thread(), dahdi_hangup(), dahdi_new(), dahdi_read(), dahdi_write(), my_all_subchannels_hungup(), my_set_linear_mode(), my_start_cid_detect(), my_stop_cid_detect(), and send_callerid().

◆ dahdi_setoption()

static int dahdi_setoption ( struct ast_channel chan,
int  option,
void *  data,
int  datalen 
)
static
Todo:
XXX This is an abuse of the stack!!

Definition at line 6843 of file chan_dahdi.c.

6844{
6845 char *cp;
6846 signed char *scp;
6847 int x;
6848 int idx;
6849 struct dahdi_pvt *p = ast_channel_tech_pvt(chan), *pp;
6850 struct oprmode *oprmode;
6851
6852
6853 /* all supported options require data */
6854 if (!p || !data || (datalen < 1)) {
6855 errno = EINVAL;
6856 return -1;
6857 }
6858
6859 switch (option) {
6860 case AST_OPTION_TXGAIN:
6861 scp = (signed char *) data;
6862 idx = dahdi_get_index(chan, p, 0);
6863 if (idx < 0) {
6864 ast_log(LOG_WARNING, "No index in TXGAIN?\n");
6865 return -1;
6866 }
6867 ast_debug(1, "Setting actual tx gain on %s to %f\n", ast_channel_name(chan), p->txgain + (float) *scp);
6868 return set_actual_txgain(p->subs[idx].dfd, p->txgain + (float) *scp, p->txdrc, p->law);
6869 case AST_OPTION_RXGAIN:
6870 scp = (signed char *) data;
6871 idx = dahdi_get_index(chan, p, 0);
6872 if (idx < 0) {
6873 ast_log(LOG_WARNING, "No index in RXGAIN?\n");
6874 return -1;
6875 }
6876 ast_debug(1, "Setting actual rx gain on %s to %f\n", ast_channel_name(chan), p->rxgain + (float) *scp);
6877 return set_actual_rxgain(p->subs[idx].dfd, p->rxgain + (float) *scp, p->rxdrc, p->law);
6879 if (!p->dsp)
6880 break;
6881 cp = (char *) data;
6882 switch (*cp) {
6883 case 1:
6884 ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",ast_channel_name(chan));
6885 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */
6886 break;
6887 case 2:
6888 ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",ast_channel_name(chan));
6889 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */
6890 break;
6891 default:
6892 ast_debug(1, "Set option TONE VERIFY, mode: OFF(0) on %s\n",ast_channel_name(chan));
6893 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */
6894 break;
6895 }
6896 break;
6897 case AST_OPTION_TDD:
6898 /* turn on or off TDD */
6899 cp = (char *) data;
6900 p->mate = 0;
6901 if (!*cp) { /* turn it off */
6902 ast_debug(1, "Set option TDD MODE, value: OFF(0) on %s\n",ast_channel_name(chan));
6903 if (p->tdd)
6904 tdd_free(p->tdd);
6905 p->tdd = 0;
6906 break;
6907 }
6908 ast_debug(1, "Set option TDD MODE, value: %s(%d) on %s\n",
6909 (*cp == 2) ? "MATE" : "ON", (int) *cp, ast_channel_name(chan));
6911 /* otherwise, turn it on */
6912 if (!p->didtdd) { /* if havent done it yet */
6913 unsigned char mybuf[41000];/*! \todo XXX This is an abuse of the stack!! */
6914 unsigned char *buf;
6915 int size, res, fd, len;
6916 struct pollfd fds[1];
6917
6918 buf = mybuf;
6919 memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
6920 ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */
6921 len = 40000;
6922 idx = dahdi_get_index(chan, p, 0);
6923 if (idx < 0) {
6924 ast_log(LOG_WARNING, "No index in TDD?\n");
6925 return -1;
6926 }
6927 fd = p->subs[idx].dfd;
6928 while (len) {
6929 if (ast_check_hangup(chan))
6930 return -1;
6931 size = len;
6932 if (size > READ_SIZE)
6933 size = READ_SIZE;
6934 fds[0].fd = fd;
6935 fds[0].events = POLLPRI | POLLOUT;
6936 fds[0].revents = 0;
6937 res = poll(fds, 1, -1);
6938 if (!res) {
6939 ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel);
6940 continue;
6941 }
6942 /* if got exception */
6943 if (fds[0].revents & POLLPRI)
6944 return -1;
6945 if (!(fds[0].revents & POLLOUT)) {
6946 ast_debug(1, "write fd not ready on channel %d\n", p->channel);
6947 continue;
6948 }
6949 res = write(fd, buf, size);
6950 if (res != size) {
6951 if (res == -1) return -1;
6952 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
6953 break;
6954 }
6955 len -= size;
6956 buf += size;
6957 }
6958 p->didtdd = 1; /* set to have done it now */
6959 }
6960 if (*cp == 2) { /* Mate mode */
6961 if (p->tdd)
6962 tdd_free(p->tdd);
6963 p->tdd = 0;
6964 p->mate = 1;
6965 break;
6966 }
6967 if (!p->tdd) { /* if we don't have one yet */
6968 p->tdd = tdd_new(); /* allocate one */
6969 }
6970 break;
6971 case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */
6972 if (!p->dsp)
6973 break;
6974 cp = (char *) data;
6975 ast_debug(1, "Set option RELAX DTMF, value: %s(%d) on %s\n",
6976 *cp ? "ON" : "OFF", (int) *cp, ast_channel_name(chan));
6978 break;
6979 case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */
6980#if defined(HAVE_PRI)
6982 && ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
6983 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */
6984 break;
6985 }
6986#endif /* defined(HAVE_PRI) */
6987
6988 cp = (char *) data;
6989 if (!*cp) {
6990 ast_debug(1, "Set option AUDIO MODE, value: OFF(0) on %s\n", ast_channel_name(chan));
6991 x = 0;
6993 } else {
6994 ast_debug(1, "Set option AUDIO MODE, value: ON(1) on %s\n", ast_channel_name(chan));
6995 x = 1;
6996 }
6997 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x) == -1)
6998 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, x, strerror(errno));
6999 break;
7000 case AST_OPTION_OPRMODE: /* Operator services mode */
7001 oprmode = (struct oprmode *) data;
7002 /* We don't support operator mode across technologies */
7003 if (strcasecmp(ast_channel_tech(chan)->type, ast_channel_tech(oprmode->peer)->type)) {
7004 ast_log(LOG_NOTICE, "Operator mode not supported on %s to %s calls.\n",
7006 errno = EINVAL;
7007 return -1;
7008 }
7010 p->oprmode = pp->oprmode = 0;
7011 /* setup peers */
7012 p->oprpeer = pp;
7013 pp->oprpeer = p;
7014 /* setup modes, if any */
7015 if (oprmode->mode)
7016 {
7017 pp->oprmode = oprmode->mode;
7018 p->oprmode = -oprmode->mode;
7019 }
7020 ast_debug(1, "Set Operator Services mode, value: %d on %s/%s\n",
7022 break;
7023 case AST_OPTION_ECHOCAN:
7024 cp = (char *) data;
7025 if (*cp) {
7026 ast_debug(1, "Enabling echo cancellation on %s\n", ast_channel_name(chan));
7027 dahdi_ec_enable(p);
7028 } else {
7029 ast_debug(1, "Disabling echo cancellation on %s\n", ast_channel_name(chan));
7031 }
7032 break;
7034 cp = (char *) data;
7035 ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", ast_channel_name(chan));
7036 if (*cp) {
7038 } else {
7040 }
7041 break;
7043 cp = (char *) data;
7044 if (p->dsp) {
7045 ast_debug(1, "%sabling fax tone detection on %s\n", *cp ? "En" : "Dis", ast_channel_name(chan));
7046 if (*cp) {
7048 } else {
7049 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
7050 }
7052 }
7053 break;
7054 default:
7055 return -1;
7056 }
7057 errno = 0;
7058
7059 return 0;
7060}
void dahdi_dtmf_detect_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:6777
void dahdi_dtmf_detect_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:6763
#define DSP_DIGITMODE_MUTEMAX
Definition: dsp.h:36
#define DSP_DIGITMODE_MUTECONF
Definition: dsp.h:35
#define DSP_DIGITMODE_RELAXDTMF
Definition: dsp.h:37
#define AST_OPTION_RELAXDTMF
#define AST_OPTION_RXGAIN
#define AST_OPTION_OPRMODE
#define AST_OPTION_TXGAIN
#define AST_OPTION_ECHOCAN
const char *const type
Definition: channel.h:629
struct ast_channel * peer
struct tdd_state * tdd_new(void)
Definition: tdd.c:103
void tdd_free(struct tdd_state *tdd)
Definition: tdd.c:218
int ast_tdd_gen_ecdisa(unsigned char *outbuf, int len)
Definition: tdd.c:148

References ast_channel_name(), ast_channel_tech(), ast_channel_tech_pvt(), ast_check_hangup(), ast_debug, ast_dsp_set_digitmode(), ast_dsp_set_features(), ast_log, AST_OPTION_AUDIO_MODE, AST_OPTION_DIGIT_DETECT, AST_OPTION_ECHOCAN, AST_OPTION_FAX_DETECT, AST_OPTION_OPRMODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_tdd_gen_ecdisa(), buf, dahdi_pvt::channel, dahdi_dtmf_detect_disable(), dahdi_dtmf_detect_enable(), dahdi_ec_disable(), dahdi_ec_enable(), dahdi_get_index, dahdi_sig_pri_lib_handles(), dahdi_subchannel::dfd, dahdi_pvt::didtdd, dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_FAX_DETECT, dahdi_pvt::dsp_features, dahdi_pvt::dtmfrelax, errno, dahdi_pvt::law, len(), LOG_NOTICE, LOG_WARNING, dahdi_pvt::mate, oprmode::mode, dahdi_pvt::oprmode, dahdi_pvt::oprpeer, oprmode::peer, READ_SIZE, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, set_actual_rxgain(), set_actual_txgain(), dahdi_pvt::sig, dahdi_pvt::sig_pvt, SUB_REAL, dahdi_pvt::subs, dahdi_pvt::tdd, tdd_free(), tdd_new(), dahdi_pvt::txdrc, dahdi_pvt::txgain, type, and ast_channel_tech::type.

◆ dahdi_show_channel()

static char * dahdi_show_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 16070 of file chan_dahdi.c.

16071{
16072 int channel;
16073 struct dahdi_pvt *tmp = NULL;
16074 struct dahdi_confinfo ci;
16075 struct dahdi_params ps;
16076 int x;
16077 char hwrxgain[15];
16078 char hwtxgain[15];
16079
16080 switch (cmd) {
16081 case CLI_INIT:
16082 e->command = "dahdi show channel";
16083 e->usage =
16084 "Usage: dahdi show channel <chan num>\n"
16085 " Detailed information about a given channel\n";
16086 return NULL;
16087 case CLI_GENERATE:
16088 return NULL;
16089 }
16090
16091 if (a->argc != 4)
16092 return CLI_SHOWUSAGE;
16093
16094 channel = atoi(a->argv[3]);
16095
16097 for (tmp = iflist; tmp; tmp = tmp->next) {
16098 if (tmp->channel == channel) {
16099 ast_cli(a->fd, "Channel: %d\n", tmp->channel);
16100 ast_cli(a->fd, "Description: %s\n", tmp->description);
16101 ast_cli(a->fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].dfd);
16102 ast_cli(a->fd, "Span: %d\n", tmp->span);
16103 ast_cli(a->fd, "Extension: %s\n", tmp->exten);
16104 ast_cli(a->fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
16105 ast_cli(a->fd, "Context: %s\n", tmp->context);
16106 ast_cli(a->fd, "Caller ID: %s\n", tmp->cid_num);
16107 ast_cli(a->fd, "Calling TON: %d\n", tmp->cid_ton);
16108#if defined(HAVE_PRI)
16109#if defined(HAVE_PRI_SUBADDR)
16110 ast_cli(a->fd, "Caller ID subaddress: %s\n", tmp->cid_subaddr);
16111#endif /* defined(HAVE_PRI_SUBADDR) */
16112#endif /* defined(HAVE_PRI) */
16113 ast_cli(a->fd, "Caller ID name: %s\n", tmp->cid_name);
16114 ast_cli(a->fd, "Mailbox: %s\n", S_OR(tmp->mailbox, "none"));
16115 if (tmp->vars) {
16116 struct ast_variable *v;
16117 ast_cli(a->fd, "Variables:\n");
16118 for (v = tmp->vars ; v ; v = v->next)
16119 ast_cli(a->fd, " %s = %s\n", v->name, v->value);
16120 }
16121 ast_cli(a->fd, "Destroy: %d\n", tmp->destroy);
16122 ast_cli(a->fd, "InAlarm: %d\n", tmp->inalarm);
16123 ast_cli(a->fd, "Signalling Type: %s\n", sig2str(tmp->sig));
16124 ast_cli(a->fd, "Radio: %d\n", tmp->radio);
16125 ast_cli(a->fd, "Owner: %s\n", tmp->owner ? ast_channel_name(tmp->owner) : "<None>");
16126 ast_cli(a->fd, "Real: %s%s%s\n", tmp->subs[SUB_REAL].owner ? ast_channel_name(tmp->subs[SUB_REAL].owner) : "<None>", tmp->subs[SUB_REAL].inthreeway ? " (Confed)" : "", tmp->subs[SUB_REAL].linear ? " (Linear)" : "");
16127 ast_cli(a->fd, "Callwait: %s%s%s\n", tmp->subs[SUB_CALLWAIT].owner ? ast_channel_name(tmp->subs[SUB_CALLWAIT].owner) : "<None>", tmp->subs[SUB_CALLWAIT].inthreeway ? " (Confed)" : "", tmp->subs[SUB_CALLWAIT].linear ? " (Linear)" : "");
16128 ast_cli(a->fd, "Threeway: %s%s%s\n", tmp->subs[SUB_THREEWAY].owner ? ast_channel_name(tmp->subs[SUB_THREEWAY].owner) : "<None>", tmp->subs[SUB_THREEWAY].inthreeway ? " (Confed)" : "", tmp->subs[SUB_THREEWAY].linear ? " (Linear)" : "");
16129 ast_cli(a->fd, "Confno: %d\n", tmp->confno);
16130 ast_cli(a->fd, "Propagated Conference: %d\n", tmp->propconfno);
16131 ast_cli(a->fd, "Real in conference: %d\n", tmp->inconference);
16132 ast_cli(a->fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
16133 ast_cli(a->fd, "Busy Detection: %s\n", tmp->busydetect ? "yes" : "no");
16134 if (tmp->busydetect) {
16135#if defined(BUSYDETECT_TONEONLY)
16136 ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_TONEONLY\n");
16137#elif defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
16138 ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_COMPARE_TONE_AND_SILENCE\n");
16139#endif
16140#ifdef BUSYDETECT_DEBUG
16141 ast_cli(a->fd, " Busy Detector Debug: Enabled\n");
16142#endif
16143 ast_cli(a->fd, " Busy Count: %d\n", tmp->busycount);
16144 ast_cli(a->fd, " Busy Pattern: %d,%d,%d,%d\n", tmp->busy_cadence.pattern[0], tmp->busy_cadence.pattern[1], (tmp->busy_cadence.length == 4) ? tmp->busy_cadence.pattern[2] : 0, (tmp->busy_cadence.length == 4) ? tmp->busy_cadence.pattern[3] : 0);
16145 }
16146 ast_cli(a->fd, "TDD: %s\n", tmp->tdd ? "yes" : "no");
16147 ast_cli(a->fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
16148 ast_cli(a->fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
16149 ast_cli(a->fd, "Default law: %s\n", tmp->law_default == DAHDI_LAW_MULAW ? "ulaw" : tmp->law_default == DAHDI_LAW_ALAW ? "alaw" : "unknown");
16150 ast_cli(a->fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
16151 ast_cli(a->fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
16152 if (tmp->hwrxgain_enabled) {
16153 snprintf(hwrxgain, sizeof(hwrxgain), "%.1f", tmp->hwrxgain);
16154 } else {
16155 ast_copy_string(hwrxgain, "Disabled", sizeof(hwrxgain));
16156 }
16157 if (tmp->hwtxgain_enabled) {
16158 snprintf(hwtxgain, sizeof(hwtxgain), "%.1f", tmp->hwtxgain);
16159 } else {
16160 ast_copy_string(hwtxgain, "Disabled", sizeof(hwtxgain));
16161 }
16162 ast_cli(a->fd, "HW Gains (RX/TX): %s/%s\n", hwrxgain, hwtxgain);
16163 ast_cli(a->fd, "SW Gains (RX/TX): %.2f/%.2f\n", tmp->rxgain, tmp->txgain);
16164 ast_cli(a->fd, "Dynamic Range Compression (RX/TX): %.2f/%.2f\n", tmp->rxdrc, tmp->txdrc);
16165 ast_cli(a->fd, "DND: %s\n", dahdi_dnd(tmp, -1) ? "yes" : "no");
16166 ast_cli(a->fd, "Echo Cancellation:\n");
16167
16168 if (tmp->echocancel.head.tap_length) {
16169 ast_cli(a->fd, "\t%u taps\n", tmp->echocancel.head.tap_length);
16170 for (x = 0; x < tmp->echocancel.head.param_count; x++) {
16171 ast_cli(a->fd, "\t\t%s: %dd\n", tmp->echocancel.params[x].name, tmp->echocancel.params[x].value);
16172 }
16173 ast_cli(a->fd, "\t%scurrently %s\n", tmp->echocanbridged ? "" : "(unless TDM bridged) ", tmp->echocanon ? "ON" : "OFF");
16174 } else {
16175 ast_cli(a->fd, "\tnone\n");
16176 }
16177 ast_cli(a->fd, "Wait for dialtone: %dms\n", tmp->waitfordialtone);
16178 if (tmp->master)
16179 ast_cli(a->fd, "Master Channel: %d\n", tmp->master->channel);
16180 for (x = 0; x < MAX_SLAVES; x++) {
16181 if (tmp->slaves[x])
16182 ast_cli(a->fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
16183 }
16184#ifdef HAVE_OPENR2
16185 if (tmp->mfcr2) {
16186 char calldir[OR2_MAX_PATH];
16187 openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan);
16188 openr2_variant_t r2variant = openr2_context_get_variant(r2context);
16189 ast_cli(a->fd, "MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan));
16190 ast_cli(a->fd, "MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan));
16191 ast_cli(a->fd, "MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan));
16192 ast_cli(a->fd, "MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan));
16193 ast_cli(a->fd, "MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ? "Yes" : "No");
16194 ast_cli(a->fd, "MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant));
16195 ast_cli(a->fd, "MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context));
16196 ast_cli(a->fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context));
16197#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
16198 ast_cli(a->fd, "MFC/R2 DTMF Dialing: %s\n", openr2_context_get_dtmf_dialing(r2context, NULL, NULL) ? "Yes" : "No");
16199 ast_cli(a->fd, "MFC/R2 DTMF Detection: %s\n", openr2_context_get_dtmf_detection(r2context) ? "Yes" : "No");
16200#endif
16201 ast_cli(a->fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No");
16202#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
16203 ast_cli(a->fd, "MFC/R2 Skip Category Request: %s\n", openr2_context_get_skip_category_request(r2context) ? "Yes" : "No");
16204#endif
16205 ast_cli(a->fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No");
16206 ast_cli(a->fd, "MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No");
16207 ast_cli(a->fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No");
16208 ast_cli(a->fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No");
16209 ast_cli(a->fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No");
16210 ast_cli(a->fd, "MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context));
16211 ast_cli(a->fd, "MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context));
16212 ast_cli(a->fd, "MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan));
16213 ast_cli(a->fd, "MFC/R2 Tx CAS: %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan));
16214 ast_cli(a->fd, "MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan));
16215 ast_cli(a->fd, "MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan));
16216 ast_cli(a->fd, "MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir, sizeof(calldir)));
16217 }
16218#endif
16219#if defined(HAVE_SS7)
16220 if (tmp->ss7) {
16221 struct sig_ss7_chan *chan = tmp->sig_pvt;
16222
16223 ast_cli(a->fd, "CIC: %d\n", chan->cic);
16224 }
16225#endif /* defined(HAVE_SS7) */
16226#ifdef HAVE_PRI
16227 if (tmp->pri) {
16228 struct sig_pri_chan *chan = tmp->sig_pvt;
16229
16230 ast_cli(a->fd, "PRI Flags: ");
16231 if (chan->resetting != SIG_PRI_RESET_IDLE) {
16232 ast_cli(a->fd, "Resetting=%u ", chan->resetting);
16233 }
16234 if (chan->call)
16235 ast_cli(a->fd, "Call ");
16236 if (chan->allocated) {
16237 ast_cli(a->fd, "Allocated ");
16238 }
16239 ast_cli(a->fd, "\n");
16240 if (tmp->logicalspan)
16241 ast_cli(a->fd, "PRI Logical Span: %d\n", tmp->logicalspan);
16242 else
16243 ast_cli(a->fd, "PRI Logical Span: Implicit\n");
16244 }
16245#endif
16246 memset(&ci, 0, sizeof(ci));
16247 ps.channo = tmp->channel;
16248 if (tmp->subs[SUB_REAL].dfd > -1) {
16249 memset(&ci, 0, sizeof(ci));
16250 if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
16251 ast_cli(a->fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, (unsigned)ci.confmode);
16252 }
16253 if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONFMUTE, &x)) {
16254 ast_cli(a->fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
16255 }
16256 memset(&ps, 0, sizeof(ps));
16257 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
16258 ast_log(LOG_WARNING, "Failed to get parameters on channel %d: %s\n", tmp->channel, strerror(errno));
16259 } else {
16260 ast_cli(a->fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
16261 }
16262 }
16264 return CLI_SUCCESS;
16265 }
16266 }
16268
16269 ast_cli(a->fd, "Unable to find given channel %d\n", channel);
16270 return CLI_FAILURE;
16271}
@ SIG_PRI_RESET_IDLE
The channel is not being RESTARTed.
Definition: sig_pri.h:154
enum sig_pri_reset_state resetting
Channel reset/restart state.
Definition: sig_pri.h:361
unsigned int allocated
TRUE when this channel is allocated.
Definition: sig_pri.h:339
int channel
Definition: sig_pri.h:290
q931_call * call
Definition: sig_pri.h:356

References a, sig_pri_chan::allocated, ast_channel_name(), ast_cli(), ast_copy_string(), ast_log, ast_mutex_lock, ast_mutex_unlock, sig_pri_chan::call, dahdi_pvt::channel, sig_pri_chan::channel, sig_ss7_chan::cic, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_dnd(), errno, iflist, iflock, LOG_WARNING, MAX_SLAVES, ast_variable::name, ast_variable::next, NULL, sig_pri_chan::resetting, S_OR, sig2str, SIG_PRI_RESET_IDLE, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, tmp(), ast_cli_entry::usage, and ast_variable::value.

◆ dahdi_show_channels()

static char * dahdi_show_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 15989 of file chan_dahdi.c.

15990{
15991#define FORMAT "%7s %4d %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"
15992#define FORMAT2 "%7s %4s %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"
15993 ast_group_t targetnum = 0;
15994 int filtertype = 0;
15995 struct dahdi_pvt *tmp = NULL;
15996 char tmps[20];
15997 char blockstr[20];
15998
15999 switch (cmd) {
16000 case CLI_INIT:
16001 e->command = "dahdi show channels [group|context]";
16002 e->usage =
16003 "Usage: dahdi show channels [ group <group> | context <context> ]\n"
16004 " Shows a list of available channels with optional filtering\n"
16005 " <group> must be a number between 0 and 63\n";
16006 return NULL;
16007 case CLI_GENERATE:
16008 return NULL;
16009 }
16010
16011 /* syntax: dahdi show channels [ group <group> | context <context> ] */
16012
16013 if (!((a->argc == 3) || (a->argc == 5))) {
16014 return CLI_SHOWUSAGE;
16015 }
16016
16017 if (a->argc == 5) {
16018 if (!strcasecmp(a->argv[3], "group")) {
16019 targetnum = atoi(a->argv[4]);
16020 if (63 < targetnum) {
16021 return CLI_SHOWUSAGE;
16022 }
16023 targetnum = ((ast_group_t) 1) << targetnum;
16024 filtertype = 1;
16025 } else if (!strcasecmp(a->argv[3], "context")) {
16026 filtertype = 2;
16027 }
16028 }
16029
16030 ast_cli(a->fd, FORMAT2, "Chan", "Span", "Signalling", "Extension", "Context", "Language", "MOH Interpret", "Blocked", "In Service", "Alarms", "Description");
16032 for (tmp = iflist; tmp; tmp = tmp->next) {
16033 int alm = 0;
16034 if (filtertype) {
16035 switch(filtertype) {
16036 case 1: /* dahdi show channels group <group> */
16037 if (!(tmp->group & targetnum)) {
16038 continue;
16039 }
16040 break;
16041 case 2: /* dahdi show channels context <context> */
16042 if (strcasecmp(tmp->context, a->argv[4])) {
16043 continue;
16044 }
16045 break;
16046 default:
16047 break;
16048 }
16049 }
16050 if (tmp->channel > 0) {
16051 snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
16052 alm = get_alarms(tmp);
16053 } else {
16054 ast_copy_string(tmps, "pseudo", sizeof(tmps));
16055 }
16056
16057 blockstr[0] = tmp->locallyblocked ? 'L' : ' ';
16058 blockstr[1] = tmp->remotelyblocked ? 'R' : ' ';
16059 blockstr[2] = '\0';
16060
16061 ast_cli(a->fd, FORMAT, tmps, tmp->span, sig2str(tmp->sig), tmp->exten, tmp->context, tmp->language, tmp->mohinterpret, blockstr, tmp->inservice ? "Yes" : "No",
16062 alarm2str(alm), tmp->description);
16063 }
16065 return CLI_SUCCESS;
16066#undef FORMAT
16067#undef FORMAT2
16068}
#define FORMAT
#define FORMAT2
unsigned long long ast_group_t
Definition: channel.h:213

References a, alarm2str(), ast_cli(), ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FORMAT, FORMAT2, get_alarms(), iflist, iflock, NULL, sig2str, tmp(), and ast_cli_entry::usage.

◆ dahdi_show_status()

static char * dahdi_show_status ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 16348 of file chan_dahdi.c.

16349{
16350 #define FORMAT "%4d %-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n"
16351 #define FORMAT2 "%4s %-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n"
16352 int span;
16353 int res;
16354 char alarmstr[50];
16355
16356 int ctl;
16357 struct dahdi_spaninfo s;
16358
16359 switch (cmd) {
16360 case CLI_INIT:
16361 e->command = "dahdi show status";
16362 e->usage =
16363 "Usage: dahdi show status\n"
16364 " Shows a list of DAHDI cards with status\n";
16365 return NULL;
16366 case CLI_GENERATE:
16367 return NULL;
16368 }
16369 ctl = open("/dev/dahdi/ctl", O_RDWR);
16370 if (ctl < 0) {
16371 ast_cli(a->fd, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno));
16372 return CLI_FAILURE;
16373 }
16374 ast_cli(a->fd, FORMAT2, "Span", "Description", "Alarms", "IRQ", "bpviol", "CRC", "Framing", "Coding", "Options", "LBO");
16375
16376 for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
16377 s.spanno = span;
16378 res = ioctl(ctl, DAHDI_SPANSTAT, &s);
16379 if (res) {
16380 continue;
16381 }
16382 build_alarm_info(alarmstr, &s);
16383 ast_cli(a->fd, FORMAT, span, s.desc, alarmstr, s.irqmisses, s.bpvcount, s.crc4count,
16384 s.lineconfig & DAHDI_CONFIG_D4 ? "D4" :
16385 s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" :
16386 s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" :
16387 "CAS",
16388 s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" :
16389 s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" :
16390 s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" :
16391 "Unknown",
16392 s.lineconfig & DAHDI_CONFIG_CRC4 ?
16393 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" :
16394 s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : "",
16395 lbostr[s.lbo]
16396 );
16397 }
16398 close(ctl);
16399
16400 return CLI_SUCCESS;
16401#undef FORMAT
16402#undef FORMAT2
16403}

References a, ast_cli(), build_alarm_info(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, errno, FORMAT, FORMAT2, lbostr, NULL, and ast_cli_entry::usage.

◆ dahdi_show_version()

static char * dahdi_show_version ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 16405 of file chan_dahdi.c.

16406{
16407 int pseudo_fd = -1;
16408 struct dahdi_versioninfo vi;
16409
16410 switch (cmd) {
16411 case CLI_INIT:
16412 e->command = "dahdi show version";
16413 e->usage =
16414 "Usage: dahdi show version\n"
16415 " Shows the DAHDI version in use\n";
16416 return NULL;
16417 case CLI_GENERATE:
16418 return NULL;
16419 }
16420 if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) {
16421 ast_cli(a->fd, "Failed to open control file to get version.\n");
16422 return CLI_SUCCESS;
16423 }
16424
16425 strcpy(vi.version, "Unknown");
16426 strcpy(vi.echo_canceller, "Unknown");
16427
16428 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi))
16429 ast_cli(a->fd, "Failed to get DAHDI version: %s\n", strerror(errno));
16430 else
16431 ast_cli(a->fd, "DAHDI Version: %s Echo Canceller: %s\n", vi.version, vi.echo_canceller);
16432
16433 close(pseudo_fd);
16434
16435 return CLI_SUCCESS;
16436}

References a, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, errno, NULL, and ast_cli_entry::usage.

◆ dahdi_sig2str()

static char * dahdi_sig2str ( int  sig)
static

Definition at line 4651 of file chan_dahdi.c.

4652{
4653 static char buf[256];
4654 switch (sig) {
4655 case SIG_EM:
4656 return "E & M Immediate";
4657 case SIG_EMWINK:
4658 return "E & M Wink";
4659 case SIG_EM_E1:
4660 return "E & M E1";
4661 case SIG_FEATD:
4662 return "Feature Group D (DTMF)";
4663 case SIG_FEATDMF:
4664 return "Feature Group D (MF)";
4665 case SIG_FEATDMF_TA:
4666 return "Feature Group D (MF) Tandem Access";
4667 case SIG_FEATB:
4668 return "Feature Group B (MF)";
4669 case SIG_E911:
4670 return "E911 (MF)";
4671 case SIG_FGC_CAMA:
4672 return "FGC/CAMA (Dialpulse)";
4673 case SIG_FGC_CAMAMF:
4674 return "FGC/CAMA (MF)";
4675 case SIG_FXSLS:
4676 return "FXS Loopstart";
4677 case SIG_FXSGS:
4678 return "FXS Groundstart";
4679 case SIG_FXSKS:
4680 return "FXS Kewlstart";
4681 case SIG_FXOLS:
4682 return "FXO Loopstart";
4683 case SIG_FXOGS:
4684 return "FXO Groundstart";
4685 case SIG_FXOKS:
4686 return "FXO Kewlstart";
4687 case SIG_PRI:
4688 return "ISDN PRI";
4689 case SIG_BRI:
4690 return "ISDN BRI Point to Point";
4691 case SIG_BRI_PTMP:
4692 return "ISDN BRI Point to MultiPoint";
4693 case SIG_SS7:
4694 return "SS7";
4695 case SIG_MFCR2:
4696 return "MFC/R2";
4697 case SIG_SF:
4698 return "SF (Tone) Immediate";
4699 case SIG_SFWINK:
4700 return "SF (Tone) Wink";
4701 case SIG_SF_FEATD:
4702 return "SF (Tone) with Feature Group D (DTMF)";
4703 case SIG_SF_FEATDMF:
4704 return "SF (Tone) with Feature Group D (MF)";
4705 case SIG_SF_FEATB:
4706 return "SF (Tone) with Feature Group B (MF)";
4707 case 0:
4708 return "Pseudo";
4709 default:
4710 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
4711 return buf;
4712 }
4713}
#define SIG_BRI
Definition: chan_dahdi.h:801
#define SIG_BRI_PTMP
Definition: chan_dahdi.h:802

References buf, SIG_BRI, SIG_BRI_PTMP, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_MFCR2, SIG_PRI, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, and SIG_SS7.

Referenced by mkintf().

◆ dahdi_softhangup_all()

static void dahdi_softhangup_all ( void  )
static

Definition at line 15813 of file chan_dahdi.c.

15814{
15815 struct dahdi_pvt *p;
15816retry:
15818 for (p = iflist; p; p = p->next) {
15819 ast_mutex_lock(&p->lock);
15820 if (p->owner && !p->restartpending) {
15821 if (ast_channel_trylock(p->owner)) {
15822 if (DEBUG_ATLEAST(3))
15823 ast_verbose("Avoiding deadlock\n");
15824 /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */
15827 goto retry;
15828 }
15829 if (DEBUG_ATLEAST(3))
15830 ast_verbose("Softhanging up on %s\n", ast_channel_name(p->owner));
15832 p->restartpending = 1;
15835 }
15837 }
15839}
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2458
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2206
#define DEBUG_ATLEAST(level)

References ast_channel_name(), ast_channel_trylock, ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, AST_SOFTHANGUP_EXPLICIT, ast_softhangup_nolock(), ast_verbose(), DEBUG_ATLEAST, iflist, iflock, dahdi_pvt::lock, dahdi_pvt::next, num_restart_pending, dahdi_pvt::owner, and dahdi_pvt::restartpending.

Referenced by dahdi_restart().

◆ dahdi_train_ec()

static void dahdi_train_ec ( struct dahdi_pvt p)
static

Definition at line 4953 of file chan_dahdi.c.

4954{
4955 int x;
4956 int res;
4957
4958 if (p && p->echocanon && p->echotraining) {
4959 x = p->echotraining;
4960 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x);
4961 if (res)
4962 ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno));
4963 else
4964 ast_debug(1, "Engaged echo training on channel %d\n", p->channel);
4965 } else {
4966 ast_debug(1, "No echo training requested\n");
4967 }
4968}

References ast_debug, ast_log, dahdi_pvt::channel, dahdi_subchannel::dfd, dahdi_pvt::echocanon, dahdi_pvt::echotraining, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_handle_event(), and my_train_echocanceller().

◆ dahdi_wait_event()

static int dahdi_wait_event ( int  fd)
inlinestatic

Avoid the silly dahdi_waitevent which ignores a bunch of events.

Definition at line 782 of file chan_dahdi.c.

783{
784 int i, j = 0;
785 i = DAHDI_IOMUX_SIGEVENT;
786 if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
787 return -1;
788 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
789 return -1;
790 return j;
791}

Referenced by analog_ss_thread(), and my_wait_event().

◆ dahdi_wink()

static int dahdi_wink ( struct dahdi_pvt p,
int  index 
)
static

Definition at line 9796 of file chan_dahdi.c.

9797{
9798 int j;
9799 dahdi_set_hook(p->subs[idx].dfd, DAHDI_WINK);
9800 for (;;)
9801 {
9802 /* set bits of interest */
9803 j = DAHDI_IOMUX_SIGEVENT;
9804 /* wait for some happening */
9805 if (ioctl(p->subs[idx].dfd,DAHDI_IOMUX,&j) == -1) return(-1);
9806 /* exit loop if we have it */
9807 if (j & DAHDI_IOMUX_SIGEVENT) break;
9808 }
9809 /* get the event info */
9810 if (ioctl(p->subs[idx].dfd,DAHDI_GETEVENT,&j) == -1) return(-1);
9811 return 0;
9812}

References dahdi_set_hook(), dahdi_subchannel::dfd, and dahdi_pvt::subs.

Referenced by analog_ss_thread(), and my_wink().

◆ dahdi_write()

static int dahdi_write ( struct ast_channel ast,
struct ast_frame frame 
)
static

Definition at line 9271 of file chan_dahdi.c.

9272{
9273 struct dahdi_pvt *p;
9274 int res;
9275 int idx;
9276
9277 /* Write a frame of (presumably voice) data */
9278 if (frame->frametype != AST_FRAME_VOICE) {
9279 if (frame->frametype != AST_FRAME_IMAGE) {
9280 ast_log(LOG_WARNING, "Don't know what to do with frame type '%u'\n",
9281 frame->frametype);
9282 }
9283 return 0;
9284 }
9285
9286 /* Return if it's not valid data */
9287 if (!frame->data.ptr || !frame->datalen) {
9288 return 0;
9289 }
9290
9291 p = ast_channel_tech_pvt(ast);
9292 ast_mutex_lock(&p->lock);
9293
9294 idx = dahdi_get_index(ast, p, 0);
9295 if (idx < 0) {
9297 ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast_channel_name(ast));
9298 return -1;
9299 }
9300
9301 if (p->dialing) {
9303 ast_debug(5, "Dropping frame since I'm still dialing on %s...\n",
9304 ast_channel_name(ast));
9305 return 0;
9306 }
9307 if (!p->owner) {
9309 ast_debug(5, "Dropping frame since there is no active owner on %s...\n",
9310 ast_channel_name(ast));
9311 return 0;
9312 }
9313 if (p->cidspill) {
9315 ast_debug(5, "Dropping frame since I've still got a callerid spill on %s...\n",
9316 ast_channel_name(ast));
9317 return 0;
9318 }
9319
9321 if (!p->subs[idx].linear) {
9322 p->subs[idx].linear = 1;
9323 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
9324 if (res)
9325 ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
9326 }
9327 res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 1);
9330 /* x-law already */
9331 if (p->subs[idx].linear) {
9332 p->subs[idx].linear = 0;
9333 res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
9334 if (res)
9335 ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
9336 }
9337 res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 0);
9338 } else {
9340 ast_log(LOG_WARNING, "Cannot handle frames in %s format\n",
9342 return -1;
9343 }
9345 if (res < 0) {
9346 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
9347 return -1;
9348 }
9349 return 0;
9350}
static int my_dahdi_write(struct dahdi_pvt *p, unsigned char *buf, int len, int idx, int linear)
Definition: chan_dahdi.c:9249
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
@ AST_FRAME_IMAGE

References ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_format_alaw, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_get_name(), ast_format_slin, ast_format_ulaw, AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log, ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, dahdi_pvt::cidspill, dahdi_get_index, dahdi_setlinear(), ast_frame::data, ast_frame::datalen, dahdi_subchannel::dfd, dahdi_pvt::dialing, errno, ast_frame_subclass::format, ast_frame::frametype, dahdi_subchannel::linear, dahdi_pvt::lock, LOG_WARNING, my_dahdi_write(), dahdi_pvt::owner, ast_frame::ptr, ast_frame::subclass, and dahdi_pvt::subs.

◆ dahdichannel_to_ami()

static struct ast_manager_event_blob * dahdichannel_to_ami ( struct stasis_message msg)
static

Definition at line 1910 of file chan_dahdi.c.

1911{
1912 RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
1913 struct ast_channel_blob *obj = stasis_message_data(msg);
1914 struct ast_json *group, *span, *channel;
1915
1916 channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1917 if (!channel_string) {
1918 return NULL;
1919 }
1920
1921 group = ast_json_object_get(obj->blob, "group");
1922 span = ast_json_object_get(obj->blob, "span");
1923 channel = ast_json_object_get(obj->blob, "channel");
1924
1925 return ast_manager_event_blob_create(EVENT_FLAG_CALL, "DAHDIChannel",
1926 "%s"
1927 "DAHDIGroup: %llu\r\n"
1928 "DAHDISpan: %u\r\n"
1929 "DAHDIChannel: %s\r\n",
1930 ast_str_buffer(channel_string),
1932 (unsigned int)ast_json_integer_get(span),
1933 ast_json_string_get(channel));
1934}
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition: json.c:332
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
struct ast_manager_event_blob * ast_manager_event_blob_create(int event_flags, const char *manager_event, const char *extra_fields_fmt,...)
Construct a ast_manager_event_blob.
Definition: manager.c:10564
#define EVENT_FLAG_CALL
Definition: manager.h:76
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
Blob of data associated with a channel.
struct ast_channel_snapshot * snapshot
struct ast_json * blob
Abstract JSON element (object, array, string, int, ...).

References ast_free, ast_json_integer_get(), ast_json_object_get(), ast_json_string_get(), ast_manager_build_channel_state_string(), ast_manager_event_blob_create(), ast_str_buffer(), ast_channel_blob::blob, EVENT_FLAG_CALL, NULL, RAII_VAR, ast_channel_blob::snapshot, and stasis_message_data().

◆ dahdievent_to_analogevent()

static enum analog_event dahdievent_to_analogevent ( int  event)
static

Definition at line 2606 of file chan_dahdi.c.

2607{
2608 enum analog_event res;
2609
2610 switch (event) {
2611 case DAHDI_EVENT_ONHOOK:
2612 res = ANALOG_EVENT_ONHOOK;
2613 break;
2614 case DAHDI_EVENT_RINGOFFHOOK:
2616 break;
2617 case DAHDI_EVENT_WINKFLASH:
2619 break;
2620 case DAHDI_EVENT_ALARM:
2621 res = ANALOG_EVENT_ALARM;
2622 break;
2623 case DAHDI_EVENT_NOALARM:
2625 break;
2626 case DAHDI_EVENT_DIALCOMPLETE:
2628 break;
2629 case DAHDI_EVENT_RINGERON:
2631 break;
2632 case DAHDI_EVENT_RINGEROFF:
2634 break;
2635 case DAHDI_EVENT_HOOKCOMPLETE:
2637 break;
2638 case DAHDI_EVENT_PULSE_START:
2640 break;
2641 case DAHDI_EVENT_POLARITY:
2643 break;
2644 case DAHDI_EVENT_RINGBEGIN:
2646 break;
2647 case DAHDI_EVENT_EC_DISABLED:
2649 break;
2650 case DAHDI_EVENT_REMOVED:
2652 break;
2653 case DAHDI_EVENT_NEONMWI_ACTIVE:
2655 break;
2656 case DAHDI_EVENT_NEONMWI_INACTIVE:
2658 break;
2659#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2660 case DAHDI_EVENT_TX_CED_DETECTED:
2662 break;
2663 case DAHDI_EVENT_RX_CED_DETECTED:
2665 break;
2666 case DAHDI_EVENT_EC_NLP_DISABLED:
2668 break;
2669 case DAHDI_EVENT_EC_NLP_ENABLED:
2671 break;
2672#endif
2673 case DAHDI_EVENT_PULSEDIGIT:
2675 break;
2676 case DAHDI_EVENT_DTMFDOWN:
2678 break;
2679 case DAHDI_EVENT_DTMFUP:
2680 res = ANALOG_EVENT_DTMFUP;
2681 break;
2682 default:
2683 switch(event & 0xFFFF0000) {
2684 case DAHDI_EVENT_PULSEDIGIT:
2685 case DAHDI_EVENT_DTMFDOWN:
2686 case DAHDI_EVENT_DTMFUP:
2687 /* The event includes a digit number in the low word.
2688 * Converting it to a 'enum analog_event' would remove
2689 * that information. Thus it is returned as-is.
2690 */
2691 return event;
2692 }
2693
2694 res = ANALOG_EVENT_ERROR;
2695 break;
2696 }
2697
2698 return res;
2699}
analog_event
Definition: sig_analog.h:79
@ ANALOG_EVENT_HOOKCOMPLETE
Definition: sig_analog.h:89
@ ANALOG_EVENT_DTMFDOWN
Definition: sig_analog.h:104
@ ANALOG_EVENT_RINGEROFF
Definition: sig_analog.h:88
@ ANALOG_EVENT_PULSE_START
Definition: sig_analog.h:90
@ ANALOG_EVENT_TX_CED_DETECTED
Definition: sig_analog.h:97
@ ANALOG_EVENT_NEONMWI_ACTIVE
Definition: sig_analog.h:95
@ ANALOG_EVENT_RINGBEGIN
Definition: sig_analog.h:92
@ ANALOG_EVENT_ONHOOK
Definition: sig_analog.h:81
@ ANALOG_EVENT_EC_DISABLED
Definition: sig_analog.h:93
@ ANALOG_EVENT_WINKFLASH
Definition: sig_analog.h:83
@ ANALOG_EVENT_ERROR
Definition: sig_analog.h:101
@ ANALOG_EVENT_PULSEDIGIT
Definition: sig_analog.h:103
@ ANALOG_EVENT_RINGERON
Definition: sig_analog.h:87
@ ANALOG_EVENT_RX_CED_DETECTED
Definition: sig_analog.h:98
@ ANALOG_EVENT_ALARM
Definition: sig_analog.h:84
@ ANALOG_EVENT_DIALCOMPLETE
Definition: sig_analog.h:86
@ ANALOG_EVENT_EC_NLP_ENABLED
Definition: sig_analog.h:100
@ ANALOG_EVENT_POLARITY
Definition: sig_analog.h:91
@ ANALOG_EVENT_NEONMWI_INACTIVE
Definition: sig_analog.h:96
@ ANALOG_EVENT_DTMFUP
Definition: sig_analog.h:105
@ ANALOG_EVENT_EC_NLP_DISABLED
Definition: sig_analog.h:99
@ ANALOG_EVENT_RINGOFFHOOK
Definition: sig_analog.h:82
@ ANALOG_EVENT_REMOVED
Definition: sig_analog.h:94
@ ANALOG_EVENT_NOALARM
Definition: sig_analog.h:85
Definition: astman.c:222

References ANALOG_EVENT_ALARM, ANALOG_EVENT_DIALCOMPLETE, ANALOG_EVENT_DTMFDOWN, ANALOG_EVENT_DTMFUP, ANALOG_EVENT_EC_DISABLED, ANALOG_EVENT_EC_NLP_DISABLED, ANALOG_EVENT_EC_NLP_ENABLED, ANALOG_EVENT_ERROR, ANALOG_EVENT_HOOKCOMPLETE, ANALOG_EVENT_NEONMWI_ACTIVE, ANALOG_EVENT_NEONMWI_INACTIVE, ANALOG_EVENT_NOALARM, ANALOG_EVENT_ONHOOK, ANALOG_EVENT_POLARITY, ANALOG_EVENT_PULSE_START, ANALOG_EVENT_PULSEDIGIT, ANALOG_EVENT_REMOVED, ANALOG_EVENT_RINGBEGIN, ANALOG_EVENT_RINGEROFF, ANALOG_EVENT_RINGERON, ANALOG_EVENT_RINGOFFHOOK, ANALOG_EVENT_RX_CED_DETECTED, ANALOG_EVENT_TX_CED_DETECTED, and ANALOG_EVENT_WINKFLASH.

Referenced by do_monitor(), my_get_callerid(), and my_get_event().

◆ dahdisig_to_analogsig()

static enum analog_sigtype dahdisig_to_analogsig ( int  sig)
static

Definition at line 1182 of file chan_dahdi.c.

1183{
1184 switch (sig) {
1185 case SIG_FXOLS:
1186 return ANALOG_SIG_FXOLS;
1187 case SIG_FXOGS:
1188 return ANALOG_SIG_FXOGS;
1189 case SIG_FXOKS:
1190 return ANALOG_SIG_FXOKS;
1191 case SIG_FXSLS:
1192 return ANALOG_SIG_FXSLS;
1193 case SIG_FXSGS:
1194 return ANALOG_SIG_FXSGS;
1195 case SIG_FXSKS:
1196 return ANALOG_SIG_FXSKS;
1197 case SIG_EMWINK:
1198 return ANALOG_SIG_EMWINK;
1199 case SIG_EM:
1200 return ANALOG_SIG_EM;
1201 case SIG_EM_E1:
1202 return ANALOG_SIG_EM_E1;
1203 case SIG_FEATD:
1204 return ANALOG_SIG_FEATD;
1205 case SIG_FEATDMF:
1206 return ANALOG_SIG_FEATDMF;
1207 case SIG_E911:
1208 return SIG_E911;
1209 case SIG_FGC_CAMA:
1210 return ANALOG_SIG_FGC_CAMA;
1211 case SIG_FGC_CAMAMF:
1212 return ANALOG_SIG_FGC_CAMAMF;
1213 case SIG_FEATB:
1214 return ANALOG_SIG_FEATB;
1215 case SIG_SFWINK:
1216 return ANALOG_SIG_SFWINK;
1217 case SIG_SF:
1218 return ANALOG_SIG_SF;
1219 case SIG_SF_FEATD:
1220 return ANALOG_SIG_SF_FEATD;
1221 case SIG_SF_FEATDMF:
1222 return ANALOG_SIG_SF_FEATDMF;
1223 case SIG_FEATDMF_TA:
1224 return ANALOG_SIG_FEATDMF_TA;
1225 case SIG_SF_FEATB:
1226 return ANALOG_SIG_FEATB;
1227 default:
1228 return -1;
1229 }
1230}
@ ANALOG_SIG_FEATD
Definition: sig_analog.h:56
@ ANALOG_SIG_FEATDMF_TA
Definition: sig_analog.h:66
@ ANALOG_SIG_FGC_CAMAMF
Definition: sig_analog.h:60
@ ANALOG_SIG_FXOLS
Definition: sig_analog.h:47
@ ANALOG_SIG_FEATDMF
Definition: sig_analog.h:57
@ ANALOG_SIG_EM_E1
Definition: sig_analog.h:55
@ ANALOG_SIG_EMWINK
Definition: sig_analog.h:53
@ ANALOG_SIG_FXOKS
Definition: sig_analog.h:48
@ ANALOG_SIG_SF
Definition: sig_analog.h:63
@ ANALOG_SIG_FGC_CAMA
Definition: sig_analog.h:59
@ ANALOG_SIG_FXSLS
Definition: sig_analog.h:50
@ ANALOG_SIG_EM
Definition: sig_analog.h:54
@ ANALOG_SIG_FXOGS
Definition: sig_analog.h:49
@ ANALOG_SIG_FXSGS
Definition: sig_analog.h:52
@ ANALOG_SIG_SF_FEATDMF
Definition: sig_analog.h:65
@ ANALOG_SIG_SFWINK
Definition: sig_analog.h:62
@ ANALOG_SIG_FEATB
Definition: sig_analog.h:61
@ ANALOG_SIG_SF_FEATD
Definition: sig_analog.h:64
@ ANALOG_SIG_FXSKS
Definition: sig_analog.h:51

References ANALOG_SIG_EM, ANALOG_SIG_EM_E1, ANALOG_SIG_EMWINK, ANALOG_SIG_FEATB, ANALOG_SIG_FEATD, ANALOG_SIG_FEATDMF, ANALOG_SIG_FEATDMF_TA, ANALOG_SIG_FGC_CAMA, ANALOG_SIG_FGC_CAMAMF, ANALOG_SIG_FXOGS, ANALOG_SIG_FXOKS, ANALOG_SIG_FXOLS, ANALOG_SIG_FXSGS, ANALOG_SIG_FXSKS, ANALOG_SIG_FXSLS, ANALOG_SIG_SF, ANALOG_SIG_SF_FEATD, ANALOG_SIG_SF_FEATDMF, ANALOG_SIG_SFWINK, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, and SIG_SFWINK.

Referenced by mkintf().

◆ deep_copy_dahdi_chan_conf()

static void deep_copy_dahdi_chan_conf ( struct dahdi_chan_conf dest,
const struct dahdi_chan_conf src 
)
static

Definition at line 19934 of file chan_dahdi.c.

19935{
19936 struct ast_cc_config_params *cc_params;
19937
19938 cc_params = dest->chan.cc_params;
19939 *dest = *src;
19940 dest->chan.cc_params = cc_params;
19942}

References ast_cc_copy_config_params(), dahdi_pvt::cc_params, and dahdi_chan_conf::chan.

Referenced by setup_dahdi_int().

◆ destroy_all_channels()

static void destroy_all_channels ( void  )
static

Definition at line 5925 of file chan_dahdi.c.

5926{
5927 int chan;
5928#if defined(HAVE_PRI)
5929 unsigned span;
5930 struct sig_pri_span *pri;
5931#endif /* defined(HAVE_PRI) */
5932 struct dahdi_pvt *p;
5933
5934 while (num_restart_pending) {
5935 usleep(1);
5936 }
5937
5939 /* Destroy all the interfaces and free their memory */
5940 while (iflist) {
5941 p = iflist;
5942
5943 chan = p->channel;
5944#if defined(HAVE_PRI_SERVICE_MESSAGES)
5945 {
5946 char db_chan_name[20];
5947 char db_answer[5];
5948 char state;
5949 int why = -1;
5950
5951 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, p->span, chan);
5952 if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) {
5953 sscanf(db_answer, "%1c:%30d", &state, &why);
5954 }
5955 if (!why) {
5956 /* SRVST persistence is not required */
5957 ast_db_del(db_chan_name, SRVST_DBKEY);
5958 }
5959 }
5960#endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
5961 /* Free associated memory */
5963 ast_verb(3, "Unregistered channel %d\n", chan);
5964 }
5965 ifcount = 0;
5967
5968#if defined(HAVE_PRI)
5969 /* Destroy all of the no B channel interface lists */
5970 for (span = 0; span < NUM_SPANS; ++span) {
5971 if (!pris[span].dchannels[0]) {
5972 break;
5973 }
5974 pri = &pris[span].pri;
5975 ast_mutex_lock(&pri->lock);
5976 while (pri->no_b_chan_iflist) {
5977 p = pri->no_b_chan_iflist;
5978
5979 /* Free associated memory */
5981 }
5982 ast_mutex_unlock(&pri->lock);
5983 }
5984#endif /* defined(HAVE_PRI) */
5985}
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Definition: main/db.c:427
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: main/db.c:476
enum cc_state state
Definition: ccss.c:393
static void destroy_dahdi_pvt(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:5827
static int ifcount
Definition: chan_dahdi.c:749
struct pri * pri
Definition: sig_pri.h:602
void * no_b_chan_iflist
Definition: sig_pri.h:607
ast_mutex_t lock
Definition: sig_pri.h:616

References ast_db_del(), ast_db_get(), ast_mutex_lock, ast_mutex_unlock, ast_verb, dahdi_pvt::channel, destroy_dahdi_pvt(), ifcount, iflist, iflock, sig_pri_span::lock, sig_pri_span::no_b_chan_iflist, num_restart_pending, NUM_SPANS, sig_pri_span::pri, dahdi_pvt::span, and state.

Referenced by __unload_module(), and dahdi_restart().

◆ destroy_channel()

static void destroy_channel ( struct dahdi_pvt cur,
int  now 
)
static

Definition at line 5907 of file chan_dahdi.c.

5908{
5909 int i;
5910
5911 if (!now) {
5912 /* Do not destroy the channel now if it is owned by someone. */
5913 if (cur->owner) {
5914 return;
5915 }
5916 for (i = 0; i < 3; i++) {
5917 if (cur->subs[i].owner) {
5918 return;
5919 }
5920 }
5921 }
5922 destroy_dahdi_pvt(cur);
5923}

References destroy_dahdi_pvt(), dahdi_subchannel::owner, dahdi_pvt::owner, and dahdi_pvt::subs.

Referenced by dahdi_destroy_channel_range(), and dahdi_hangup().

◆ destroy_dahdi_pvt()

static void destroy_dahdi_pvt ( struct dahdi_pvt pvt)
static

Definition at line 5827 of file chan_dahdi.c.

5828{
5829 struct dahdi_pvt *p = pvt;
5830
5831 if (p->manages_span_alarms) {
5833 if (next) {
5835 }
5836 }
5837
5838 /* Remove channel from the list */
5839#if defined(HAVE_PRI)
5840 dahdi_unlink_pri_pvt(p);
5841#endif /* defined(HAVE_PRI) */
5842#if defined(HAVE_SS7)
5843 dahdi_unlink_ss7_pvt(p);
5844#endif /* defined(HAVE_SS7) */
5845#if defined(HAVE_OPENR2)
5846 dahdi_unlink_mfcr2_pvt(p);
5847#endif /* defined(HAVE_SS7) */
5848 switch (pvt->which_iflist) {
5849 case DAHDI_IFLIST_NONE:
5850 break;
5851 case DAHDI_IFLIST_MAIN:
5853 break;
5854#if defined(HAVE_PRI)
5855 case DAHDI_IFLIST_NO_B_CHAN:
5856 if (p->pri) {
5857 dahdi_nobch_extract(p->pri, p);
5858 }
5859 break;
5860#endif /* defined(HAVE_PRI) */
5861 }
5862
5863 if (p->sig_pvt) {
5864 if (dahdi_analog_lib_handles(p->sig, 0, 0)) {
5866 }
5867 switch (p->sig) {
5868#if defined(HAVE_PRI)
5871 break;
5872#endif /* defined(HAVE_PRI) */
5873#if defined(HAVE_SS7)
5874 case SIG_SS7:
5876 break;
5877#endif /* defined(HAVE_SS7) */
5878 default:
5879 break;
5880 }
5881 }
5882 ast_free(p->cidspill);
5883 if (p->use_smdi) {
5885 }
5886 if (p->mwi_event_sub) {
5888 }
5889 if (p->vars) {
5891 }
5892 if (p->cc_params) {
5894 }
5895
5898
5901 if (p->owner) {
5903 }
5904 ast_free(p);
5905}
static void dahdi_iflist_extract(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:5600
static struct dahdi_pvt * find_next_iface_in_span(struct dahdi_pvt *cur)
Definition: chan_dahdi.c:5816
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7732
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
#define ast_mutex_destroy(a)
Definition: lock.h:188
void * ast_mwi_unsubscribe(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic and MWI.
Definition: mwi.c:254
void analog_delete(struct analog_pvt *doomed)
Delete the analog private structure.
Definition: sig_analog.c:4104
void sig_pri_chan_delete(struct sig_pri_chan *doomed)
void sig_ss7_chan_delete(struct sig_ss7_chan *doomed)
struct ast_mwi_subscriber * mwi_event_sub
Opaque event subscription parameters for message waiting indication support.
Definition: chan_dahdi.h:711
unsigned int manages_span_alarms
TRUE if the channel alarms will be managed also as Span ones.
Definition: chan_dahdi.h:465

References analog_delete(), ao2_cleanup, ast_cc_config_params_destroy(), ast_channel_tech_pvt_set(), ast_free, ast_mutex_destroy, ast_mwi_unsubscribe(), ast_unref_namedgroups(), ast_variables_destroy(), dahdi_pvt::cc_params, dahdi_pvt::cidspill, dahdi_analog_lib_handles(), dahdi_close_sub(), dahdi_iflist_extract(), DAHDI_IFLIST_MAIN, DAHDI_IFLIST_NONE, find_next_iface_in_span(), dahdi_pvt::lock, dahdi_pvt::manages_span_alarms, dahdi_pvt::mwi_event_sub, dahdi_pvt::named_callgroups, dahdi_pvt::named_pickupgroups, dahdi_pvt::next, NULL, dahdi_pvt::owner, dahdi_pvt::sig, sig_pri_chan_delete(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, sig_ss7_chan_delete(), dahdi_pvt::smdi_iface, SUB_REAL, dahdi_pvt::use_smdi, dahdi_pvt::vars, and dahdi_pvt::which_iflist.

Referenced by destroy_all_channels(), destroy_channel(), duplicate_pseudo(), and mkintf().

◆ determine_starting_point()

static struct dahdi_pvt * determine_starting_point ( const char *  data,
struct dahdi_starting_point param 
)
static

Definition at line 13742 of file chan_dahdi.c.

13743{
13744 char *dest;
13745 char *s;
13746 int x;
13747 int res = 0;
13748 struct dahdi_pvt *p;
13749 char *subdir = NULL;
13751 AST_APP_ARG(group); /* channel/group token */
13752 //AST_APP_ARG(ext); /* extension token */
13753 //AST_APP_ARG(opts); /* options token */
13754 AST_APP_ARG(other); /* Any remining unused arguments */
13755 );
13756
13757 /*
13758 * data is ---v
13759 * Dial(DAHDI/pseudo[/extension[/options]])
13760 * Dial(DAHDI/<channel#>[c|r<cadence#>|d][/extension[/options]])
13761 * Dial(DAHDI/<subdir>!<channel#>[c|r<cadence#>|d][/extension[/options]])
13762 * Dial(DAHDI/i<span>[/extension[/options]])
13763 * Dial(DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadence#>|d][/extension[/options]])
13764 *
13765 * i - ISDN span channel restriction.
13766 * Used by CC to ensure that the CC recall goes out the same span.
13767 * Also to make ISDN channel names dialable when the sequence number
13768 * is stripped off. (Used by DTMF attended transfer feature.)
13769 *
13770 * g - channel group allocation search forward
13771 * G - channel group allocation search backward
13772 * r - channel group allocation round robin search forward
13773 * R - channel group allocation round robin search backward
13774 *
13775 * c - Wait for DTMF digit to confirm answer
13776 * r<cadence#> - Set distinctive ring cadence number
13777 * d - Force bearer capability for ISDN/SS7 call to digital.
13778 */
13779
13780 if (data) {
13781 dest = ast_strdupa(data);
13782 } else {
13783 ast_log(LOG_WARNING, "Channel requested with no data\n");
13784 return NULL;
13785 }
13786 AST_NONSTANDARD_APP_ARGS(args, dest, '/');
13787 if (!args.argc || ast_strlen_zero(args.group)) {
13788 ast_log(LOG_WARNING, "No channel/group specified\n");
13789 return NULL;
13790 }
13791
13792 /* Initialize the output parameters */
13793 memset(param, 0, sizeof(*param));
13794 param->channelmatch = -1;
13795
13796 if (strchr(args.group, '!') != NULL) {
13797 char *prev = args.group;
13798 while ((s = strchr(prev, '!')) != NULL) {
13799 *s++ = '/';
13800 prev = s;
13801 }
13802 *(prev - 1) = '\0';
13803 subdir = args.group;
13804 args.group = prev;
13805 } else if (args.group[0] == 'i') {
13806 /* Extract the ISDN span channel restriction specifier. */
13807 res = sscanf(args.group + 1, "%30d", &x);
13808 if (res < 1) {
13809 ast_log(LOG_WARNING, "Unable to determine ISDN span for data %s\n", data);
13810 return NULL;
13811 }
13812 param->span = x;
13813
13814 /* Remove the ISDN span channel restriction specifier. */
13815 s = strchr(args.group, '-');
13816 if (!s) {
13817 /* Search all groups since we are ISDN span restricted. */
13818 return iflist;
13819 }
13820 args.group = s + 1;
13821 res = 0;
13822 }
13823 if (toupper(args.group[0]) == 'G' || toupper(args.group[0])=='R') {
13824 /* Retrieve the group number */
13825 s = args.group + 1;
13826 res = sscanf(s, "%30d%1c%30d", &x, &param->opt, &param->cadence);
13827 if (res < 1) {
13828 ast_log(LOG_WARNING, "Unable to determine group for data %s\n", data);
13829 return NULL;
13830 }
13831 param->groupmatch = ((ast_group_t) 1 << x);
13832
13833 if (toupper(args.group[0]) == 'G') {
13834 if (args.group[0] == 'G') {
13835 param->backwards = 1;
13836 p = ifend;
13837 } else
13838 p = iflist;
13839 } else {
13840 if (ARRAY_LEN(round_robin) <= x) {
13841 ast_log(LOG_WARNING, "Round robin index %d out of range for data %s\n",
13842 x, data);
13843 return NULL;
13844 }
13845 if (args.group[0] == 'R') {
13846 param->backwards = 1;
13847 p = round_robin[x] ? round_robin[x]->prev : ifend;
13848 if (!p)
13849 p = ifend;
13850 } else {
13851 p = round_robin[x] ? round_robin[x]->next : iflist;
13852 if (!p)
13853 p = iflist;
13854 }
13855 param->roundrobin = 1;
13856 param->rr_starting_point = x;
13857 }
13858 } else {
13859 s = args.group;
13860 if (!strcasecmp(s, "pseudo")) {
13861 /* Special case for pseudo */
13862 x = CHAN_PSEUDO;
13863 param->channelmatch = x;
13864 } else {
13865 res = sscanf(s, "%30d%1c%30d", &x, &param->opt, &param->cadence);
13866 if (res < 1) {
13867 ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", data);
13868 return NULL;
13869 } else {
13870 param->channelmatch = x;
13871 }
13872 }
13873 if (subdir) {
13874 char path[PATH_MAX];
13875 struct stat stbuf;
13876
13877 snprintf(path, sizeof(path), "/dev/dahdi/%s/%d",
13878 subdir, param->channelmatch);
13879 if (stat(path, &stbuf) < 0) {
13880 ast_log(LOG_WARNING, "stat(%s) failed: %s\n",
13881 path, strerror(errno));
13882 return NULL;
13883 }
13884 if (!S_ISCHR(stbuf.st_mode)) {
13885 ast_log(LOG_ERROR, "%s: Not a character device file\n",
13886 path);
13887 return NULL;
13888 }
13889 param->channelmatch = minor(stbuf.st_rdev);
13890 }
13891
13892 p = iflist;
13893 }
13894
13895 if (param->opt == 'r' && res < 3) {
13896 ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", data);
13897 param->opt = '\0';
13898 }
13899
13900 return p;
13901}
#define PATH_MAX
Definition: asterisk.h:40
ast_group_t groupmatch
Definition: chan_dahdi.c:13726

References args, ARRAY_LEN, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_NONSTANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), dahdi_starting_point::backwards, dahdi_starting_point::cadence, CHAN_PSEUDO, dahdi_starting_point::channelmatch, errno, dahdi_starting_point::groupmatch, ifend, iflist, LOG_ERROR, LOG_WARNING, dahdi_pvt::next, NULL, dahdi_starting_point::opt, PATH_MAX, dahdi_pvt::prev, round_robin, dahdi_starting_point::roundrobin, dahdi_starting_point::rr_starting_point, and dahdi_starting_point::span.

Referenced by dahdi_cc_callback(), and dahdi_request().

◆ digit_to_dtmfindex()

static int digit_to_dtmfindex ( char  digit)
static

Definition at line 4481 of file chan_dahdi.c.

4482{
4483 if (isdigit(digit))
4484 return DAHDI_TONE_DTMF_BASE + (digit - '0');
4485 else if (digit >= 'A' && digit <= 'D')
4486 return DAHDI_TONE_DTMF_A + (digit - 'A');
4487 else if (digit >= 'a' && digit <= 'd')
4488 return DAHDI_TONE_DTMF_A + (digit - 'a');
4489 else if (digit == '*')
4490 return DAHDI_TONE_DTMF_s;
4491 else if (digit == '#')
4492 return DAHDI_TONE_DTMF_p;
4493 else
4494 return -1;
4495}

References digit.

Referenced by dahdi_digit_begin().

◆ do_monitor()

static void * do_monitor ( void *  data)
static

Definition at line 11859 of file chan_dahdi.c.

11860{
11861 int count, res, res2, spoint, pollres=0;
11862 struct dahdi_pvt *i;
11863 struct dahdi_pvt *last = NULL;
11864 struct dahdi_pvt *doomed;
11865 time_t thispass = 0, lastpass = 0;
11866 int found;
11867 char buf[1024];
11868 struct pollfd *pfds=NULL;
11869 int lastalloc = -1;
11870 /* This thread monitors all the frame relay interfaces which are not yet in use
11871 (and thus do not have a separate thread) indefinitely */
11872 /* From here on out, we die whenever asked */
11873#if 0
11874 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
11875 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
11876 return NULL;
11877 }
11878 ast_debug(1, "Monitor starting...\n");
11879#endif
11880 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
11881
11882 pthread_cleanup_push(monitor_pfds_clean, &pfds);
11883 for (;;) {
11884 /* Lock the interface list */
11886 if (!pfds || (lastalloc != ifcount)) {
11887 if (pfds) {
11888 ast_free(pfds);
11889 pfds = NULL;
11890 }
11891 if (ifcount) {
11892 if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
11894 return NULL;
11895 }
11896 }
11897 lastalloc = ifcount;
11898 }
11899 /* Build the stuff we're going to poll on, that is the socket of every
11900 dahdi_pvt that does not have an associated owner channel */
11901 count = 0;
11902 for (i = iflist; i; i = i->next) {
11903 ast_mutex_lock(&i->lock);
11904 if (pfds && (i->subs[SUB_REAL].dfd > -1) && i->sig && (!i->radio) && !(i->sig & SIG_MFCR2)) {
11905 if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
11906 struct analog_pvt *p = i->sig_pvt;
11907
11908 if (!p) {
11909 ast_log(LOG_ERROR, "No sig_pvt?\n");
11910 } else if (!p->owner && !p->subs[SUB_REAL].owner) {
11911 /* This needs to be watched, as it lacks an owner */
11912 pfds[count].fd = i->subs[SUB_REAL].dfd;
11913 pfds[count].events = POLLPRI;
11914 pfds[count].revents = 0;
11915 /* Message waiting or r2 channels also get watched for reading */
11916 if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk ||
11917 (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) {
11918 pfds[count].events |= POLLIN;
11919 }
11920 count++;
11921 }
11922 } else {
11923 if (!i->owner && !i->subs[SUB_REAL].owner && !i->mwimonitoractive ) {
11924 /* This needs to be watched, as it lacks an owner */
11925 pfds[count].fd = i->subs[SUB_REAL].dfd;
11926 pfds[count].events = POLLPRI;
11927 pfds[count].revents = 0;
11928 /* If we are monitoring for VMWI or sending CID, we need to
11929 read from the channel as well */
11930 if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk ||
11931 (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) {
11932 pfds[count].events |= POLLIN;
11933 }
11934 count++;
11935 }
11936 }
11937 }
11939 }
11940 /* Okay, now that we know what to do, release the interface lock */
11942
11943 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
11944 pthread_testcancel();
11945 /* Wait at least a second for something to happen */
11946 res = poll(pfds, count, 1000);
11947 pthread_testcancel();
11948 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
11949
11950 /* Okay, poll has finished. Let's see what happened. */
11951 if (res < 0) {
11952 if ((errno != EAGAIN) && (errno != EINTR))
11953 ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
11954 continue;
11955 }
11956 /* Alright, lock the interface list again, and let's look and see what has
11957 happened */
11959 found = 0;
11960 spoint = 0;
11961 lastpass = thispass;
11962 thispass = time(NULL);
11963 doomed = NULL;
11964 for (i = iflist;; i = i->next) {
11965 if (doomed) {
11967 doomed = NULL;
11968 }
11969 if (!i) {
11970 break;
11971 }
11972
11973 if (thispass != lastpass) {
11974 if (!found && ((i == last) || ((i == iflist) && !last))) {
11975 last = i;
11976 if (last) {
11977 struct analog_pvt *analog_p = last->sig_pvt;
11978 /* Only allow MWI to be initiated on a quiescent fxs port */
11979 if (analog_p
11980 && !last->mwisendactive
11981 && (last->sig & __DAHDI_SIG_FXO)
11982 && !analog_p->fxsoffhookstate
11983 && !last->owner
11984 && (!ast_strlen_zero(last->mailbox) || last->mwioverride_active)
11985 && !analog_p->subs[SUB_REAL].owner /* could be a recall ring from a flash hook hold */
11986 && (thispass - analog_p->onhooktime > 3)) {
11987 res = has_voicemail(last);
11988 if (analog_p->msgstate != res) {
11989 /* Set driver resources for signalling VMWI */
11990 res2 = ioctl(last->subs[SUB_REAL].dfd, DAHDI_VMWI, &res);
11991 if (res2) {
11992 /* TODO: This message will ALWAYS be generated on some cards; any way to restrict it to those cards where it is interesting? */
11993 ast_debug(3, "Unable to control message waiting led on channel %d: %s\n", last->channel, strerror(errno));
11994 }
11995 /* If enabled for FSK spill then initiate it */
11996 if (mwi_send_init(last)) {
11997 ast_log(LOG_WARNING, "Unable to initiate mwi send sequence on channel %d\n", last->channel);
11998 }
11999 analog_p->msgstate = res;
12000 found ++;
12001 }
12002 }
12003 last = last->next;
12004 }
12005 }
12006 }
12007 if ((i->subs[SUB_REAL].dfd > -1) && i->sig) {
12008 if (i->radio && !i->owner)
12009 {
12010 res = dahdi_get_event(i->subs[SUB_REAL].dfd);
12011 if (res)
12012 {
12013 ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
12014 /* Don't hold iflock while handling init events */
12016 if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode))
12018 else
12019 doomed = handle_init_event(i, res);
12021 }
12022 continue;
12023 }
12024 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].dfd, count, &spoint);
12025 if (pollres & POLLIN) {
12026 if (i->owner || i->subs[SUB_REAL].owner) {
12027#ifdef HAVE_PRI
12028 if (!i->pri)
12029#endif
12030 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd);
12031 continue;
12032 }
12034 ast_log(LOG_WARNING, "Whoa.... I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd);
12035 continue;
12036 }
12037 res = read(i->subs[SUB_REAL].dfd, buf, sizeof(buf));
12038 if (res > 0) {
12039 if (i->mwimonitor_fsk) {
12040 if (calc_energy((unsigned char *) buf, res, AST_LAW(i)) > mwilevel) {
12041 pthread_attr_t attr;
12042 pthread_t threadid;
12043 struct mwi_thread_data *mtd;
12044
12045 pthread_attr_init(&attr);
12046 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
12047
12048 ast_debug(1, "Maybe some MWI on port %d!\n", i->channel);
12049 if ((mtd = ast_calloc(1, sizeof(*mtd)))) {
12050 mtd->pvt = i;
12051 memcpy(mtd->buf, buf, res);
12052 mtd->len = res;
12053 i->mwimonitoractive = 1;
12054 if (ast_pthread_create_background(&threadid, &attr, mwi_thread, mtd)) {
12055 ast_log(LOG_WARNING, "Unable to start mwi thread on channel %d\n", i->channel);
12056 i->mwimonitoractive = 0;
12057 ast_free(mtd);
12058 }
12059 }
12060 }
12061 /* If configured to check for a DTMF CID spill that comes without alert (e.g no polarity reversal) */
12062 } else if (i->cid_start == CID_START_DTMF_NOALERT) {
12063 int energy;
12064 struct timeval now;
12065 /* State machine dtmfcid_holdoff_state allows for the line to settle
12066 * before checking agin for dtmf energy. Presently waits for 500 mS before checking again
12067 */
12068 if (1 == i->dtmfcid_holdoff_state) {
12069 gettimeofday(&i->dtmfcid_delay, NULL);
12070 i->dtmfcid_holdoff_state = 2;
12071 } else if (2 == i->dtmfcid_holdoff_state) {
12072 gettimeofday(&now, NULL);
12073 if ((int)(now.tv_sec - i->dtmfcid_delay.tv_sec) * 1000000 + (int)now.tv_usec - (int)i->dtmfcid_delay.tv_usec > 500000) {
12074 i->dtmfcid_holdoff_state = 0;
12075 }
12076 } else {
12077 energy = calc_energy((unsigned char *) buf, res, AST_LAW(i));
12078 if (!i->mwisendactive && energy > dtmfcid_level) {
12079 pthread_t threadid;
12080 struct ast_channel *chan;
12082 if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
12083 /* just in case this event changes or somehow destroys a channel, set doomed here too */
12085 i->dtmfcid_holdoff_state = 1;
12086 } else {
12087 ast_callid callid = 0;
12088 int callid_created = ast_callid_threadstorage_auto(&callid);
12089 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
12090 if (!chan) {
12091 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
12092 } else {
12093 res = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan);
12094 if (res) {
12095 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
12096 ast_hangup(chan);
12097 } else {
12098 i->dtmfcid_holdoff_state = 1;
12099 }
12100 }
12102 }
12104 }
12105 }
12106 }
12107 if (i->mwisendactive) {
12109 }
12110 } else {
12111 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
12112 }
12113 }
12114 if (pollres & POLLPRI) {
12115 if (i->owner || i->subs[SUB_REAL].owner) {
12116#ifdef HAVE_PRI
12117 if (!i->pri)
12118#endif
12119 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].dfd);
12120 continue;
12121 }
12122 res = dahdi_get_event(i->subs[SUB_REAL].dfd);
12123 ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
12124 /* Don't hold iflock while handling init events */
12126 if (0 == i->mwisendactive || 0 == mwi_send_process_event(i, res)) {
12127 if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode))
12129 else
12130 doomed = handle_init_event(i, res);
12131 }
12132 if (i->doreoriginate && res == DAHDI_EVENT_HOOKCOMPLETE) {
12133 /* Actually automatically reoriginate this FXS line, if directed to.
12134 * We should get a DAHDI_EVENT_HOOKCOMPLETE from the loop disconnect
12135 * doing its thing (one reason why this is for FXOKS only: FXOLS
12136 * hangups don't give us any DAHDI events to piggyback off of)*/
12137 i->doreoriginate = 0;
12138 /* Double check the channel is still off-hook. There's only about a millisecond
12139 * between when doreoriginate is set high and we see that here, but just to be safe. */
12140 if (!my_is_off_hook(i)) {
12141 ast_debug(1, "Woah! Went back on hook before reoriginate could happen on channel %d\n", i->channel);
12142 } else {
12143 ast_verb(3, "Automatic reorigination on channel %d\n", i->channel);
12144 res = DAHDI_EVENT_RINGOFFHOOK; /* Pretend that the physical channel just went off hook */
12145 if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
12147 } else {
12148 doomed = handle_init_event(i, res);
12149 }
12150 }
12151 }
12153 }
12154 }
12155 }
12158#ifdef HAVE_OPENR2
12159 dahdi_r2_destroy_nodev();
12160#endif
12161 }
12162 /* Never reached */
12163 pthread_cleanup_pop(1);
12164 return NULL;
12165
12166}
struct sla_ringing_trunk * last
Definition: app_sla.c:332
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static int calc_energy(const unsigned char *buf, int len, struct ast_format *law)
Definition: chan_dahdi.c:11089
static void release_doomed_pris(void)
Definition: chan_dahdi.c:1283
static enum analog_event dahdievent_to_analogevent(int event)
Definition: chan_dahdi.c:2606
static int mwi_send_init(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:11260
static void * mwi_thread(void *data)
Definition: chan_dahdi.c:11103
static int mwilevel
Definition: chan_dahdi.c:733
static int mwi_send_process_buffer(struct dahdi_pvt *pvt, int num_read)
Definition: chan_dahdi.c:11313
static int dtmfcid_level
Definition: chan_dahdi.c:734
static int mwi_send_process_event(struct dahdi_pvt *pvt, int event)
Definition: chan_dahdi.c:11401
static struct dahdi_pvt * handle_init_event(struct dahdi_pvt *i, int event)
Definition: chan_dahdi.c:11595
static void monitor_pfds_clean(void *arg)
Definition: chan_dahdi.c:11854
static int ast_fdisset(struct pollfd *pfds, int fd, int maximum, int *start)
Helper function for migrating select to poll.
Definition: channel.h:2827
void * analog_handle_init_event(struct analog_pvt *i, int event)
Definition: sig_analog.c:3793
@ ANALOG_EVENT_DTMFCID
Definition: sig_analog.h:102
int msgstate
-1 = unknown, 0 = no messages, 1 = new messages available
Definition: sig_analog.h:284
int onhooktime
Definition: sig_analog.h:281
struct ast_channel * owner
Definition: sig_analog.h:277
struct analog_subchannel subs[3]
Definition: sig_analog.h:279
struct ast_channel * owner
Definition: sig_analog.h:264
struct timeval dtmfcid_delay
Definition: chan_dahdi.h:591
unsigned int mwisendactive
TRUE if a MWI message sending thread is active.
Definition: chan_dahdi.h:433
unsigned int mwimonitoractive
TRUE if an MWI monitor thread is currently active.
Definition: chan_dahdi.h:431
int dtmfcid_holdoff_state
Definition: chan_dahdi.h:590
unsigned int mwimonitor_fsk
TRUE if the FXO port monitors for fsk type MWI indications from the other end.
Definition: chan_dahdi.h:423
struct dahdi_pvt * pvt
Definition: chan_dahdi.c:11084
unsigned char buf[READ_SIZE]
Definition: chan_dahdi.c:11085
struct sla_ringing_trunk * next
Definition: app_sla.c:308
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:592

References ANALOG_EVENT_DTMFCID, analog_handle_init_event(), analog_ss_thread(), ast_callid_threadstorage_auto(), ast_callid_threadstorage_auto_clean(), ast_calloc, ast_debug, ast_fdisset(), ast_free, ast_hangup(), AST_LAW, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, ast_pthread_create_detached, AST_STATE_PRERING, ast_strlen_zero(), ast_verb, buf, mwi_thread_data::buf, calc_energy(), ast_channel::callid, dahdi_pvt::channel, dahdi_pvt::cid_start, CID_START_DTMF_NOALERT, dahdi_pvt::cidspill, dahdi_analog_lib_handles(), dahdi_destroy_channel_range(), dahdi_get_event(), dahdi_new(), dahdievent_to_analogevent(), dahdi_subchannel::dfd, dahdi_pvt::doreoriginate, dahdi_pvt::dtmfcid_delay, dahdi_pvt::dtmfcid_holdoff_state, dtmfcid_level, errno, event2str(), analog_pvt::fxsoffhookstate, handle_init_event(), has_voicemail(), ifcount, iflist, iflock, last, mwi_thread_data::len, dahdi_pvt::lock, LOG_ERROR, LOG_WARNING, monitor_pfds_clean(), analog_pvt::msgstate, mwi_send_init(), mwi_send_process_buffer(), mwi_send_process_event(), mwi_thread(), mwilevel, dahdi_pvt::mwimonitor_fsk, dahdi_pvt::mwimonitoractive, dahdi_pvt::mwisendactive, my_is_off_hook(), sla_ringing_trunk::next, dahdi_pvt::next, NULL, analog_pvt::onhooktime, dahdi_pvt::oprmode, dahdi_subchannel::owner, dahdi_pvt::owner, analog_subchannel::owner, analog_pvt::owner, mwi_thread_data::pvt, dahdi_pvt::radio, release_doomed_pris(), dahdi_pvt::sig, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_MFCR2, dahdi_pvt::sig_pvt, SUB_REAL, dahdi_pvt::subs, and analog_pvt::subs.

Referenced by restart_monitor().

◆ drc_sample()

static int drc_sample ( int  sample,
float  drc 
)
static

Definition at line 4998 of file chan_dahdi.c.

4999{
5000 float neg;
5001 float shallow, steep;
5002 float max = SHRT_MAX;
5003
5004 neg = (sample < 0 ? -1 : 1);
5005 steep = drc*sample;
5006 shallow = neg*(max-max/drc)+(float)sample/drc;
5007 if (fabsf(steep) < fabsf(shallow)) {
5008 sample = steep;
5009 }
5010 else {
5011 sample = shallow;
5012 }
5013
5014 return sample;
5015}
#define max(a, b)
Definition: f2c.h:198

References max.

Referenced by fill_rxgain(), and fill_txgain().

◆ duplicate_pseudo()

static struct dahdi_pvt * duplicate_pseudo ( struct dahdi_pvt src)
static

Definition at line 13678 of file chan_dahdi.c.

13679{
13680 struct dahdi_pvt *p;
13681 struct dahdi_bufferinfo bi;
13682 int res;
13683
13684 p = ast_malloc(sizeof(*p));
13685 if (!p) {
13686 return NULL;
13687 }
13688 *p = *src;
13689
13690 /* Must deep copy the cc_params. */
13692 if (!p->cc_params) {
13693 ast_free(p);
13694 return NULL;
13695 }
13697
13699 p->next = NULL;
13700 p->prev = NULL;
13701 ast_mutex_init(&p->lock);
13702 p->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo");
13703 if (p->subs[SUB_REAL].dfd < 0) {
13704 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno));
13706 return NULL;
13707 }
13708 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
13709 if (!res) {
13710 bi.txbufpolicy = src->buf_policy;
13711 bi.rxbufpolicy = src->buf_policy;
13712 bi.numbufs = src->buf_no;
13713 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
13714 if (res < 0) {
13715 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel: %s\n", strerror(errno));
13716 }
13717 } else
13718 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel: %s\n", strerror(errno));
13719 p->destroy = 1;
13721 return p;
13722}
static void dahdi_iflist_insert(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:5552
#define ast_mutex_init(pmutex)
Definition: lock.h:186

References ast_cc_config_params_init, ast_cc_copy_config_params(), ast_free, ast_log, ast_malloc, ast_mutex_init, dahdi_pvt::buf_no, dahdi_pvt::buf_policy, dahdi_pvt::cc_params, dahdi_iflist_insert(), DAHDI_IFLIST_NONE, dahdi_open(), dahdi_pvt::destroy, destroy_dahdi_pvt(), dahdi_subchannel::dfd, errno, dahdi_pvt::lock, LOG_ERROR, LOG_WARNING, dahdi_pvt::next, NULL, dahdi_pvt::prev, SUB_REAL, dahdi_pvt::subs, and dahdi_pvt::which_iflist.

Referenced by dahdi_request().

◆ event2str()

static const char * event2str ( int  event)
static

Definition at line 4642 of file chan_dahdi.c.

4643{
4644 static char buf[256];
4645 if ((event > -1) && (event < (ARRAY_LEN(events))) )
4646 return events[event];
4647 sprintf(buf, "Event %d", event); /* safe */
4648 return buf;
4649}
static const char *const events[]
Definition: chan_dahdi.c:4597

References ARRAY_LEN, buf, and events.

Referenced by __dahdi_exception(), analog_ss_thread(), dahdi_handle_event(), do_monitor(), mwi_thread(), and my_distinctive_ring().

◆ fill_rxgain()

static void fill_rxgain ( struct dahdi_gains *  g,
float  gain,
float  drc,
int  law 
)
static

Definition at line 5068 of file chan_dahdi.c.

5069{
5070 int j;
5071 int k;
5072 float linear_gain = pow(10.0, gain / 20.0);
5073
5074 switch (law) {
5075 case DAHDI_LAW_ALAW:
5076 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
5077 if (gain || drc) {
5078 k = AST_ALAW(j);
5079 if (drc) {
5080 k = drc_sample(k, drc);
5081 }
5082 k = (float)k * linear_gain;
5083 if (k > 32767) {
5084 k = 32767;
5085 } else if (k < -32768) {
5086 k = -32768;
5087 }
5088 g->rxgain[j] = AST_LIN2A(k);
5089 } else {
5090 g->rxgain[j] = j;
5091 }
5092 }
5093 break;
5094 case DAHDI_LAW_MULAW:
5095 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
5096 if (gain || drc) {
5097 k = AST_MULAW(j);
5098 if (drc) {
5099 k = drc_sample(k, drc);
5100 }
5101 k = (float)k * linear_gain;
5102 if (k > 32767) {
5103 k = 32767;
5104 } else if (k < -32768) {
5105 k = -32768;
5106 }
5107 g->rxgain[j] = AST_LIN2MU(k);
5108 } else {
5109 g->rxgain[j] = j;
5110 }
5111 }
5112 break;
5113 }
5114}
#define AST_LIN2A(a)
Definition: alaw.h:50
static int drc_sample(int sample, float drc)
Definition: chan_dahdi.c:4998
#define AST_LIN2MU(a)
Definition: ulaw.h:49

References ARRAY_LEN, AST_ALAW, AST_LIN2A, AST_LIN2MU, AST_MULAW, and drc_sample().

Referenced by set_actual_rxgain().

◆ fill_txgain()

static void fill_txgain ( struct dahdi_gains *  g,
float  gain,
float  drc,
int  law 
)
static

Definition at line 5018 of file chan_dahdi.c.

5019{
5020 int j;
5021 int k;
5022
5023 float linear_gain = pow(10.0, gain / 20.0);
5024
5025 switch (law) {
5026 case DAHDI_LAW_ALAW:
5027 for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
5028 if (gain || drc) {
5029 k = AST_ALAW(j);
5030 if (drc) {
5031 k = drc_sample(k, drc);
5032 }
5033 k = (float)k * linear_gain;
5034 if (k > 32767) {
5035 k = 32767;
5036 } else if (k < -32768) {
5037 k = -32768;
5038 }
5039 g->txgain[j] = AST_LIN2A(k);
5040 } else {
5041 g->txgain[j] = j;
5042 }
5043 }
5044 break;
5045 case DAHDI_LAW_MULAW:
5046 for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
5047 if (gain || drc) {
5048 k = AST_MULAW(j);
5049 if (drc) {
5050 k = drc_sample(k, drc);
5051 }
5052 k = (float)k * linear_gain;
5053 if (k > 32767) {
5054 k = 32767;
5055 } else if (k < -32768) {
5056 k = -32768;
5057 }
5058 g->txgain[j] = AST_LIN2MU(k);
5059
5060 } else {
5061 g->txgain[j] = j;
5062 }
5063 }
5064 break;
5065 }
5066}

References ARRAY_LEN, AST_ALAW, AST_LIN2A, AST_LIN2MU, AST_MULAW, and drc_sample().

Referenced by set_actual_txgain().

◆ find_channel()

static struct dahdi_pvt * find_channel ( int  channel)
static

Definition at line 16755 of file chan_dahdi.c.

16756{
16757 struct dahdi_pvt *p;
16758
16760 for (p = iflist; p; p = p->next) {
16761 if (p->channel == channel) {
16762 break;
16763 }
16764 }
16766 return p;
16767}

References ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, iflist, iflock, and dahdi_pvt::next.

Referenced by find_channel_from_str().

◆ find_channel_from_str()

static struct dahdi_pvt * find_channel_from_str ( const char *  channel)
static

Definition at line 16778 of file chan_dahdi.c.

16779{
16780 int chan_num;
16781
16782 if (sscanf(channel, "%30d", &chan_num) != 1) {
16783 /* Not numeric string. */
16784 return NULL;
16785 }
16786
16787 return find_channel(chan_num);
16788}
static struct dahdi_pvt * find_channel(int channel)
Definition: chan_dahdi.c:16755

References dahdi_pvt::channel, find_channel(), and NULL.

Referenced by action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_transfer(), and action_transferhangup().

◆ find_next_iface_in_span()

static struct dahdi_pvt * find_next_iface_in_span ( struct dahdi_pvt cur)
static

Definition at line 5816 of file chan_dahdi.c.

5817{
5818 if (cur->next && cur->next->span == cur->span) {
5819 return cur->next;
5820 } else if (cur->prev && cur->prev->span == cur->span) {
5821 return cur->prev;
5822 }
5823
5824 return NULL;
5825}

References dahdi_pvt::next, NULL, dahdi_pvt::prev, and dahdi_pvt::span.

Referenced by destroy_dahdi_pvt().

◆ fxo_pvt()

static struct dahdi_pvt * fxo_pvt ( struct ast_channel chan)
static

Return DAHDI pivot if channel is FXO signalled.

Definition at line 2842 of file chan_dahdi.c.

2843{
2844 int res;
2845 struct dahdi_params dahdip;
2846 struct dahdi_pvt *pvt = NULL;
2847
2848 if (strcasecmp(ast_channel_tech(chan)->type, "DAHDI")) {
2849 ast_log(LOG_WARNING, "%s is not a DAHDI channel\n", ast_channel_name(chan));
2850 return NULL;
2851 }
2852
2853 memset(&dahdip, 0, sizeof(dahdip));
2854 res = ioctl(ast_channel_fd(chan, 0), DAHDI_GET_PARAMS, &dahdip);
2855
2856 if (res) {
2857 ast_log(LOG_WARNING, "Unable to get parameters of %s: %s\n", ast_channel_name(chan), strerror(errno));
2858 return NULL;
2859 }
2860 if (!(dahdip.sigtype & __DAHDI_SIG_FXO)) {
2861 ast_log(LOG_WARNING, "%s is not FXO signalled\n", ast_channel_name(chan));
2862 return NULL;
2863 }
2864
2865 pvt = ast_channel_tech_pvt(chan);
2866 if (!dahdi_analog_lib_handles(pvt->sig, 0, 0)) {
2867 ast_log(LOG_WARNING, "Channel signalling is not analog");
2868 return NULL;
2869 }
2870
2871 return pvt;
2872}

References ast_channel_fd(), ast_channel_name(), ast_channel_tech(), ast_channel_tech_pvt(), ast_log, dahdi_analog_lib_handles(), errno, LOG_WARNING, NULL, dahdi_pvt::sig, and type.

Referenced by polarity_read(), and polarity_write().

◆ gen_pvt_field_callback() [1/3]

gen_pvt_field_callback ( int  ,
firstdigit_timeout   
)

◆ gen_pvt_field_callback() [2/3]

gen_pvt_field_callback ( int  ,
interdigit_timeout   
)

◆ gen_pvt_field_callback() [3/3]

gen_pvt_field_callback ( int  ,
matchdigit_timeout   
)

◆ get_alarms()

static int get_alarms ( struct dahdi_pvt p)
static

Checks channel for alarms

Parameters
pa channel to check for alarms.
Returns
the alarms on the span to which the channel belongs, or alarms on the channel if no span alarms.

Definition at line 7567 of file chan_dahdi.c.

7568{
7569 int res;
7570 struct dahdi_spaninfo zi;
7571 struct dahdi_params params;
7572
7573 memset(&zi, 0, sizeof(zi));
7574 zi.spanno = p->span;
7575
7576 if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SPANSTAT, &zi)) >= 0) {
7577 if (zi.alarms != DAHDI_ALARM_NONE)
7578 return zi.alarms;
7579 } else {
7580 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d: %s\n", p->channel, strerror(errno));
7581 return 0;
7582 }
7583
7584 /* No alarms on the span. Check for channel alarms. */
7585 memset(&params, 0, sizeof(params));
7586 if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &params)) >= 0)
7587 return params.chan_alarms;
7588
7589 ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
7590
7591 return DAHDI_ALARM_NONE;
7592}

References ast_log, dahdi_pvt::channel, dahdi_subchannel::dfd, errno, LOG_WARNING, dahdi_pvt::span, SUB_REAL, and dahdi_pvt::subs.

Referenced by action_dahdishowchannels(), dahdi_handle_event(), dahdi_show_channels(), handle_init_event(), mkintf(), mwi_thread(), and my_get_and_handle_alarms().

◆ handle_alarms()

static void handle_alarms ( struct dahdi_pvt p,
int  alms 
)
static

Definition at line 7727 of file chan_dahdi.c.

7728{
7729 const char *alarm_str;
7730
7731#if defined(HAVE_PRI)
7733 return;
7734 }
7735#endif /* defined(HAVE_PRI) */
7736
7737 alarm_str = alarm2str(alms);
7739 ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
7740 publish_channel_alarm(p->channel, alarm_str);
7741 }
7742
7744 ast_log(LOG_WARNING, "Detected alarm on span %d: %s\n", p->span, alarm_str);
7745 publish_span_alarm(p->span, alarm_str);
7746 }
7747}
static void publish_channel_alarm(int channel, const char *alarm_txt)
Definition: chan_dahdi.c:7708
static void publish_span_alarm(int span, const char *alarm_txt)
Definition: chan_dahdi.c:7694
static int report_alarms
Definition: chan_dahdi.c:738
#define REPORT_CHANNEL_ALARMS
Definition: chan_dahdi.c:736
#define REPORT_SPAN_ALARMS
Definition: chan_dahdi.c:737
int sig_pri_is_alarm_ignored(struct sig_pri_span *pri)

References alarm2str(), ast_log, dahdi_pvt::channel, dahdi_sig_pri_lib_handles(), LOG_WARNING, dahdi_pvt::manages_span_alarms, publish_channel_alarm(), publish_span_alarm(), report_alarms, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, dahdi_pvt::sig, sig_pri_is_alarm_ignored(), and dahdi_pvt::span.

Referenced by dahdi_handle_event(), handle_init_event(), mkintf(), mwi_thread(), and my_get_and_handle_alarms().

◆ handle_clear_alarms()

static void handle_clear_alarms ( struct dahdi_pvt p)
static

Definition at line 3796 of file chan_dahdi.c.

3797{
3798#if defined(HAVE_PRI)
3800 return;
3801 }
3802#endif /* defined(HAVE_PRI) */
3803
3806 }
3809 }
3810}
static void publish_channel_alarm_clear(int channel)
Definition: chan_dahdi.c:3765
static void publish_span_alarm_clear(int span)
Definition: chan_dahdi.c:3783

References dahdi_pvt::channel, dahdi_sig_pri_lib_handles(), dahdi_pvt::manages_span_alarms, publish_channel_alarm_clear(), publish_span_alarm_clear(), report_alarms, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, dahdi_pvt::sig, sig_pri_is_alarm_ignored(), and dahdi_pvt::span.

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

◆ handle_dahdi_show_cadences()

static char * handle_dahdi_show_cadences ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 16273 of file chan_dahdi.c.

16274{
16275 int i, j;
16276 switch (cmd) {
16277 case CLI_INIT:
16278 e->command = "dahdi show cadences";
16279 e->usage =
16280 "Usage: dahdi show cadences\n"
16281 " Shows all cadences currently defined\n";
16282 return NULL;
16283 case CLI_GENERATE:
16284 return NULL;
16285 }
16286 for (i = 0; i < num_cadence; i++) {
16287 char output[1024];
16288 char tmp[16], tmp2[64];
16289 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
16290 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
16291
16292 for (j = 0; j < 16; j++) {
16293 if (cadences[i].ringcadence[j] == 0)
16294 break;
16295 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
16296 if (cidrings[i] * 2 - 1 == j)
16297 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
16298 else
16299 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
16300 if (j != 0)
16301 strncat(output, ",", sizeof(output) - strlen(output) - 1);
16302 strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
16303 }
16304 ast_cli(a->fd,"%s\n",output);
16305 }
16306 return CLI_SUCCESS;
16307}
static int cidrings[NUM_CADENCE_MAX]
cidrings says in which pause to transmit the cid information, where the first pause is 1,...
Definition: chan_dahdi.c:701
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX]
Definition: chan_dahdi.c:690
static int num_cadence
Definition: chan_dahdi.c:685
#define COLOR_MAGENTA
Definition: term.h:60
#define COLOR_BLACK
Definition: term.h:50
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
Definition: term.c:235
#define COLOR_GREEN
Definition: term.h:54

References a, ast_cli(), cadences, cidrings, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, COLOR_BLACK, COLOR_GREEN, COLOR_MAGENTA, ast_cli_entry::command, NULL, num_cadence, term_color(), tmp(), and ast_cli_entry::usage.

◆ handle_init_event()

static struct dahdi_pvt * handle_init_event ( struct dahdi_pvt i,
int  event 
)
static

Definition at line 11595 of file chan_dahdi.c.

11596{
11597 int res;
11598 pthread_t threadid;
11599 struct ast_channel *chan;
11600 ast_callid callid = 0;
11601 int callid_created;
11602
11603 /* Handle an event on a given channel for the monitor thread. */
11604
11605 switch (event) {
11606 case DAHDI_EVENT_NONE:
11607 case DAHDI_EVENT_BITSCHANGED:
11608 break;
11609 case DAHDI_EVENT_WINKFLASH:
11610 case DAHDI_EVENT_RINGOFFHOOK:
11611 if (i->inalarm) break;
11612 if (i->radio) break;
11613 /* Got a ring/answer. What kind of channel are we? */
11614 switch (i->sig) {
11615 case SIG_FXOLS:
11616 case SIG_FXOGS:
11617 case SIG_FXOKS:
11618 res = dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
11619 if (res && (errno == EBUSY)) {
11620 break;
11621 }
11622
11623 callid_created = ast_callid_threadstorage_auto(&callid);
11624
11625 /* Cancel VMWI spill */
11626 ast_free(i->cidspill);
11627 i->cidspill = NULL;
11629
11630 if (i->immediate) {
11631 dahdi_ec_enable(i);
11632 /* The channel is immediately up. Start right away */
11633 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
11634 chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, NULL, NULL, callid);
11635 if (!chan) {
11636 ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
11637 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
11638 if (res < 0)
11639 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
11640 }
11641 } else {
11642 /* Check for callerid, digits, etc */
11643 chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, NULL, NULL, callid);
11644 if (chan) {
11645 if (has_voicemail(i))
11646 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
11647 else
11648 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
11649 if (res < 0)
11650 ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
11651 if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
11652 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
11653 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
11654 if (res < 0)
11655 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
11656 ast_hangup(chan);
11657 }
11658 } else
11659 ast_log(LOG_WARNING, "Unable to create channel\n");
11660 }
11661
11663 break;
11664 case SIG_FXSLS:
11665 case SIG_FXSGS:
11666 case SIG_FXSKS:
11667 i->ringt = i->ringt_base;
11668 /* Fall through */
11669 case SIG_EMWINK:
11670 case SIG_FEATD:
11671 case SIG_FEATDMF:
11672 case SIG_FEATDMF_TA:
11673 case SIG_E911:
11674 case SIG_FGC_CAMA:
11675 case SIG_FGC_CAMAMF:
11676 case SIG_FEATB:
11677 case SIG_EM:
11678 case SIG_EM_E1:
11679 case SIG_SFWINK:
11680 case SIG_SF_FEATD:
11681 case SIG_SF_FEATDMF:
11682 case SIG_SF_FEATB:
11683 case SIG_SF:
11684 /* Check for callerid, digits, etc */
11685 callid_created = ast_callid_threadstorage_auto(&callid);
11686 if (i->cid_start == CID_START_POLARITY_IN) {
11687 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
11688 } else {
11689 chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, NULL, NULL, callid);
11690 }
11691
11692 if (!chan) {
11693 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
11694 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
11695 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
11696 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
11697 if (res < 0) {
11698 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
11699 }
11700 ast_hangup(chan);
11701 }
11702
11704 break;
11705 default:
11706 ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
11707 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
11708 if (res < 0)
11709 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
11710 return NULL;
11711 }
11712 break;
11713 case DAHDI_EVENT_NOALARM:
11714 switch (i->sig) {
11715#if defined(HAVE_PRI)
11717 ast_mutex_lock(&i->lock);
11720 break;
11721#endif /* defined(HAVE_PRI) */
11722#if defined(HAVE_SS7)
11723 case SIG_SS7:
11725 break;
11726#endif /* defined(HAVE_SS7) */
11727 default:
11728 i->inalarm = 0;
11729 break;
11730 }
11732 break;
11733 case DAHDI_EVENT_ALARM:
11734 switch (i->sig) {
11735#if defined(HAVE_PRI)
11737 ast_mutex_lock(&i->lock);
11740 break;
11741#endif /* defined(HAVE_PRI) */
11742#if defined(HAVE_SS7)
11743 case SIG_SS7:
11745 break;
11746#endif /* defined(HAVE_SS7) */
11747 default:
11748 i->inalarm = 1;
11749 break;
11750 }
11751 res = get_alarms(i);
11752 handle_alarms(i, res);
11753 /* fall thru intentionally */
11754 case DAHDI_EVENT_ONHOOK:
11755 if (i->radio)
11756 break;
11757 /* Back on hook. Hang up. */
11758 switch (i->sig) {
11759 case SIG_FXOLS:
11760 case SIG_FXOGS:
11761 case SIG_FEATD:
11762 case SIG_FEATDMF:
11763 case SIG_FEATDMF_TA:
11764 case SIG_E911:
11765 case SIG_FGC_CAMA:
11766 case SIG_FGC_CAMAMF:
11767 case SIG_FEATB:
11768 case SIG_EM:
11769 case SIG_EM_E1:
11770 case SIG_EMWINK:
11771 case SIG_SF_FEATD:
11772 case SIG_SF_FEATDMF:
11773 case SIG_SF_FEATB:
11774 case SIG_SF:
11775 case SIG_SFWINK:
11776 case SIG_FXSLS:
11777 case SIG_FXSGS:
11778 case SIG_FXSKS:
11779 case SIG_FXOKS:
11781 /* Diddle the battery for the zhone */
11782#ifdef ZHONE_HACK
11783 dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
11784 usleep(1);
11785#endif
11786 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
11787 dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
11788 break;
11789 case SIG_SS7:
11792 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
11793 break;
11794 default:
11795 ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
11796 res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
11797 return NULL;
11798 }
11799 break;
11800 case DAHDI_EVENT_POLARITY:
11801 switch (i->sig) {
11802 case SIG_FXSLS:
11803 case SIG_FXSKS:
11804 case SIG_FXSGS:
11805 /* We have already got a PR before the channel was
11806 created, but it wasn't handled. We need polarity
11807 to be REV for remote hangup detection to work.
11808 At least in Spain */
11809 callid_created = ast_callid_threadstorage_auto(&callid);
11814 ast_verb(2, "Starting post polarity "
11815 "CID detection on channel %d\n",
11816 i->channel);
11817 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
11818 if (!chan) {
11819 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
11820 } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
11821 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
11822 ast_hangup(chan);
11823 }
11824 }
11826 break;
11827 default:
11828 ast_log(LOG_WARNING, "handle_init_event detected "
11829 "polarity reversal on non-FXO (SIG_FXS) "
11830 "interface %d\n", i->channel);
11831 }
11832 break;
11833 case DAHDI_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */
11835 "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n",
11836 i->channel);
11837 return i;
11838 case DAHDI_EVENT_NEONMWI_ACTIVE:
11839 if (i->mwimonitor_neon) {
11840 notify_message(i->mailbox, 1);
11841 ast_log(LOG_NOTICE, "NEON MWI set for channel %d, mailbox %s \n", i->channel, i->mailbox);
11842 }
11843 break;
11844 case DAHDI_EVENT_NEONMWI_INACTIVE:
11845 if (i->mwimonitor_neon) {
11846 notify_message(i->mailbox, 0);
11847 ast_log(LOG_NOTICE, "NEON MWI cleared for channel %d, mailbox %s\n", i->channel, i->mailbox);
11848 }
11849 break;
11850 }
11851 return NULL;
11852}
static void notify_message(char *mailbox, int thereornot)
Send MWI state change.
Definition: chan_dahdi.c:3553
char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Voice mailbox location.
Definition: chan_dahdi.h:709
unsigned int mwimonitor_neon
TRUE if the FXO port monitors for neon type MWI indications from the other end.
Definition: chan_dahdi.h:418

References analog_ss_thread(), ast_callid_threadstorage_auto(), ast_callid_threadstorage_auto_clean(), ast_free, ast_hangup(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_detached, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, ast_verb, ast_channel::callid, dahdi_pvt::channel, dahdi_pvt::cid_start, CID_START_POLARITY, CID_START_POLARITY_IN, dahdi_pvt::cidspill, dahdi_ec_disable(), dahdi_ec_enable(), dahdi_new(), dahdi_set_hook(), dahdi_subchannel::dfd, errno, get_alarms(), handle_alarms(), handle_clear_alarms(), dahdi_pvt::hanguponpolarityswitch, has_voicemail(), dahdi_pvt::immediate, dahdi_pvt::inalarm, dahdi_pvt::lock, LOG_NOTICE, LOG_WARNING, dahdi_pvt::mailbox, dahdi_pvt::mwimonitor_neon, notify_message(), NULL, dahdi_pvt::polarity, POLARITY_REV, dahdi_pvt::radio, restore_conference(), dahdi_pvt::ringt, dahdi_pvt::ringt_base, dahdi_pvt::sig, sig2str, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, sig_pri_chan_alarm_notify(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, SIG_SS7, sig_ss7_set_alarm(), SUB_REAL, and dahdi_pvt::subs.

Referenced by do_monitor().

◆ has_voicemail()

static int has_voicemail ( struct dahdi_pvt p)
static

Definition at line 5293 of file chan_dahdi.c.

5294{
5295 int new_msgs;
5296 RAII_VAR(struct stasis_message *, mwi_message, NULL, ao2_cleanup);
5297
5298 /* A manual MWI disposition has been requested, use that instead
5299 * if this is for sending the new MWI indication. */
5300 if (p->mwioverride_active) {
5301 /* We don't clear p->mwioverride_active automatically,
5302 * because otherwise do_monitor would just change it back to the way it was.
5303 * We need to keep the override active until explicitly disabled by the user,
5304 * so that we can keep returning the correct answer in subsequent calls to do_monitor. */
5305 ast_debug(6, "MWI manual override active on channel %d: pretending that it should be %s\n",
5306 p->channel, p->mwioverride_disposition ? "active" : "inactive");
5307 return p->mwioverride_disposition;
5308 }
5309
5311 if (mwi_message) {
5312 struct ast_mwi_state *mwi_state = stasis_message_data(mwi_message);
5313 new_msgs = mwi_state->new_msgs;
5314 } else {
5316 }
5317
5318 return new_msgs;
5319}
int ast_app_has_voicemail(const char *mailboxes, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX"....
Definition: main/app.c:582
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
Definition: mwi.c:94
struct stasis_message * stasis_cache_get(struct stasis_cache *cache, struct stasis_message_type *type, const char *id)
Retrieve an item from the cache for the ast_eid_default entity.
Definition: stasis_cache.c:686
The structure that contains MWI state.
Definition: mwi.h:455
int new_msgs
Definition: mwi.h:459

References ao2_cleanup, ast_app_has_voicemail(), ast_debug, ast_mwi_state_cache(), ast_mwi_state_type(), dahdi_pvt::channel, dahdi_pvt::mailbox, dahdi_pvt::mwioverride_active, dahdi_pvt::mwioverride_disposition, ast_mwi_state::new_msgs, NULL, RAII_VAR, stasis_cache_get(), and stasis_message_data().

Referenced by dahdi_handle_event(), do_monitor(), handle_init_event(), mwi_send_init(), and my_has_voicemail().

◆ is_group_or_channel_match()

static int is_group_or_channel_match ( struct dahdi_pvt p,
int  span,
ast_group_t  groupmatch,
int *  groupmatched,
int  channelmatch,
int *  channelmatched 
)
static

Definition at line 13439 of file chan_dahdi.c.

13440{
13441#if defined(HAVE_PRI)
13442 if (0 < span) {
13443 /* The channel must be on the specified PRI span. */
13444 if (!p->pri || p->pri->span != span) {
13445 return 0;
13446 }
13447 if (!groupmatch && channelmatch == -1) {
13448 /* Match any group since it only needs to be on the PRI span. */
13449 *groupmatched = 1;
13450 return 1;
13451 }
13452 }
13453#endif /* defined(HAVE_PRI) */
13454 /* check group matching */
13455 if (groupmatch) {
13456 if ((p->group & groupmatch) != groupmatch)
13457 /* Doesn't match the specified group, try the next one */
13458 return 0;
13459 *groupmatched = 1;
13460 }
13461 /* Check to see if we have a channel match */
13462 if (channelmatch != -1) {
13463 if (p->channel != channelmatch)
13464 /* Doesn't match the specified channel, try the next one */
13465 return 0;
13466 *channelmatched = 1;
13467 }
13468
13469 return 1;
13470}

References dahdi_pvt::channel, dahdi_pvt::group, and dahdi_pvt::span.

Referenced by dahdi_cc_callback(), and dahdi_request().

◆ isourconf()

static int isourconf ( struct dahdi_pvt p,
struct dahdi_subchannel c 
)
static

Definition at line 4755 of file chan_dahdi.c.

4756{
4757 /* If they're listening to our channel, they're ours */
4758 if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON))
4759 return 1;
4760 /* If they're a talker on our (allocated) conference, they're ours */
4761 if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER))
4762 return 1;
4763 return 0;
4764}

References c, dahdi_pvt::channel, and dahdi_pvt::confno.

Referenced by conf_del().

◆ isslavenative()

static int isslavenative ( struct dahdi_pvt p,
struct dahdi_pvt **  out 
)
static

Definition at line 4785 of file chan_dahdi.c.

4786{
4787 int x;
4788 int useslavenative;
4789 struct dahdi_pvt *slave = NULL;
4790 /* Start out optimistic */
4791 useslavenative = 1;
4792 /* Update conference state in a stateless fashion */
4793 for (x = 0; x < 3; x++) {
4794 /* Any three-way calling makes slave native mode *definitely* out
4795 of the question */
4796 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway)
4797 useslavenative = 0;
4798 }
4799 /* If we don't have any 3-way calls, check to see if we have
4800 precisely one slave */
4801 if (useslavenative) {
4802 for (x = 0; x < MAX_SLAVES; x++) {
4803 if (p->slaves[x]) {
4804 if (slave) {
4805 /* Whoops already have a slave! No
4806 slave native and stop right away */
4807 slave = NULL;
4808 useslavenative = 0;
4809 break;
4810 } else {
4811 /* We have one slave so far */
4812 slave = p->slaves[x];
4813 }
4814 }
4815 }
4816 }
4817 /* If no slave, slave native definitely out */
4818 if (!slave)
4819 useslavenative = 0;
4820 else if (slave->law != p->law) {
4821 useslavenative = 0;
4822 slave = NULL;
4823 }
4824 if (out)
4825 *out = slave;
4826 return useslavenative;
4827}

References dahdi_subchannel::dfd, dahdi_subchannel::inthreeway, dahdi_pvt::law, MAX_SLAVES, NULL, out, dahdi_pvt::slaves, and dahdi_pvt::subs.

Referenced by dahdi_conf_update(), and my_complete_conference_update().

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 20279 of file chan_dahdi.c.

20280{
20281 int res;
20282#if defined(HAVE_PRI) || defined(HAVE_SS7)
20283 int y;
20284#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
20285
20286 if (STASIS_MESSAGE_TYPE_INIT(dahdichannel_type)) {
20288 }
20289
20292 }
20296
20300 }
20301
20302#ifdef HAVE_PRI
20303 memset(pris, 0, sizeof(pris));
20304 for (y = 0; y < NUM_SPANS; y++) {
20305 sig_pri_init_pri(&pris[y].pri);
20306 }
20307 pri_set_error(dahdi_pri_error);
20308 pri_set_message(dahdi_pri_message);
20309 ast_register_application_xml(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec);
20310#ifdef HAVE_PRI_PROG_W_CAUSE
20311 ast_register_application_xml(dahdi_send_callrerouting_facility_app, dahdi_send_callrerouting_facility_exec);
20312#endif
20313#if defined(HAVE_PRI_CCSS)
20314 if (ast_cc_agent_register(&dahdi_pri_cc_agent_callbacks)
20315 || ast_cc_monitor_register(&dahdi_pri_cc_monitor_callbacks)) {
20318 }
20319#endif /* defined(HAVE_PRI_CCSS) */
20320 if (sig_pri_load(
20321#if defined(HAVE_PRI_CCSS)
20322 dahdi_pri_cc_type
20323#else
20324 NULL
20325#endif /* defined(HAVE_PRI_CCSS) */
20326 )) {
20329 }
20330#endif
20331#if defined(HAVE_SS7)
20332 memset(linksets, 0, sizeof(linksets));
20333 for (y = 0; y < NUM_SPANS; y++) {
20334 sig_ss7_init_linkset(&linksets[y].ss7);
20335 }
20336 ss7_set_error(dahdi_ss7_error);
20337 ss7_set_message(dahdi_ss7_message);
20338 ss7_set_hangup(sig_ss7_cb_hangup);
20339 ss7_set_notinservice(sig_ss7_cb_notinservice);
20340 ss7_set_call_null(sig_ss7_cb_call_null);
20341#endif /* defined(HAVE_SS7) */
20342 res = setup_dahdi(0);
20343 /* Make sure we can register our DAHDI channel type */
20344 if (res) {
20347 }
20349 ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n");
20352 }
20353#ifdef HAVE_PRI
20354 ast_cli_register_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
20355#endif
20356#if defined(HAVE_SS7)
20357 ast_cli_register_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli));
20358#endif /* defined(HAVE_SS7) */
20359#ifdef HAVE_OPENR2
20360 ast_cli_register_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli));
20361 ast_register_application_xml(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec);
20362#endif
20363
20365
20367 memset(round_robin, 0, sizeof(round_robin));
20368 ast_manager_register_xml("DAHDITransfer", 0, action_transfer);
20370 ast_manager_register_xml("DAHDIDialOffhook", 0, action_dahdidialoffhook);
20373 ast_manager_register_xml("DAHDIShowChannels", 0, action_dahdishowchannels);
20374 ast_manager_register_xml("DAHDIShowStatus", 0, action_dahdishowstatus);
20376#if defined(HAVE_PRI)
20377 ast_manager_register_xml("PRIShowSpans", 0, action_prishowspans);
20378 ast_manager_register_xml("PRIDebugSet", 0, action_pri_debug_set);
20379 ast_manager_register_xml("PRIDebugFileSet", EVENT_FLAG_SYSTEM, action_pri_debug_file_set);
20380 ast_manager_register_xml("PRIDebugFileUnset", 0, action_pri_debug_file_unset);
20381#endif /* defined(HAVE_PRI) */
20382
20384
20385 return res;
20386}
int dahdi_native_load(const struct ast_channel_tech *tech)
int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks)
Register a set of monitor callbacks with the core.
Definition: ccss.c:1162
int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks)
Register a set of agent callbacks with the core.
Definition: ccss.c:1217
static int __unload_module(void)
Definition: chan_dahdi.c:18108
static int action_transfer(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16828
static int action_dahdidndon(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16790
static int action_dahdishowchannels(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16906
static int action_dahdirestart(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:15979
static int action_dahdidndoff(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16809
static int action_dahdidialoffhook(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16874
static int action_transferhangup(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16851
static int action_dahdishowstatus(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16994
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define ast_cond_init(cond, attr)
Definition: lock.h:201
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558
int sig_pri_load(const char *cc_type_name)
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493

References __unload_module(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_dahdishowchannels(), action_dahdishowstatus(), action_transfer(), action_transferhangup(), ao2_ref, ARRAY_LEN, ast_cc_agent_register(), ast_cc_monitor_register(), ast_channel_register(), ast_cli_register_multiple, ast_cond_init, ast_custom_function_register, ast_format_alaw, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_slin, ast_format_ulaw, ast_log, ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, ast_register_application_xml, ast_channel_tech::capabilities, dahdi_cli, dahdi_native_load(), dahdi_tech, EVENT_FLAG_SYSTEM, LOG_ERROR, NULL, NUM_SPANS, polarity_function, round_robin, setup_dahdi(), sig_pri_init_pri(), sig_pri_load(), sig_ss7_cb_call_null(), sig_ss7_cb_hangup(), sig_ss7_cb_notinservice(), sig_ss7_init_linkset(), ss_thread_complete, and STASIS_MESSAGE_TYPE_INIT.

◆ mkintf()

static struct dahdi_pvt * mkintf ( int  channel,
const struct dahdi_chan_conf conf,
int  reloading 
)
static

< Current channel structure initializing

< TRUE if the channel interface already exists.

Definition at line 12493 of file chan_dahdi.c.

12494{
12495 /* Make a dahdi_pvt structure for this interface */
12496 struct dahdi_pvt *tmp;/*!< Current channel structure initializing */
12497 char fn[80];
12498 struct dahdi_bufferinfo bi;
12499
12500 int res;
12501#if defined(HAVE_PRI)
12502 int span = 0;
12503#endif /* defined(HAVE_PRI) */
12504 int here = 0;/*!< TRUE if the channel interface already exists. */
12505 int x;
12506 struct analog_pvt *analog_p = NULL;
12507 struct dahdi_params p;
12508#if defined(HAVE_PRI)
12509 struct dahdi_spaninfo si;
12510 struct sig_pri_chan *pri_chan = NULL;
12511#endif /* defined(HAVE_PRI) */
12512#if defined(HAVE_SS7)
12513 struct sig_ss7_chan *ss7_chan = NULL;
12514#endif /* defined(HAVE_SS7) */
12515
12516 /* Search channel interface list to see if it already exists. */
12517 for (tmp = iflist; tmp; tmp = tmp->next) {
12518 if (!tmp->destroy) {
12519 if (tmp->channel == channel) {
12520 /* The channel interface already exists. */
12521 here = 1;
12522 break;
12523 }
12524 if (tmp->channel > channel) {
12525 /* No way it can be in the sorted list. */
12526 tmp = NULL;
12527 break;
12528 }
12529 }
12530 }
12531
12532 if (!here && reloading != 1) {
12533 tmp = ast_calloc(1, sizeof(*tmp));
12534 if (!tmp) {
12535 return NULL;
12536 }
12537 tmp->cc_params = ast_cc_config_params_init();
12538 if (!tmp->cc_params) {
12539 ast_free(tmp);
12540 return NULL;
12541 }
12542 ast_mutex_init(&tmp->lock);
12543 ifcount++;
12544 for (x = 0; x < 3; x++)
12545 tmp->subs[x].dfd = -1;
12546 tmp->channel = channel;
12547 tmp->priindication_oob = conf->chan.priindication_oob;
12548 }
12549
12550 if (tmp) {
12551 int chan_sig = conf->chan.sig;
12552
12553 /* If there are variables in tmp before it is updated to match the new config, clear them */
12554 if (reloading && tmp->vars) {
12556 tmp->vars = NULL;
12557 }
12558
12559 if (!here) {
12560 /* Can only get here if this is a new channel interface being created. */
12561 if ((channel != CHAN_PSEUDO)) {
12562 int count = 0;
12563
12564 snprintf(fn, sizeof(fn), "%d", channel);
12565 /* Open non-blocking */
12566 tmp->subs[SUB_REAL].dfd = dahdi_open(fn);
12567 /* Retry open on restarts, but don't keep retrying if the channel doesn't exist (e.g. not configured) */
12568 while (tmp->subs[SUB_REAL].dfd < 0 && reloading == 2 && count < 1000 && errno != ENXIO) { /* the kernel may not call dahdi_release fast enough for the open flagbit to be cleared in time */
12569 usleep(1);
12570 tmp->subs[SUB_REAL].dfd = dahdi_open(fn);
12571 count++;
12572 }
12573 /* Allocate a DAHDI structure */
12574 if (tmp->subs[SUB_REAL].dfd < 0) {
12575 ast_log(LOG_ERROR, "Unable to open channel %d: %s\nhere = %d, tmp->channel = %d, channel = %d\n", channel, strerror(errno), here, tmp->channel, channel);
12577 return NULL;
12578 }
12579 memset(&p, 0, sizeof(p));
12580 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
12581 if (res < 0) {
12582 ast_log(LOG_ERROR, "Unable to get parameters: %s\n", strerror(errno));
12584 return NULL;
12585 }
12586 if (conf->is_sig_auto)
12587 chan_sig = sigtype_to_signalling(p.sigtype);
12588 if (p.sigtype != (chan_sig & 0x3ffff)) {
12589 ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(chan_sig), sig2str(p.sigtype));
12591 return NULL;
12592 }
12593 tmp->law_default = p.curlaw;
12594 tmp->law = p.curlaw;
12595 tmp->span = p.spanno;
12596#if defined(HAVE_PRI)
12597 span = p.spanno - 1;
12598#endif /* defined(HAVE_PRI) */
12599 } else {
12600 chan_sig = 0;
12601 }
12602 tmp->sig = chan_sig;
12603 tmp->outsigmod = conf->chan.outsigmod;
12604
12605 if (dahdi_analog_lib_handles(chan_sig, tmp->radio, tmp->oprmode)) {
12606 analog_p = analog_new(dahdisig_to_analogsig(chan_sig), tmp);
12607 if (!analog_p) {
12609 return NULL;
12610 }
12611 tmp->sig_pvt = analog_p;
12612 }
12613#if defined(HAVE_SS7)
12614 if (chan_sig == SIG_SS7) {
12615 struct dahdi_ss7 *ss7;
12616 int clear = 0;
12617
12618 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &clear)) {
12619 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
12621 return NULL;
12622 }
12623
12624 ss7 = ss7_resolve_linkset(cur_linkset);
12625 if (!ss7) {
12626 ast_log(LOG_ERROR, "Unable to find linkset %d\n", cur_linkset);
12628 return NULL;
12629 }
12630 ss7->ss7.span = cur_linkset;
12631 if (cur_cicbeginswith < 0) {
12632 ast_log(LOG_ERROR, "Need to set cicbeginswith for the channels!\n");
12634 return NULL;
12635 }
12636 ss7_chan = sig_ss7_chan_new(tmp, &ss7->ss7);
12637 if (!ss7_chan) {
12639 return NULL;
12640 }
12641 tmp->sig_pvt = ss7_chan;
12642 tmp->ss7 = &ss7->ss7;
12643
12644 ss7_chan->channel = tmp->channel;
12645 ss7_chan->cic = cur_cicbeginswith++;
12646
12647 /* DB: Add CIC's DPC information */
12648 ss7_chan->dpc = cur_defaultdpc;
12649
12650 ss7->ss7.pvts[ss7->ss7.numchans++] = ss7_chan;
12651
12652 ast_copy_string(ss7->ss7.internationalprefix, conf->ss7.ss7.internationalprefix, sizeof(ss7->ss7.internationalprefix));
12653 ast_copy_string(ss7->ss7.nationalprefix, conf->ss7.ss7.nationalprefix, sizeof(ss7->ss7.nationalprefix));
12654 ast_copy_string(ss7->ss7.subscriberprefix, conf->ss7.ss7.subscriberprefix, sizeof(ss7->ss7.subscriberprefix));
12655 ast_copy_string(ss7->ss7.unknownprefix, conf->ss7.ss7.unknownprefix, sizeof(ss7->ss7.unknownprefix));
12656 ast_copy_string(ss7->ss7.networkroutedprefix, conf->ss7.ss7.networkroutedprefix, sizeof(ss7->ss7.networkroutedprefix));
12657
12658 ss7->ss7.called_nai = conf->ss7.ss7.called_nai;
12659 ss7->ss7.calling_nai = conf->ss7.ss7.calling_nai;
12660 }
12661#endif /* defined(HAVE_SS7) */
12662#ifdef HAVE_OPENR2
12663 if (chan_sig == SIG_MFCR2) {
12664 struct dahdi_mfcr2 *r2_link;
12665 struct r2link_entry *r2_le = dahdi_r2_get_link(conf);
12666 r2_link = &r2_le->mfcr2;
12667 if (!r2_link) {
12668 ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n");
12670 return NULL;
12671 }
12672 if (!r2_link->protocol_context && dahdi_r2_set_context(r2_link, conf)) {
12673 ast_log(LOG_ERROR, "Cannot create OpenR2 protocol context.\n");
12675 return NULL;
12676 }
12677 if (r2_link->numchans == ARRAY_LEN(r2_link->pvts)) {
12678 ast_log(LOG_ERROR, "Cannot add more channels to this link!\n");
12680 return NULL;
12681 }
12682 r2_link->pvts[r2_link->numchans++] = tmp;
12683 tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context,
12684 tmp->subs[SUB_REAL].dfd,
12685 NULL, NULL);
12686 if (!tmp->r2chan) {
12687 openr2_liberr_t err = openr2_context_get_last_error(r2_link->protocol_context);
12688 ast_log(LOG_ERROR, "Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err));
12690 return NULL;
12691 }
12692 r2_link->live_chans++;
12693 tmp->mfcr2 = r2_link;
12694 if (conf->mfcr2.call_files) {
12695 openr2_chan_enable_call_files(tmp->r2chan);
12696 }
12697 openr2_chan_set_client_data(tmp->r2chan, tmp);
12698 /* cast seems to be needed to get rid of the annoying warning regarding format attribute */
12699 openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log);
12700 openr2_chan_set_log_level(tmp->r2chan, conf->mfcr2.loglevel);
12701 tmp->mfcr2_category = conf->mfcr2.category;
12702 tmp->mfcr2_charge_calls = conf->mfcr2.charge_calls;
12703 tmp->mfcr2_allow_collect_calls = conf->mfcr2.allow_collect_calls;
12704 tmp->mfcr2_forced_release = conf->mfcr2.forced_release;
12705 tmp->mfcr2_accept_on_offer = conf->mfcr2.accept_on_offer;
12706 tmp->mfcr2call = 0;
12707 tmp->mfcr2_dnis_index = 0;
12708 tmp->mfcr2_ani_index = 0;
12709 }
12710#endif
12711#ifdef HAVE_PRI
12712 if (dahdi_sig_pri_lib_handles(chan_sig)) {
12713 int offset;
12714 int matchesdchan;
12715 int x,y;
12716 int myswitchtype = 0;
12717
12718 offset = 0;
12719 if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &offset)) {
12720 ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
12722 return NULL;
12723 }
12724 if (span >= NUM_SPANS) {
12725 ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
12727 return NULL;
12728 } else {
12729 si.spanno = 0;
12730 if (ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SPANSTAT,&si) == -1) {
12731 ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
12733 return NULL;
12734 }
12735 /* Store the logical span first based upon the real span */
12736 tmp->logicalspan = pris[span].prilogicalspan;
12737 pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
12738 if (span < 0) {
12739 ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
12741 return NULL;
12742 }
12743 myswitchtype = conf->pri.pri.switchtype;
12744 /* Make sure this isn't a d-channel */
12745 matchesdchan=0;
12746 for (x = 0; x < NUM_SPANS; x++) {
12747 for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) {
12748 if (pris[x].dchannels[y] == tmp->channel) {
12749 matchesdchan = 1;
12750 break;
12751 }
12752 }
12753 }
12754 if (!matchesdchan) {
12755 if (pris[span].pri.nodetype && (pris[span].pri.nodetype != conf->pri.pri.nodetype)) {
12756 ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].pri.nodetype));
12758 return NULL;
12759 }
12760 if (pris[span].pri.switchtype && (pris[span].pri.switchtype != myswitchtype)) {
12761 ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].pri.switchtype));
12763 return NULL;
12764 }
12765 if ((pris[span].pri.dialplan) && (pris[span].pri.dialplan != conf->pri.pri.dialplan)) {
12766 ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, pris[span].pri.dialplan == -1 ? "Dynamically set dialplan in ISDN" : pri_plan2str(pris[span].pri.dialplan));
12768 return NULL;
12769 }
12770 if (!ast_strlen_zero(pris[span].pri.idledial) && strcmp(pris[span].pri.idledial, conf->pri.pri.idledial)) {
12771 ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.pri.idledial);
12773 return NULL;
12774 }
12775 if (!ast_strlen_zero(pris[span].pri.idleext) && strcmp(pris[span].pri.idleext, conf->pri.pri.idleext)) {
12776 ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.pri.idleext);
12778 return NULL;
12779 }
12780 if (pris[span].pri.minunused && (pris[span].pri.minunused != conf->pri.pri.minunused)) {
12781 ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.pri.minunused);
12783 return NULL;
12784 }
12785 if (pris[span].pri.minidle && (pris[span].pri.minidle != conf->pri.pri.minidle)) {
12786 ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.pri.minidle);
12788 return NULL;
12789 }
12790 if (pris[span].pri.numchans >= ARRAY_LEN(pris[span].pri.pvts)) {
12791 ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
12792 pris[span].pri.trunkgroup);
12794 return NULL;
12795 }
12796
12797 pri_chan = sig_pri_chan_new(tmp, &pris[span].pri, tmp->logicalspan, p.chanpos, pris[span].mastertrunkgroup);
12798 if (!pri_chan) {
12800 return NULL;
12801 }
12802 tmp->sig_pvt = pri_chan;
12803 tmp->pri = &pris[span].pri;
12804
12805 tmp->priexclusive = conf->chan.priexclusive;
12806
12807 if (!tmp->pri->cc_params) {
12808 tmp->pri->cc_params = ast_cc_config_params_init();
12809 if (!tmp->pri->cc_params) {
12811 return NULL;
12812 }
12813 }
12814 ast_cc_copy_config_params(tmp->pri->cc_params,
12815 conf->chan.cc_params);
12816
12817 pris[span].pri.sig = chan_sig;
12818 pris[span].pri.nodetype = conf->pri.pri.nodetype;
12819 pris[span].pri.switchtype = myswitchtype;
12820 pris[span].pri.nsf = conf->pri.pri.nsf;
12821 pris[span].pri.dialplan = conf->pri.pri.dialplan;
12822 pris[span].pri.localdialplan = conf->pri.pri.localdialplan;
12823 pris[span].pri.cpndialplan = conf->pri.pri.cpndialplan;
12824 pris[span].pri.pvts[pris[span].pri.numchans++] = tmp->sig_pvt;
12825 pris[span].pri.minunused = conf->pri.pri.minunused;
12826 pris[span].pri.minidle = conf->pri.pri.minidle;
12827 pris[span].pri.overlapdial = conf->pri.pri.overlapdial;
12828 pris[span].pri.qsigchannelmapping = conf->pri.pri.qsigchannelmapping;
12829 pris[span].pri.discardremoteholdretrieval = conf->pri.pri.discardremoteholdretrieval;
12830#if defined(HAVE_PRI_SERVICE_MESSAGES)
12831 pris[span].pri.enable_service_message_support = conf->pri.pri.enable_service_message_support;
12832#endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
12833#ifdef HAVE_PRI_INBANDDISCONNECT
12834 pris[span].pri.inbanddisconnect = conf->pri.pri.inbanddisconnect;
12835#endif
12836#if defined(HAVE_PRI_CALL_HOLD)
12837 pris[span].pri.hold_disconnect_transfer =
12838 conf->pri.pri.hold_disconnect_transfer;
12839#endif /* defined(HAVE_PRI_CALL_HOLD) */
12840#if defined(HAVE_PRI_CCSS)
12841 pris[span].pri.cc_ptmp_recall_mode =
12842 conf->pri.pri.cc_ptmp_recall_mode;
12843 pris[span].pri.cc_qsig_signaling_link_req =
12844 conf->pri.pri.cc_qsig_signaling_link_req;
12845 pris[span].pri.cc_qsig_signaling_link_rsp =
12846 conf->pri.pri.cc_qsig_signaling_link_rsp;
12847#endif /* defined(HAVE_PRI_CCSS) */
12848#if defined(HAVE_PRI_CALL_WAITING)
12849 pris[span].pri.max_call_waiting_calls =
12850 conf->pri.pri.max_call_waiting_calls;
12851 pris[span].pri.allow_call_waiting_calls =
12852 conf->pri.pri.allow_call_waiting_calls;
12853#endif /* defined(HAVE_PRI_CALL_WAITING) */
12854 pris[span].pri.transfer = conf->chan.transfer;
12855 pris[span].pri.facilityenable = conf->pri.pri.facilityenable;
12856#if defined(HAVE_PRI_L2_PERSISTENCE)
12857 pris[span].pri.l2_persistence = conf->pri.pri.l2_persistence;
12858#endif /* defined(HAVE_PRI_L2_PERSISTENCE) */
12859 pris[span].pri.colp_send = conf->pri.pri.colp_send;
12860#if defined(HAVE_PRI_AOC_EVENTS)
12861 pris[span].pri.aoc_passthrough_flag = conf->pri.pri.aoc_passthrough_flag;
12862 pris[span].pri.aoce_delayhangup = conf->pri.pri.aoce_delayhangup;
12863#endif /* defined(HAVE_PRI_AOC_EVENTS) */
12864 if (chan_sig == SIG_BRI_PTMP) {
12865 pris[span].pri.layer1_ignored = conf->pri.pri.layer1_ignored;
12866 } else {
12867 /* Option does not apply to this line type. */
12868 pris[span].pri.layer1_ignored = 0;
12869 }
12870 pris[span].pri.append_msn_to_user_tag = conf->pri.pri.append_msn_to_user_tag;
12871 pris[span].pri.inband_on_setup_ack = conf->pri.pri.inband_on_setup_ack;
12872 pris[span].pri.inband_on_proceeding = conf->pri.pri.inband_on_proceeding;
12873 ast_copy_string(pris[span].pri.initial_user_tag, conf->chan.cid_tag, sizeof(pris[span].pri.initial_user_tag));
12874 ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list));
12875#if defined(HAVE_PRI_MWI)
12876 ast_copy_string(pris[span].pri.mwi_mailboxes,
12877 conf->pri.pri.mwi_mailboxes,
12878 sizeof(pris[span].pri.mwi_mailboxes));
12879 ast_copy_string(pris[span].pri.mwi_vm_boxes,
12880 conf->pri.pri.mwi_vm_boxes,
12881 sizeof(pris[span].pri.mwi_vm_boxes));
12882 ast_copy_string(pris[span].pri.mwi_vm_numbers,
12883 conf->pri.pri.mwi_vm_numbers,
12884 sizeof(pris[span].pri.mwi_vm_numbers));
12885#endif /* defined(HAVE_PRI_MWI) */
12886 ast_copy_string(pris[span].pri.idledial, conf->pri.pri.idledial, sizeof(pris[span].pri.idledial));
12887 ast_copy_string(pris[span].pri.idleext, conf->pri.pri.idleext, sizeof(pris[span].pri.idleext));
12888 ast_copy_string(pris[span].pri.internationalprefix, conf->pri.pri.internationalprefix, sizeof(pris[span].pri.internationalprefix));
12889 ast_copy_string(pris[span].pri.nationalprefix, conf->pri.pri.nationalprefix, sizeof(pris[span].pri.nationalprefix));
12890 ast_copy_string(pris[span].pri.localprefix, conf->pri.pri.localprefix, sizeof(pris[span].pri.localprefix));
12891 ast_copy_string(pris[span].pri.privateprefix, conf->pri.pri.privateprefix, sizeof(pris[span].pri.privateprefix));
12892 ast_copy_string(pris[span].pri.unknownprefix, conf->pri.pri.unknownprefix, sizeof(pris[span].pri.unknownprefix));
12893 pris[span].pri.moh_signaling = conf->pri.pri.moh_signaling;
12894 pris[span].pri.resetinterval = conf->pri.pri.resetinterval;
12895#if defined(HAVE_PRI_DISPLAY_TEXT)
12896 pris[span].pri.display_flags_send = conf->pri.pri.display_flags_send;
12897 pris[span].pri.display_flags_receive = conf->pri.pri.display_flags_receive;
12898#endif /* defined(HAVE_PRI_DISPLAY_TEXT) */
12899#if defined(HAVE_PRI_MCID)
12900 pris[span].pri.mcid_send = conf->pri.pri.mcid_send;
12901#endif /* defined(HAVE_PRI_MCID) */
12902 pris[span].pri.force_restart_unavailable_chans = conf->pri.pri.force_restart_unavailable_chans;
12903#if defined(HAVE_PRI_DATETIME_SEND)
12904 pris[span].pri.datetime_send = conf->pri.pri.datetime_send;
12905#endif /* defined(HAVE_PRI_DATETIME_SEND) */
12906
12907 for (x = 0; x < PRI_MAX_TIMERS; x++) {
12908 pris[span].pri.pritimers[x] = conf->pri.pri.pritimers[x];
12909 }
12910
12911#if defined(HAVE_PRI_CALL_WAITING)
12912 /* Channel initial config parameters. */
12913 pris[span].pri.ch_cfg.stripmsd = conf->chan.stripmsd;
12914 pris[span].pri.ch_cfg.hidecallerid = conf->chan.hidecallerid;
12915 pris[span].pri.ch_cfg.hidecalleridname = conf->chan.hidecalleridname;
12916 pris[span].pri.ch_cfg.immediate = conf->chan.immediate;
12917 pris[span].pri.ch_cfg.priexclusive = conf->chan.priexclusive;
12918 pris[span].pri.ch_cfg.priindication_oob = conf->chan.priindication_oob;
12919 pris[span].pri.ch_cfg.use_callerid = conf->chan.use_callerid;
12920 pris[span].pri.ch_cfg.use_callingpres = conf->chan.use_callingpres;
12921 ast_copy_string(pris[span].pri.ch_cfg.context, conf->chan.context, sizeof(pris[span].pri.ch_cfg.context));
12922 ast_copy_string(pris[span].pri.ch_cfg.mohinterpret, conf->chan.mohinterpret, sizeof(pris[span].pri.ch_cfg.mohinterpret));
12923#endif /* defined(HAVE_PRI_CALL_WAITING) */
12924 } else {
12925 ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", p.chanpos);
12927 return NULL;
12928 }
12929 }
12930 }
12931#endif
12932 } else {
12933 /* already exists in interface list */
12934 ast_log(LOG_WARNING, "Attempt to configure channel %d with signaling %s ignored because it is already configured to be %s.\n", tmp->channel, dahdi_sig2str(chan_sig), dahdi_sig2str(tmp->sig));
12935 chan_sig = tmp->sig;
12936 if (tmp->subs[SUB_REAL].dfd > -1) {
12937 memset(&p, 0, sizeof(p));
12938 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
12939 }
12940 }
12941 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
12942 switch (chan_sig) {
12943 case SIG_FXSKS:
12944 case SIG_FXSLS:
12945 case SIG_EM:
12946 case SIG_EM_E1:
12947 case SIG_EMWINK:
12948 case SIG_FEATD:
12949 case SIG_FEATDMF:
12950 case SIG_FEATDMF_TA:
12951 case SIG_FEATB:
12952 case SIG_E911:
12953 case SIG_SF:
12954 case SIG_SFWINK:
12955 case SIG_FGC_CAMA:
12956 case SIG_FGC_CAMAMF:
12957 case SIG_SF_FEATD:
12958 case SIG_SF_FEATDMF:
12959 case SIG_SF_FEATB:
12960 p.starttime = 250;
12961 break;
12962 }
12963
12964 if (tmp->radio) {
12965 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
12966 p.channo = channel;
12967 p.rxwinktime = 1;
12968 p.rxflashtime = 1;
12969 p.starttime = 1;
12970 p.debouncetime = 5;
12971 } else {
12972 p.channo = channel;
12973 /* Override timing settings based on config file */
12974 if (conf->timing.prewinktime >= 0)
12975 p.prewinktime = conf->timing.prewinktime;
12976 if (conf->timing.preflashtime >= 0)
12977 p.preflashtime = conf->timing.preflashtime;
12978 if (conf->timing.winktime >= 0)
12979 p.winktime = conf->timing.winktime;
12980 if (conf->timing.flashtime >= 0)
12981 p.flashtime = conf->timing.flashtime;
12982 if (conf->timing.starttime >= 0)
12983 p.starttime = conf->timing.starttime;
12984 if (conf->timing.rxwinktime >= 0)
12985 p.rxwinktime = conf->timing.rxwinktime;
12986 if (conf->timing.rxflashtime >= 0)
12987 p.rxflashtime = conf->timing.rxflashtime;
12988 if (conf->timing.debouncetime >= 0)
12989 p.debouncetime = conf->timing.debouncetime;
12990 }
12991
12992 /* don't set parms on a pseudo-channel */
12993 if (tmp->subs[SUB_REAL].dfd >= 0)
12994 {
12995 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_PARAMS, &p);
12996 if (res < 0) {
12997 ast_log(LOG_ERROR, "Unable to set parameters: %s\n", strerror(errno));
12999 return NULL;
13000 }
13001 }
13002#if 1
13003 if (!here && (tmp->subs[SUB_REAL].dfd > -1)) {
13004 memset(&bi, 0, sizeof(bi));
13005 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
13006 if (!res) {
13007 bi.txbufpolicy = conf->chan.buf_policy;
13008 bi.rxbufpolicy = conf->chan.buf_policy;
13009 bi.numbufs = conf->chan.buf_no;
13010 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
13011 if (res < 0) {
13012 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", channel, strerror(errno));
13013 }
13014 } else {
13015 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", channel, strerror(errno));
13016 }
13017 tmp->buf_policy = conf->chan.buf_policy;
13018 tmp->buf_no = conf->chan.buf_no;
13019 tmp->usefaxbuffers = conf->chan.usefaxbuffers;
13020 tmp->faxbuf_policy = conf->chan.faxbuf_policy;
13021 tmp->faxbuf_no = conf->chan.faxbuf_no;
13022 /* This is not as gnarly as it may first appear. If the ioctl above failed, we'd be setting
13023 * tmp->bufsize to zero which would cause subsequent faxbuffer-related ioctl calls to fail.
13024 * The reason the ioctl call above failed should to be determined before worrying about the
13025 * faxbuffer-related ioctl calls */
13026 tmp->bufsize = bi.bufsize;
13027 }
13028#endif
13029 tmp->immediate = conf->chan.immediate;
13030 tmp->immediatering = conf->chan.immediatering;
13031 tmp->transfertobusy = conf->chan.transfertobusy;
13032 tmp->dialmode = conf->chan.dialmode;
13033 if (chan_sig & __DAHDI_SIG_FXS) {
13034 tmp->mwimonitor_fsk = conf->chan.mwimonitor_fsk;
13035 tmp->mwimonitor_neon = conf->chan.mwimonitor_neon;
13036 tmp->mwimonitor_rpas = conf->chan.mwimonitor_rpas;
13037 }
13038 tmp->ringt_base = ringt_base;
13039 tmp->firstradio = 0;
13040 if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS))
13041 tmp->permcallwaiting = conf->chan.callwaiting;
13042 else
13043 tmp->permcallwaiting = 0;
13044 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */
13045 tmp->destroy = 0;
13046 tmp->drings = conf->chan.drings;
13047
13048 /* 10 is a nice default. */
13049 if (tmp->drings.ringnum[0].range == 0)
13050 tmp->drings.ringnum[0].range = 10;
13051 if (tmp->drings.ringnum[1].range == 0)
13052 tmp->drings.ringnum[1].range = 10;
13053 if (tmp->drings.ringnum[2].range == 0)
13054 tmp->drings.ringnum[2].range = 10;
13055
13056 tmp->usedistinctiveringdetection = usedistinctiveringdetection;
13057 tmp->callwaitingcallerid = conf->chan.callwaitingcallerid;
13058 tmp->threewaycalling = conf->chan.threewaycalling;
13059 tmp->threewaysilenthold = conf->chan.threewaysilenthold;
13060 tmp->calledsubscriberheld = conf->chan.calledsubscriberheld; /* Not used in chan_dahdi.c, just analog pvt, but must exist on the DAHDI pvt anyways */
13061 tmp->adsi = conf->chan.adsi;
13062 tmp->use_smdi = conf->chan.use_smdi;
13063 tmp->permhidecallerid = conf->chan.hidecallerid;
13064 tmp->hidecalleridname = conf->chan.hidecalleridname;
13065 tmp->callreturn = conf->chan.callreturn;
13066 tmp->echocancel = conf->chan.echocancel;
13067 tmp->echotraining = conf->chan.echotraining;
13068 tmp->pulse = conf->chan.pulse;
13069 if (tmp->echocancel.head.tap_length) {
13070 tmp->echocanbridged = conf->chan.echocanbridged;
13071 } else {
13072 if (conf->chan.echocanbridged)
13073 ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
13074 tmp->echocanbridged = 0;
13075 }
13076 tmp->busydetect = conf->chan.busydetect;
13077 tmp->busycount = conf->chan.busycount;
13078 tmp->busy_cadence = conf->chan.busy_cadence;
13079 tmp->callprogress = conf->chan.callprogress;
13080 tmp->waitfordialtone = conf->chan.waitfordialtone;
13081 tmp->dialtone_detect = conf->chan.dialtone_detect;
13082 tmp->faxdetect_timeout = conf->chan.faxdetect_timeout;
13083 tmp->firstdigit_timeout = conf->chan.firstdigit_timeout;
13084 tmp->interdigit_timeout = conf->chan.interdigit_timeout;
13085 tmp->matchdigit_timeout = conf->chan.matchdigit_timeout;
13086 tmp->cancallforward = conf->chan.cancallforward;
13087 tmp->dtmfrelax = conf->chan.dtmfrelax;
13088 tmp->callwaiting = tmp->permcallwaiting;
13089 tmp->hidecallerid = tmp->permhidecallerid;
13090 tmp->channel = channel;
13091 tmp->stripmsd = conf->chan.stripmsd;
13092 tmp->use_callerid = conf->chan.use_callerid;
13093 tmp->cid_signalling = conf->chan.cid_signalling;
13094 tmp->cid_start = conf->chan.cid_start;
13095 tmp->dahditrcallerid = conf->chan.dahditrcallerid;
13096 tmp->restrictcid = conf->chan.restrictcid;
13097 tmp->use_callingpres = conf->chan.use_callingpres;
13098 if (tmp->usedistinctiveringdetection) {
13099 if (!tmp->use_callerid) {
13100 ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
13101 tmp->use_callerid = 1;
13102 }
13103 }
13104
13105 if (tmp->cid_signalling == CID_SIG_SMDI) {
13106 if (!tmp->use_smdi) {
13107 ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
13108 tmp->use_smdi = 1;
13109 }
13110 }
13111 if (tmp->use_smdi) {
13112 tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port);
13113 if (!(tmp->smdi_iface)) {
13114 ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
13115 tmp->use_smdi = 0;
13116 }
13117 }
13118
13119 ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode));
13120 tmp->amaflags = conf->chan.amaflags;
13121 if (!here) {
13122 tmp->confno = -1;
13123 tmp->propconfno = -1;
13124 }
13125 tmp->canpark = conf->chan.canpark;
13126 tmp->transfer = conf->chan.transfer;
13127 ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext));
13128 ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language));
13129 ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret));
13130 ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest));
13131 ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context));
13132 ast_copy_string(tmp->description, conf->chan.description, sizeof(tmp->description));
13133 ast_copy_string(tmp->parkinglot, conf->chan.parkinglot, sizeof(tmp->parkinglot));
13134 tmp->cid_ton = 0;
13135 if (dahdi_analog_lib_handles(tmp->sig, tmp->radio, tmp->oprmode)) {
13136 ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num));
13137 ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name));
13138 } else {
13139 tmp->cid_num[0] = '\0';
13140 tmp->cid_name[0] = '\0';
13141 }
13142#if defined(HAVE_PRI)
13143 if (dahdi_sig_pri_lib_handles(tmp->sig)) {
13144 tmp->cid_tag[0] = '\0';
13145 } else
13146#endif /* defined(HAVE_PRI) */
13147 {
13148 ast_copy_string(tmp->cid_tag, conf->chan.cid_tag, sizeof(tmp->cid_tag));
13149 }
13150 tmp->cid_subaddr[0] = '\0';
13151 ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox));
13152 if (channel != CHAN_PSEUDO && !ast_strlen_zero(tmp->mailbox)) {
13153 /* This module does not handle MWI in an event-based manner. However, it
13154 * subscribes to MWI for each mailbox that is configured so that the core
13155 * knows that we care about it. Then, chan_dahdi will get the MWI from the
13156 * event cache instead of checking the mailbox directly. */
13157 tmp->mwi_event_sub = ast_mwi_subscribe_pool(tmp->mailbox, stasis_subscription_cb_noop, NULL);
13158 }
13159#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
13160 tmp->mwisend_setting = conf->chan.mwisend_setting;
13161 tmp->mwisend_fsk = conf->chan.mwisend_fsk;
13162 tmp->mwisend_rpas = conf->chan.mwisend_rpas;
13163#endif
13164
13165 tmp->group = conf->chan.group;
13166 tmp->callgroup = conf->chan.callgroup;
13167 tmp->pickupgroup= conf->chan.pickupgroup;
13168 ast_unref_namedgroups(tmp->named_callgroups);
13169 tmp->named_callgroups = ast_ref_namedgroups(conf->chan.named_callgroups);
13170 ast_unref_namedgroups(tmp->named_pickupgroups);
13171 tmp->named_pickupgroups = ast_ref_namedgroups(conf->chan.named_pickupgroups);
13172 if (conf->chan.vars) {
13173 struct ast_variable *v, *tmpvar;
13174 for (v = conf->chan.vars ; v ; v = v->next) {
13175 if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
13176 if (ast_variable_list_replace(&tmp->vars, tmpvar)) {
13177 tmpvar->next = tmp->vars;
13178 tmp->vars = tmpvar;
13179 }
13180 }
13181 }
13182 }
13183 tmp->hwrxgain_enabled = conf->chan.hwrxgain_enabled;
13184 tmp->hwtxgain_enabled = conf->chan.hwtxgain_enabled;
13185 tmp->hwrxgain = conf->chan.hwrxgain;
13186 tmp->hwtxgain = conf->chan.hwtxgain;
13187 tmp->cid_rxgain = conf->chan.cid_rxgain;
13188 tmp->rxgain = conf->chan.rxgain;
13189 tmp->txgain = conf->chan.txgain;
13190 tmp->txdrc = conf->chan.txdrc;
13191 tmp->rxdrc = conf->chan.rxdrc;
13192 tmp->tonezone = conf->chan.tonezone;
13193 if (tmp->subs[SUB_REAL].dfd > -1) {
13194 if (tmp->hwrxgain_enabled) {
13195 tmp->hwrxgain_enabled = !set_hwgain(tmp->subs[SUB_REAL].dfd, tmp->hwrxgain, 0);
13196 }
13197 if (tmp->hwtxgain_enabled) {
13198 tmp->hwtxgain_enabled = !set_hwgain(tmp->subs[SUB_REAL].dfd, tmp->hwtxgain, 1);
13199 }
13200 set_actual_gain(tmp->subs[SUB_REAL].dfd, tmp->rxgain, tmp->txgain, tmp->rxdrc, tmp->txdrc, tmp->law);
13201 if (tmp->dsp)
13202 ast_dsp_set_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
13204 if (!here) {
13205 switch (chan_sig) {
13207 case SIG_SS7:
13208 case SIG_MFCR2:
13209 break;
13210 default:
13211 /* Hang it up to be sure it's good */
13212 dahdi_set_hook(tmp->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
13213 break;
13214 }
13215 }
13216 ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SETTONEZONE,&tmp->tonezone);
13217 if ((res = get_alarms(tmp)) != DAHDI_ALARM_NONE) {
13218 /* the dchannel is down so put the channel in alarm */
13219 switch (tmp->sig) {
13220#ifdef HAVE_PRI
13222 sig_pri_set_alarm(tmp->sig_pvt, 1);
13223 break;
13224#endif
13225#if defined(HAVE_SS7)
13226 case SIG_SS7:
13227 sig_ss7_set_alarm(tmp->sig_pvt, 1);
13228 break;
13229#endif /* defined(HAVE_SS7) */
13230 default:
13231 /* The only sig submodule left should be sig_analog. */
13232 analog_p = tmp->sig_pvt;
13233 if (analog_p) {
13234 analog_p->inalarm = 1;
13235 }
13236 tmp->inalarm = 1;
13237 break;
13238 }
13239 handle_alarms(tmp, res);
13240 }
13241 }
13242
13243 tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay;
13244 tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch;
13245 tmp->ani_info_digits = conf->chan.ani_info_digits;
13246 tmp->ani_wink_time = conf->chan.ani_wink_time;
13247 tmp->ani_timeout = conf->chan.ani_timeout;
13248 tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
13249 tmp->reoriginate = conf->chan.reoriginate;
13250 tmp->sendcalleridafter = conf->chan.sendcalleridafter;
13251 ast_cc_copy_config_params(tmp->cc_params, conf->chan.cc_params);
13252
13253 if (!here) {
13254 tmp->locallyblocked = 0;
13255 tmp->remotelyblocked = 0;
13256 switch (tmp->sig) {
13257#if defined(HAVE_PRI)
13259 tmp->inservice = 1;/* Inservice until actually implemented. */
13260#if defined(HAVE_PRI_SERVICE_MESSAGES)
13261 ((struct sig_pri_chan *) tmp->sig_pvt)->service_status = 0;
13262 if (chan_sig == SIG_PRI) {
13263 char db_chan_name[20];
13264 char db_answer[5];
13265
13266 /*
13267 * Initialize the active out-of-service status
13268 * and delete any record if the feature is not enabled.
13269 */
13270 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, tmp->span, tmp->channel);
13271 if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) {
13272 unsigned *why;
13273
13274 why = &((struct sig_pri_chan *) tmp->sig_pvt)->service_status;
13275 if (tmp->pri->enable_service_message_support) {
13276 char state;
13277
13278 sscanf(db_answer, "%1c:%30u", &state, why);
13279
13280 /* Ensure that only the implemented bits could be set.*/
13281 *why &= (SRVST_NEAREND | SRVST_FAREND);
13282 }
13283 if (!*why) {
13284 ast_db_del(db_chan_name, SRVST_DBKEY);
13285 }
13286 }
13287 }
13288#endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
13289 break;
13290#endif /* defined(HAVE_PRI) */
13291#if defined(HAVE_SS7)
13292 case SIG_SS7:
13293 tmp->inservice = 0;
13294 if (tmp->ss7->flags & LINKSET_FLAG_INITIALHWBLO) {
13295 tmp->remotelyblocked |= SS7_BLOCKED_HARDWARE;
13296 }
13297 break;
13298#endif /* defined(HAVE_SS7) */
13299 default:
13300 /* We default to in service on protocols that don't have a reset */
13301 tmp->inservice = 1;
13302 break;
13303 }
13304 }
13305
13306 switch (tmp->sig) {
13307#if defined(HAVE_PRI)
13309 if (pri_chan) {
13310 pri_chan->channel = tmp->channel;
13311 pri_chan->hidecallerid = tmp->hidecallerid;
13312 pri_chan->hidecalleridname = tmp->hidecalleridname;
13313 pri_chan->immediate = tmp->immediate;
13314 pri_chan->inalarm = tmp->inalarm;
13315 pri_chan->priexclusive = tmp->priexclusive;
13316 pri_chan->priindication_oob = tmp->priindication_oob;
13317 pri_chan->use_callerid = tmp->use_callerid;
13318 pri_chan->use_callingpres = tmp->use_callingpres;
13319 ast_copy_string(pri_chan->context, tmp->context,
13320 sizeof(pri_chan->context));
13321 ast_copy_string(pri_chan->mohinterpret, tmp->mohinterpret,
13322 sizeof(pri_chan->mohinterpret));
13323 pri_chan->stripmsd = tmp->stripmsd;
13324 }
13325 break;
13326#endif /* defined(HAVE_PRI) */
13327#if defined(HAVE_SS7)
13328 case SIG_SS7:
13329 if (ss7_chan) {
13330 ss7_chan->inalarm = tmp->inalarm;
13331 ss7_chan->inservice = tmp->inservice;
13332
13333 ss7_chan->stripmsd = tmp->stripmsd;
13334 ss7_chan->hidecallerid = tmp->hidecallerid;
13335 ss7_chan->use_callerid = tmp->use_callerid;
13336 ss7_chan->use_callingpres = tmp->use_callingpres;
13337 ss7_chan->immediate = tmp->immediate;
13338 ss7_chan->locallyblocked = tmp->locallyblocked;
13339 ss7_chan->remotelyblocked = tmp->remotelyblocked;
13340 ast_copy_string(ss7_chan->context, tmp->context,
13341 sizeof(ss7_chan->context));
13342 ast_copy_string(ss7_chan->mohinterpret, tmp->mohinterpret,
13343 sizeof(ss7_chan->mohinterpret));
13344 }
13345 break;
13346#endif /* defined(HAVE_SS7) */
13347 default:
13348 /* The only sig submodule left should be sig_analog. */
13349 analog_p = tmp->sig_pvt;
13350 if (analog_p) {
13351 analog_p->channel = tmp->channel;
13352 analog_p->polarityonanswerdelay = conf->chan.polarityonanswerdelay;
13353 analog_p->answeronpolarityswitch = conf->chan.answeronpolarityswitch;
13354 analog_p->ani_info_digits = conf->chan.ani_info_digits;
13355 analog_p->ani_timeout = conf->chan.ani_timeout;
13356 analog_p->ani_wink_time = conf->chan.ani_wink_time;
13357 analog_p->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
13358 analog_p->permcallwaiting = conf->chan.callwaiting; /* permcallwaiting possibly modified in analog_config_complete */
13359 analog_p->calledsubscriberheld = conf->chan.calledsubscriberheld; /* Only actually used in analog pvt, not DAHDI pvt */
13360 analog_p->callreturn = conf->chan.callreturn;
13361 analog_p->cancallforward = conf->chan.cancallforward;
13362 analog_p->canpark = conf->chan.canpark;
13363 analog_p->dahditrcallerid = conf->chan.dahditrcallerid;
13364 analog_p->immediate = conf->chan.immediate;
13365 analog_p->immediatering = conf->chan.immediatering;
13366 analog_p->permhidecallerid = conf->chan.hidecallerid; /* hidecallerid is the config setting, not permhidecallerid (~permcallwaiting above) */
13367 /* It's not necessary to set analog_p->hidecallerid here, sig_analog will set hidecallerid=permhidecaller before each call */
13368 analog_p->pulse = conf->chan.pulse;
13369 analog_p->threewaycalling = conf->chan.threewaycalling;
13370 analog_p->transfer = conf->chan.transfer;
13371 analog_p->transfertobusy = conf->chan.transfertobusy;
13372 analog_p->dialmode = conf->chan.dialmode;
13373 analog_p->use_callerid = tmp->use_callerid;
13374 analog_p->usedistinctiveringdetection = tmp->usedistinctiveringdetection;
13375 analog_p->use_smdi = tmp->use_smdi;
13376 analog_p->smdi_iface = tmp->smdi_iface;
13377 analog_p->outsigmod = ANALOG_SIG_NONE;
13378 analog_p->echotraining = conf->chan.echotraining;
13379 analog_p->cid_signalling = conf->chan.cid_signalling;
13380 analog_p->stripmsd = conf->chan.stripmsd;
13381 switch (conf->chan.cid_start) {
13382 case CID_START_POLARITY:
13384 break;
13387 break;
13390 break;
13391 default:
13392 analog_p->cid_start = ANALOG_CID_START_RING;
13393 break;
13394 }
13395 analog_p->callwaitingcallerid = conf->chan.callwaitingcallerid;
13396 analog_p->ringt = conf->chan.ringt;
13397 analog_p->ringt_base = ringt_base;
13398 analog_p->onhooktime = time(NULL);
13399 if (chan_sig & __DAHDI_SIG_FXO) {
13400 memset(&p, 0, sizeof(p));
13401 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
13402 if (!res) {
13403 analog_p->fxsoffhookstate = p.rxisoffhook;
13404 }
13405#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
13406 res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting);
13407#endif
13408 }
13409 analog_p->msgstate = -1;
13410
13411 ast_copy_string(analog_p->mohsuggest, conf->chan.mohsuggest, sizeof(analog_p->mohsuggest));
13412 ast_copy_string(analog_p->cid_num, conf->chan.cid_num, sizeof(analog_p->cid_num));
13413 ast_copy_string(analog_p->cid_name, conf->chan.cid_name, sizeof(analog_p->cid_name));
13414
13415 analog_config_complete(analog_p);
13416 }
13417 break;
13418 }
13419#if defined(HAVE_PRI)
13420 if (tmp->channel == CHAN_PSEUDO) {
13421 /*
13422 * Save off pseudo channel buffer policy values for dynamic creation of
13423 * no B channel interfaces.
13424 */
13425 dahdi_pseudo_parms.buf_no = tmp->buf_no;
13426 dahdi_pseudo_parms.buf_policy = tmp->buf_policy;
13427 dahdi_pseudo_parms.faxbuf_no = tmp->faxbuf_no;
13428 dahdi_pseudo_parms.faxbuf_policy = tmp->faxbuf_policy;
13429 }
13430#endif /* defined(HAVE_PRI) */
13431 }
13432 if (tmp && !here) {
13433 /* Add the new channel interface to the sorted channel interface list. */
13435 }
13436 return tmp;
13437}
static char * dahdi_sig2str(int sig)
Definition: chan_dahdi.c:4651
static int sigtype_to_signalling(int sigtype)
Definition: chan_dahdi.c:12474
static int ringt_base
Configured ring timeout base.
Definition: chan_dahdi.c:811
static enum analog_sigtype dahdisig_to_analogsig(int sig)
Definition: chan_dahdi.c:1182
static int usedistinctiveringdetection
Definition: chan_dahdi.c:728
struct ast_namedgroups * ast_ref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7738
#define ast_variable_new(name, value, filename)
int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement)
Replace a variable in the given list with a new value.
Definition: main/config.c:667
struct ast_mwi_subscriber * ast_mwi_subscribe_pool(const char *mailbox, stasis_subscription_cb callback, void *data)
Add an MWI state subscriber, and stasis subscription to the mailbox.
Definition: mwi.c:235
int analog_config_complete(struct analog_pvt *p)
Definition: sig_analog.c:4109
struct analog_pvt * analog_new(enum analog_sigtype signallingtype, void *private_data)
Definition: sig_analog.c:4076
@ ANALOG_SIG_NONE
Definition: sig_analog.h:46
@ ANALOG_CID_START_RING
Definition: sig_analog.h:129
@ ANALOG_CID_START_DTMF_NOALERT
Definition: sig_analog.h:130
@ ANALOG_CID_START_POLARITY
Definition: sig_analog.h:127
@ ANALOG_CID_START_POLARITY_IN
Definition: sig_analog.h:128
struct sig_pri_chan * sig_pri_chan_new(void *pvt_data, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup)
void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm)
struct sig_ss7_chan * sig_ss7_chan_new(void *pvt_data, struct sig_ss7_linkset *ss7)
#define LINKSET_FLAG_INITIALHWBLO
Definition: sig_ss7.h:69
#define SS7_BLOCKED_HARDWARE
Definition: sig_ss7.h:75
struct ast_smdi_interface * ast_smdi_interface_find(const char *iface_name)
Find an SMDI interface with the specified name.
Definition: res_smdi.c:563
void stasis_subscription_cb_noop(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Stasis subscription callback function that does nothing.
Definition: stasis.c:809
unsigned int immediate
Definition: sig_analog.h:298
unsigned int immediatering
Definition: sig_analog.h:299
unsigned int permcallwaiting
Definition: sig_analog.h:300
unsigned int canpark
Definition: sig_analog.h:295
unsigned int dahditrcallerid
Definition: sig_analog.h:296
int polarityonanswerdelay
Definition: sig_analog.h:324
char cid_num[AST_MAX_EXTENSION]
Definition: sig_analog.h:328
unsigned int permhidecallerid
Definition: sig_analog.h:301
unsigned int callwaitingcallerid
Definition: sig_analog.h:309
unsigned int ani_wink_time
Definition: sig_analog.h:289
enum analog_sigtype outsigmod
Definition: sig_analog.h:320
unsigned int usedistinctiveringdetection
Definition: sig_analog.h:308
unsigned int answeronpolarityswitch
Definition: sig_analog.h:291
unsigned int threewaycalling
Definition: sig_analog.h:303
unsigned int pulse
Definition: sig_analog.h:302
int echotraining
Definition: sig_analog.h:322
unsigned int hanguponpolarityswitch
Definition: sig_analog.h:297
enum analog_cid_start cid_start
Definition: sig_analog.h:326
unsigned int callreturn
Definition: sig_analog.h:293
unsigned int use_smdi
TRUE if SMDI (Simplified Message Desk Interface) is enabled.
Definition: sig_analog.h:313
unsigned int ani_timeout
Definition: sig_analog.h:288
int ringt_base
Definition: sig_analog.h:376
unsigned int ani_info_digits
Definition: sig_analog.h:287
unsigned int cancallforward
Definition: sig_analog.h:294
int cid_signalling
Definition: sig_analog.h:323
unsigned int transfer
Definition: sig_analog.h:305
unsigned int transfertobusy
Definition: sig_analog.h:306
unsigned int inalarm
Definition: sig_analog.h:341
char cid_name[AST_MAX_EXTENSION]
Definition: sig_analog.h:329
int stripmsd
Definition: sig_analog.h:325
unsigned int calledsubscriberheld
Definition: sig_analog.h:292
char mohsuggest[MAX_MUSICCLASS]
Definition: sig_analog.h:327
unsigned int use_callerid
Definition: sig_analog.h:307
struct ast_smdi_interface * smdi_iface
The SMDI interface to get SMDI messages from.
Definition: sig_analog.h:315
unsigned int immediate
Definition: sig_pri.h:282
unsigned int use_callingpres
Definition: sig_pri.h:286
unsigned int priexclusive
Definition: sig_pri.h:283
unsigned int hidecallerid
Definition: sig_pri.h:280
unsigned int priindication_oob
Definition: sig_pri.h:284
unsigned int hidecalleridname
Definition: sig_pri.h:281
char context[AST_MAX_CONTEXT]
Definition: sig_pri.h:287
unsigned int inalarm
Definition: sig_pri.h:324
int stripmsd
Definition: sig_pri.h:289
unsigned int use_callerid
Definition: sig_pri.h:285
char mohinterpret[MAX_MUSICCLASS]
Definition: sig_pri.h:288
unsigned int immediate
Definition: sig_ss7.h:221
unsigned int locallyblocked
Bitmask for the channel being locally blocked.
Definition: sig_ss7.h:228
unsigned int dpc
Definition: sig_ss7.h:202
unsigned int use_callingpres
TRUE if we will use the calling presentation setting from the Asterisk channel for outgoing calls.
Definition: sig_ss7.h:220
unsigned int remotelyblocked
Bitmask for the channel being remotely blocked.
Definition: sig_ss7.h:235
unsigned int hidecallerid
TRUE if the outgoing caller ID is blocked/hidden.
Definition: sig_ss7.h:213
char context[AST_MAX_CONTEXT]
Definition: sig_ss7.h:237
unsigned int inalarm
TRUE if channel is associated with a link that is down.
Definition: sig_ss7.h:288
unsigned int inservice
TRUE if channel is in service.
Definition: sig_ss7.h:290
int channel
Definition: sig_ss7.h:200
int stripmsd
Number of most significant digits/characters to strip from the dialed number.
Definition: sig_ss7.h:209
unsigned int use_callerid
TRUE if caller ID is used on this channel.
Definition: sig_ss7.h:215
char mohinterpret[MAX_MUSICCLASS]
Definition: sig_ss7.h:238

References ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, ANALOG_CID_START_RING, analog_config_complete(), analog_new(), ANALOG_SIG_NONE, analog_pvt::ani_info_digits, analog_pvt::ani_timeout, analog_pvt::ani_wink_time, analog_pvt::answeronpolarityswitch, ARRAY_LEN, ast_calloc, ast_cc_config_params_init, ast_cc_copy_config_params(), ast_copy_string(), ast_db_del(), ast_db_get(), ast_dsp_set_digitmode(), ast_free, ast_log, ast_mutex_init, ast_mwi_subscribe_pool(), ast_ref_namedgroups(), ast_smdi_interface_find(), ast_strlen_zero(), ast_unref_namedgroups(), ast_variable_list_replace(), ast_variable_new, ast_variables_destroy(), analog_pvt::calledsubscriberheld, analog_pvt::callreturn, analog_pvt::callwaitingcallerid, analog_pvt::cancallforward, analog_pvt::canpark, CHAN_PSEUDO, analog_pvt::channel, sig_pri_chan::channel, sig_ss7_chan::channel, sig_ss7_chan::cic, analog_pvt::cid_name, analog_pvt::cid_num, CID_SIG_SMDI, analog_pvt::cid_signalling, analog_pvt::cid_start, CID_START_DTMF_NOALERT, CID_START_POLARITY, CID_START_POLARITY_IN, sig_pri_chan::context, sig_ss7_chan::context, dahdi_analog_lib_handles(), dahdi_conf_update(), dahdi_iflist_insert(), dahdi_open(), dahdi_set_hook(), dahdi_sig2str(), dahdi_sig_pri_lib_handles(), dahdisig_to_analogsig(), analog_pvt::dahditrcallerid, destroy_dahdi_pvt(), analog_pvt::dialmode, sig_pri_span::dialplan, sig_ss7_chan::dpc, DSP_DIGITMODE_DTMF, analog_pvt::echotraining, errno, ast_variable::file, analog_pvt::fxsoffhookstate, get_alarms(), handle_alarms(), analog_pvt::hanguponpolarityswitch, sig_pri_chan::hidecallerid, sig_ss7_chan::hidecallerid, sig_pri_chan::hidecalleridname, sig_pri_span::idledial, sig_pri_span::idleext, ifcount, iflist, analog_pvt::immediate, sig_pri_chan::immediate, sig_ss7_chan::immediate, analog_pvt::immediatering, analog_pvt::inalarm, sig_pri_chan::inalarm, sig_ss7_chan::inalarm, sig_ss7_chan::inservice, LINKSET_FLAG_INITIALHWBLO, sig_ss7_chan::locallyblocked, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sig_pri_span::minidle, sig_pri_span::minunused, sig_pri_chan::mohinterpret, sig_ss7_chan::mohinterpret, analog_pvt::mohsuggest, analog_pvt::msgstate, ast_variable::name, ast_variable::next, sig_pri_span::nodetype, NULL, NUM_SPANS, sig_pri_span::numchans, analog_pvt::onhooktime, analog_pvt::outsigmod, analog_pvt::permcallwaiting, analog_pvt::permhidecallerid, analog_pvt::polarityonanswerdelay, sig_pri_chan::priexclusive, sig_pri_chan::priindication_oob, analog_pvt::pulse, sig_pri_span::pvts, sig_ss7_chan::remotelyblocked, analog_pvt::ringt, ringt_base, analog_pvt::ringt_base, set_actual_gain(), set_hwgain(), sig2str, SIG_BRI_PTMP, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_FXSLS, SIG_MFCR2, SIG_PRI, sig_pri_chan_new(), SIG_PRI_LIB_HANDLE_CASES, SIG_PRI_NUM_DCHANS, sig_pri_set_alarm(), SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, SIG_SS7, sig_ss7_chan_new(), sig_ss7_set_alarm(), sigtype_to_signalling(), analog_pvt::smdi_iface, SS7_BLOCKED_HARDWARE, stasis_subscription_cb_noop(), state, analog_pvt::stripmsd, sig_pri_chan::stripmsd, sig_ss7_chan::stripmsd, SUB_REAL, sig_pri_span::switchtype, analog_pvt::threewaycalling, tmp(), analog_pvt::transfer, analog_pvt::transfertobusy, sig_pri_span::trunkgroup, analog_pvt::use_callerid, sig_pri_chan::use_callerid, sig_ss7_chan::use_callerid, sig_pri_chan::use_callingpres, sig_ss7_chan::use_callingpres, analog_pvt::use_smdi, usedistinctiveringdetection, analog_pvt::usedistinctiveringdetection, and ast_variable::value.

Referenced by build_channels(), and process_dahdi().

◆ monitor_pfds_clean()

static void monitor_pfds_clean ( void *  arg)
static

Definition at line 11854 of file chan_dahdi.c.

11854 {
11855 struct pollfd **pfds = arg;
11856 ast_free(*pfds);
11857}

References ast_free.

Referenced by do_monitor().

◆ mwi_send_init()

static int mwi_send_init ( struct dahdi_pvt pvt)
static

Definition at line 11260 of file chan_dahdi.c.

11261{
11262 int x;
11263
11264#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11265 /* Determine how this spill is to be sent */
11266 if (pvt->mwisend_rpas) {
11268 pvt->mwisendactive = 1;
11269 } else if (pvt->mwisend_fsk) {
11271 pvt->mwisendactive = 1;
11272 } else {
11273 pvt->mwisendactive = 0;
11274 return 0;
11275 }
11276#else
11277 if (mwisend_rpas) {
11279 } else {
11281 }
11282 pvt->mwisendactive = 1;
11283#endif
11284
11285 if (pvt->cidspill) {
11286 ast_log(LOG_WARNING, "cidspill already exists when trying to send FSK MWI\n");
11287 ast_free(pvt->cidspill);
11288 pvt->cidspill = NULL;
11289 pvt->cidpos = 0;
11290 pvt->cidlen = 0;
11291 }
11293 if (!pvt->cidspill) {
11294 pvt->mwisendactive = 0;
11295 return -1;
11296 }
11297 x = DAHDI_FLUSH_BOTH;
11298 ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
11299 x = 3000;
11300 ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_ONHOOKTRANSFER, &x);
11301#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11302 if (pvt->mwisend_fsk) {
11303#endif
11305 CID_MWI_TYPE_MDMF_FULL, AST_LAW(pvt), pvt->cid_name, pvt->cid_num, 0);
11306 pvt->cidpos = 0;
11307#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11308 }
11309#endif
11310 return 0;
11311}
int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, struct ast_format *codec, const char *name, const char *number, int flags)
Generate message waiting indicator.
Definition: callerid.c:952
#define MAX_CALLERID_SIZE
Definition: callerid.h:50
#define CID_MWI_TYPE_MDMF_FULL
Definition: callerid.h:83
static int mwisend_rpas
Definition: chan_dahdi.c:723
@ MWI_SEND_SA
Definition: chan_dahdi.h:102
@ MWI_SEND_SPILL
Definition: chan_dahdi.h:105
struct mwisend_info mwisend_data
Definition: chan_dahdi.h:480
mwisend_states mwisend_current
Definition: chan_dahdi.h:112

References ast_callerid_vmwi_generate(), ast_calloc, ast_free, AST_LAW, ast_log, CID_MWI_TYPE_MDMF_FULL, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, dahdi_subchannel::dfd, has_voicemail(), LOG_WARNING, MAX_CALLERID_SIZE, MWI_SEND_SA, MWI_SEND_SPILL, mwisend_info::mwisend_current, dahdi_pvt::mwisend_data, mwisend_rpas, dahdi_pvt::mwisendactive, NULL, SUB_REAL, and dahdi_pvt::subs.

Referenced by do_monitor().

◆ mwi_send_process_buffer()

static int mwi_send_process_buffer ( struct dahdi_pvt pvt,
int  num_read 
)
static

Definition at line 11313 of file chan_dahdi.c.

11314{
11315 struct timeval now;
11316 int res;
11317
11318 /* sanity check to catch if this had been interrupted previously
11319 * i.e. state says there is more to do but there is no spill allocated
11320 */
11321 if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current && !pvt->cidspill) {
11323 } else if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) {
11324 /* Normal processing -- Perform mwi send action */
11325 switch ( pvt->mwisend_data.mwisend_current) {
11326 case MWI_SEND_SA:
11327 /* Send the Ring Pulse Signal Alert */
11328 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &AS_RP_cadence);
11329 if (res) {
11330 ast_log(LOG_WARNING, "Unable to set RP-AS ring cadence: %s\n", strerror(errno));
11331 goto quit;
11332 }
11333 res = dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RING);
11335 break;
11336 case MWI_SEND_SA_WAIT: /* do nothing until I get RINGEROFF event */
11337 break;
11338 case MWI_SEND_PAUSE: /* Wait between alert and spill - min of 500 mS*/
11339#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11340 if (pvt->mwisend_fsk) {
11341#endif
11342 gettimeofday(&now, NULL);
11343 if ((int)(now.tv_sec - pvt->mwisend_data.pause.tv_sec) * 1000000 + (int)now.tv_usec - (int)pvt->mwisend_data.pause.tv_usec > 500000) {
11345 }
11346#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11347 } else { /* support for mwisendtype=nofsk */
11349 }
11350#endif
11351 break;
11352 case MWI_SEND_SPILL:
11353 /* We read some number of bytes. Write an equal amount of data */
11354 if (0 < num_read) {
11355 if (num_read > pvt->cidlen - pvt->cidpos) {
11356 num_read = pvt->cidlen - pvt->cidpos;
11357 }
11358 res = write(pvt->subs[SUB_REAL].dfd, pvt->cidspill + pvt->cidpos, num_read);
11359 if (res > 0) {
11360 pvt->cidpos += res;
11361 if (pvt->cidpos >= pvt->cidlen) {
11363 }
11364 } else {
11365 ast_log(LOG_WARNING, "MWI FSK Send Write failed: %s\n", strerror(errno));
11366 goto quit;
11367 }
11368 }
11369 break;
11370 case MWI_SEND_CLEANUP:
11371 /* For now, do nothing */
11373 break;
11374 default:
11375 /* Should not get here, punt*/
11376 goto quit;
11377 }
11378 }
11379
11381 if (pvt->cidspill) {
11382 ast_free(pvt->cidspill);
11383 pvt->cidspill = NULL;
11384 pvt->cidpos = 0;
11385 pvt->cidlen = 0;
11386 }
11387 pvt->mwisendactive = 0;
11388 }
11389 return 0;
11390quit:
11391 if (pvt->cidspill) {
11392 ast_free(pvt->cidspill);
11393 pvt->cidspill = NULL;
11394 pvt->cidpos = 0;
11395 pvt->cidlen = 0;
11396 }
11397 pvt->mwisendactive = 0;
11398 return -1;
11399}
static struct dahdi_ring_cadence AS_RP_cadence
Definition: chan_dahdi.c:709
@ MWI_SEND_PAUSE
Definition: chan_dahdi.h:104
@ MWI_SEND_SA_WAIT
Definition: chan_dahdi.h:103
@ MWI_SEND_DONE
Definition: chan_dahdi.h:107
@ MWI_SEND_CLEANUP
Definition: chan_dahdi.h:106
struct timeval pause
Definition: chan_dahdi.h:111

References AS_RP_cadence, ast_free, ast_log, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, dahdi_set_hook(), dahdi_subchannel::dfd, errno, LOG_WARNING, MWI_SEND_CLEANUP, MWI_SEND_DONE, MWI_SEND_PAUSE, MWI_SEND_SA, MWI_SEND_SA_WAIT, MWI_SEND_SPILL, mwisend_info::mwisend_current, dahdi_pvt::mwisend_data, dahdi_pvt::mwisendactive, NULL, mwisend_info::pause, SUB_REAL, and dahdi_pvt::subs.

Referenced by do_monitor().

◆ mwi_send_process_event()

static int mwi_send_process_event ( struct dahdi_pvt pvt,
int  event 
)
static

Definition at line 11401 of file chan_dahdi.c.

11402{
11403 int handled = 0;
11404
11406 switch (event) {
11407 case DAHDI_EVENT_RINGEROFF:
11409 handled = 1;
11410
11411 if (dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RINGOFF) ) {
11412 ast_log(LOG_WARNING, "Unable to finish RP-AS: %s mwi send aborted\n", strerror(errno));
11413 ast_free(pvt->cidspill);
11414 pvt->cidspill = NULL;
11416 pvt->mwisendactive = 0;
11417 } else {
11419 gettimeofday(&pvt->mwisend_data.pause, NULL);
11420 }
11421 }
11422 break;
11423 /* Going off hook, I need to punt this spill */
11424 case DAHDI_EVENT_RINGOFFHOOK:
11425 if (pvt->cidspill) {
11426 ast_free(pvt->cidspill);
11427 pvt->cidspill = NULL;
11428 pvt->cidpos = 0;
11429 pvt->cidlen = 0;
11430 }
11432 pvt->mwisendactive = 0;
11433 break;
11434 case DAHDI_EVENT_RINGERON:
11435 case DAHDI_EVENT_HOOKCOMPLETE:
11436 break;
11437 default:
11438 break;
11439 }
11440 }
11441 return handled;
11442}

References ast_free, ast_log, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, dahdi_set_hook(), dahdi_subchannel::dfd, errno, LOG_WARNING, MWI_SEND_DONE, MWI_SEND_PAUSE, MWI_SEND_SA_WAIT, mwisend_info::mwisend_current, dahdi_pvt::mwisend_data, dahdi_pvt::mwisendactive, NULL, mwisend_info::pause, SUB_REAL, and dahdi_pvt::subs.

Referenced by do_monitor().

◆ mwi_thread()

static void * mwi_thread ( void *  data)
static

Definition at line 11103 of file chan_dahdi.c.

11104{
11105 struct mwi_thread_data *mtd = data;
11106 struct callerid_state *cs;
11107 pthread_t threadid;
11108 int samples = 0;
11109 char *name, *number;
11110 int flags;
11111 int i, res;
11112 unsigned int spill_done = 0;
11113 int spill_result = -1;
11114
11115 if (!(cs = callerid_new(mtd->pvt->cid_signalling))) {
11116 goto quit_no_clean;
11117 }
11118
11119 callerid_feed(cs, mtd->buf, mtd->len, AST_LAW(mtd->pvt));
11120
11121 bump_gains(mtd->pvt);
11122
11123 for (;;) {
11124 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
11125 if ((res = ioctl(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_IOMUX, &i))) {
11126 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
11127 goto quit;
11128 }
11129
11130 if (i & DAHDI_IOMUX_SIGEVENT) {
11131 struct ast_channel *chan;
11132 ast_callid callid = 0;
11133 int callid_created;
11134
11135 /* If we get an event, screen out events that we do not act on.
11136 * Otherwise, cancel and go to the simple switch to let it deal with it.
11137 */
11138 res = dahdi_get_event(mtd->pvt->subs[SUB_REAL].dfd);
11139
11140 switch (res) {
11141 case DAHDI_EVENT_NEONMWI_ACTIVE:
11142 case DAHDI_EVENT_NEONMWI_INACTIVE:
11143 case DAHDI_EVENT_NONE:
11144 case DAHDI_EVENT_BITSCHANGED:
11145 break;
11146 case DAHDI_EVENT_NOALARM:
11147 if (dahdi_analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
11148 struct analog_pvt *analog_p = mtd->pvt->sig_pvt;
11149
11150 analog_p->inalarm = 0;
11151 }
11152 mtd->pvt->inalarm = 0;
11154 break;
11155 case DAHDI_EVENT_ALARM:
11156 if (dahdi_analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
11157 struct analog_pvt *analog_p = mtd->pvt->sig_pvt;
11158
11159 analog_p->inalarm = 1;
11160 }
11161 mtd->pvt->inalarm = 1;
11162 res = get_alarms(mtd->pvt);
11163 handle_alarms(mtd->pvt, res);
11164 break; /* What to do on channel alarm ???? -- fall thru intentionally?? */
11165 default:
11166 callid_created = ast_callid_threadstorage_auto(&callid);
11167 ast_log(LOG_NOTICE, "Got event %d (%s)... Passing along to analog_ss_thread\n", res, event2str(res));
11168 callerid_free(cs);
11169
11170 restore_gains(mtd->pvt);
11171 mtd->pvt->ringt = mtd->pvt->ringt_base;
11172
11173 if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, NULL, NULL, callid))) {
11174 int result;
11175
11176 if (dahdi_analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
11178 } else {
11180 }
11181 if (result) {
11182 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", mtd->pvt->channel);
11183 res = tone_zone_play_tone(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
11184 if (res < 0)
11185 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", mtd->pvt->channel);
11186 ast_hangup(chan);
11187 }
11188 } else {
11189 ast_log(LOG_WARNING, "Could not create channel to handle call\n");
11190 }
11191
11192 ast_callid_threadstorage_auto_clean(callid, callid_created);
11193 goto quit_no_clean;
11194 }
11195 } else if (i & DAHDI_IOMUX_READ) {
11196 if ((res = read(mtd->pvt->subs[SUB_REAL].dfd, mtd->buf, sizeof(mtd->buf))) < 0) {
11197 if (errno != ELAST) {
11198 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
11199 goto quit;
11200 }
11201 break;
11202 }
11203 samples += res;
11204 if (!spill_done) {
11205 if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) {
11206 /*
11207 * The previous diagnostic message output likely
11208 * explains why it failed.
11209 */
11210 ast_log(LOG_WARNING, "Failed to decode CallerID\n");
11211 break;
11212 } else if (spill_result) {
11213 spill_done = 1;
11214 }
11215 } else {
11216 /* keep reading data until the energy level drops below the threshold
11217 so we don't get another 'trigger' on the remaining carrier signal
11218 */
11219 if (calc_energy(mtd->buf, res, AST_LAW(mtd->pvt)) <= mwilevel)
11220 break;
11221 }
11222 if (samples > (8000 * 4)) /*Termination case - time to give up*/
11223 break;
11224 }
11225 }
11226
11227 if (spill_result == 1) {
11228 callerid_get(cs, &name, &number, &flags);
11229 if (flags & CID_MSGWAITING) {
11230 ast_log(LOG_NOTICE, "mwi: Have Messages on channel %d\n", mtd->pvt->channel);
11231 notify_message(mtd->pvt->mailbox, 1);
11232 } else if (flags & CID_NOMSGWAITING) {
11233 ast_log(LOG_NOTICE, "mwi: No Messages on channel %d\n", mtd->pvt->channel);
11234 notify_message(mtd->pvt->mailbox, 0);
11235 } else {
11236 ast_log(LOG_NOTICE, "mwi: Status unknown on channel %d\n", mtd->pvt->channel);
11237 }
11238 }
11239
11240
11241quit:
11242 callerid_free(cs);
11243
11244 restore_gains(mtd->pvt);
11245
11246quit_no_clean:
11247 mtd->pvt->mwimonitoractive = 0;
11248 ast_free(mtd);
11249
11250 return NULL;
11251}
#define CID_NOMSGWAITING
Definition: callerid.h:57
#define CID_MSGWAITING
Definition: callerid.h:56
static PGresult * result
Definition: cel_pgsql.c:84
int analog_ss_thread_start(struct analog_pvt *p, struct ast_channel *chan)
Definition: sig_analog.c:2752
char number[64]
Definition: callerid.c:54

References analog_ss_thread(), analog_ss_thread_start(), ast_callid_threadstorage_auto(), ast_callid_threadstorage_auto_clean(), ast_free, ast_hangup(), AST_LAW, ast_log, ast_pthread_create_detached, AST_STATE_RING, mwi_thread_data::buf, bump_gains(), calc_energy(), callerid_feed(), callerid_free(), callerid_get(), callerid_new(), ast_channel::callid, dahdi_pvt::channel, CID_MSGWAITING, CID_NOMSGWAITING, dahdi_pvt::cid_signalling, dahdi_analog_lib_handles(), dahdi_get_event(), dahdi_new(), dahdi_subchannel::dfd, errno, event2str(), callerid_state::flags, get_alarms(), handle_alarms(), handle_clear_alarms(), dahdi_pvt::inalarm, analog_pvt::inalarm, mwi_thread_data::len, LOG_NOTICE, LOG_WARNING, dahdi_pvt::mailbox, mwilevel, dahdi_pvt::mwimonitoractive, name, notify_message(), NULL, callerid_state::number, dahdi_pvt::oprmode, mwi_thread_data::pvt, dahdi_pvt::radio, restore_gains(), result, dahdi_pvt::ringt, dahdi_pvt::ringt_base, dahdi_pvt::sig, dahdi_pvt::sig_pvt, SUB_REAL, and dahdi_pvt::subs.

Referenced by do_monitor().

◆ my_all_subchannels_hungup()

static void my_all_subchannels_hungup ( void *  pvt)
static

Definition at line 2263 of file chan_dahdi.c.

2264{
2265 struct dahdi_pvt *p = pvt;
2266 int res, law;
2267
2268 p->faxhandled = 0;
2269 p->didtdd = 0;
2270
2271 if (p->dsp) {
2272 ast_dsp_free(p->dsp);
2273 p->dsp = NULL;
2274 }
2275
2276 p->law = p->law_default;
2277 law = p->law_default;
2278 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
2279 if (res < 0)
2280 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
2281
2283
2284#if 1
2285 {
2286 int i;
2287 p->owner = NULL;
2288 /* Cleanup owners here */
2289 for (i = 0; i < 3; i++) {
2290 p->subs[i].owner = NULL;
2291 }
2292 }
2293#endif
2294
2295 reset_conf(p);
2296 if (num_restart_pending == 0) {
2298 }
2299}

References ast_dsp_free(), ast_log, dahdi_pvt::channel, dahdi_setlinear(), dahdi_subchannel::dfd, dahdi_pvt::didtdd, dahdi_pvt::dsp, errno, dahdi_pvt::faxhandled, dahdi_pvt::law, dahdi_pvt::law_default, LOG_WARNING, NULL, num_restart_pending, dahdi_subchannel::owner, dahdi_pvt::owner, reset_conf(), restart_monitor(), SUB_REAL, and dahdi_pvt::subs.

◆ my_allocate_sub()

static int my_allocate_sub ( void *  pvt,
enum analog_sub  analogsub 
)
static

Definition at line 2580 of file chan_dahdi.c.

2581{
2582 struct dahdi_pvt *p = pvt;
2583
2584 return alloc_sub(p, analogsub_to_dahdisub(analogsub));
2585}
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1253

References alloc_sub(), and analogsub_to_dahdisub().

◆ my_answer_polarityswitch()

static void my_answer_polarityswitch ( void *  pvt)
static

Definition at line 2815 of file chan_dahdi.c.

2816{
2817 struct dahdi_pvt *p = pvt;
2818
2819 if (!p->answeronpolarityswitch) {
2820 return;
2821 }
2822
2823 my_set_polarity(pvt, 1);
2824}
static void my_set_polarity(void *pvt, int value)
Definition: chan_dahdi.c:2795

References dahdi_pvt::answeronpolarityswitch, and my_set_polarity().

◆ my_callwait()

static int my_callwait ( void *  pvt)
static

Definition at line 1664 of file chan_dahdi.c.

1665{
1666 struct dahdi_pvt *p = pvt;
1667
1669 if (p->cidspill) {
1670 ast_log(LOG_WARNING, "Spill already exists?!?\n");
1671 ast_free(p->cidspill);
1672 }
1673
1674 /*
1675 * SAS: Subscriber Alert Signal, 440Hz for 300ms
1676 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
1677 */
1678 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
1679 return -1;
1680 save_conference(p);
1681 /* Silence */
1682 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
1683 if (!p->callwaitrings && p->callwaitingcallerid) {
1684 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
1685 p->callwaitcas = 1;
1686 p->cidlen = 2400 + 680 + READ_SIZE * 4;
1687 } else {
1688 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
1689 p->callwaitcas = 0;
1690 p->cidlen = 2400 + READ_SIZE * 4;
1691 }
1692 p->cidpos = 0;
1693 send_callerid(p);
1694
1695 return 0;
1696}

References ast_free, ast_gen_cas(), AST_LAW, ast_log, ast_malloc, dahdi_pvt::callwaitcas, CALLWAITING_REPEAT_SAMPLES, dahdi_pvt::callwaitingcallerid, dahdi_pvt::callwaitingrepeat, dahdi_pvt::callwaitrings, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, LOG_WARNING, READ_SIZE, save_conference(), and send_callerid().

◆ my_cancel_cidspill()

static void my_cancel_cidspill ( void *  pvt)
static

Definition at line 2213 of file chan_dahdi.c.

2214{
2215 struct dahdi_pvt *p = pvt;
2216
2217 ast_free(p->cidspill);
2218 p->cidspill = NULL;
2220}

References ast_free, dahdi_pvt::cidspill, NULL, and restore_conference().

◆ my_check_confirmanswer()

static int my_check_confirmanswer ( void *  pvt)
static

Definition at line 2196 of file chan_dahdi.c.

2197{
2198 struct dahdi_pvt *p = pvt;
2199 if (p->confirmanswer) {
2200 return 1;
2201 }
2202
2203 return 0;
2204}

References dahdi_pvt::confirmanswer.

◆ my_check_for_conference()

static int my_check_for_conference ( void *  pvt)
static

Definition at line 2373 of file chan_dahdi.c.

2374{
2375 struct dahdi_pvt *p = pvt;
2376 return check_for_conference(p);
2377}

References check_for_conference().

◆ my_check_waitingfordt()

static int my_check_waitingfordt ( void *  pvt)
static

Definition at line 2179 of file chan_dahdi.c.

2180{
2181 struct dahdi_pvt *p = pvt;
2182
2183 if (p->waitingfordt.tv_sec) {
2184 return 1;
2185 }
2186
2187 return 0;
2188}

References dahdi_pvt::waitingfordt.

◆ my_complete_conference_update()

static int my_complete_conference_update ( void *  pvt,
int  needconference 
)
static

Definition at line 2323 of file chan_dahdi.c.

2324{
2325 struct dahdi_pvt *p = pvt;
2326 int needconf = needconference;
2327 int x;
2328 int useslavenative;
2329 struct dahdi_pvt *slave = NULL;
2330
2331 useslavenative = isslavenative(p, &slave);
2332
2333 /* If we have a slave, add him to our conference now. or DAX
2334 if this is slave native */
2335 for (x = 0; x < MAX_SLAVES; x++) {
2336 if (p->slaves[x]) {
2337 if (useslavenative)
2338 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
2339 else {
2340 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
2341 needconf++;
2342 }
2343 }
2344 }
2345 /* If we're supposed to be in there, do so now */
2346 if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
2347 if (useslavenative)
2348 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
2349 else {
2350 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
2351 needconf++;
2352 }
2353 }
2354 /* If we have a master, add ourselves to his conference */
2355 if (p->master) {
2356 if (isslavenative(p->master, NULL)) {
2358 } else {
2359 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
2360 }
2361 }
2362 if (!needconf) {
2363 /* Nobody is left (or should be left) in our conference.
2364 Kill it. */
2365 p->confno = -1;
2366 }
2367
2368 return 0;
2369}

References conf_add(), dahdi_pvt::confno, GET_CHANNEL, dahdi_pvt::inconference, dahdi_subchannel::inthreeway, isslavenative(), dahdi_pvt::master, MAX_SLAVES, NULL, dahdi_pvt::slaves, SUB_REAL, and dahdi_pvt::subs.

◆ my_conf_add()

static int my_conf_add ( void *  pvt,
enum analog_sub  sub 
)
static

Definition at line 2313 of file chan_dahdi.c.

2314{
2315 struct dahdi_pvt *p = pvt;
2316 int x = analogsub_to_dahdisub(sub);
2317
2318 return conf_add(p, &p->subs[x], x, 0);
2319}
struct stasis_forward * sub
Definition: res_corosync.c:240

References analogsub_to_dahdisub(), conf_add(), sub, and dahdi_pvt::subs.

◆ my_conf_del()

static int my_conf_del ( void *  pvt,
enum analog_sub  sub 
)
static

Definition at line 2303 of file chan_dahdi.c.

2304{
2305 struct dahdi_pvt *p = pvt;
2306 int x = analogsub_to_dahdisub(sub);
2307
2308 return conf_del(p, &p->subs[x], x);
2309}

References analogsub_to_dahdisub(), conf_del(), sub, and dahdi_pvt::subs.

◆ my_confmute()

static int my_confmute ( void *  pvt,
int  mute 
)
static

Definition at line 2222 of file chan_dahdi.c.

2223{
2224 struct dahdi_pvt *p = pvt;
2225 return dahdi_confmute(p, mute);
2226}

References dahdi_confmute().

◆ my_dahdi_write()

static int my_dahdi_write ( struct dahdi_pvt p,
unsigned char *  buf,
int  len,
int  idx,
int  linear 
)
static

Definition at line 9249 of file chan_dahdi.c.

9250{
9251 int sent=0;
9252 int size;
9253 int res;
9254 int fd;
9255 fd = p->subs[idx].dfd;
9256 while (len) {
9257 size = len;
9258 if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
9259 size = (linear ? READ_SIZE * 2 : READ_SIZE);
9260 res = write(fd, buf, size);
9261 if (res != size) {
9262 ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
9263 return sent;
9264 }
9265 len -= size;
9266 buf += size;
9267 }
9268 return sent;
9269}

References ast_debug, buf, dahdi_pvt::channel, dahdi_subchannel::dfd, errno, len(), READ_SIZE, and dahdi_pvt::subs.

Referenced by dahdi_write().

◆ my_deadlock_avoidance_private()

static void my_deadlock_avoidance_private ( void *  pvt)
static

Definition at line 1903 of file chan_dahdi.c.

1904{
1905 struct dahdi_pvt *p = pvt;
1906
1908}

References DEADLOCK_AVOIDANCE, and dahdi_pvt::lock.

◆ my_decrease_ss_count()

static void my_decrease_ss_count ( void  )
static

◆ my_dial_digits()

static int my_dial_digits ( void *  pvt,
enum analog_sub  sub,
struct analog_dialoperation dop 
)
static

Definition at line 2929 of file chan_dahdi.c.

2930{
2931 struct dahdi_pvt *p = pvt;
2932
2933 if (dop->op != ANALOG_DIAL_OP_REPLACE) {
2934 ast_log(LOG_ERROR, "Fix the dial_digits callback!\n");
2935 return -1;
2936 }
2937
2938 if (sub != ANALOG_SUB_REAL) {
2939 ast_log(LOG_ERROR, "Trying to dial_digits '%s' on channel %d subchannel %u\n",
2940 dop->dialstr, p->channel, sub);
2941 return -1;
2942 }
2943
2944 return dahdi_dial_str(p, DAHDI_DIAL_OP_REPLACE, dop->dialstr);
2945}
@ ANALOG_DIAL_OP_REPLACE
Definition: sig_analog.h:134

References ANALOG_DIAL_OP_REPLACE, ANALOG_SUB_REAL, ast_log, dahdi_pvt::channel, dahdi_dial_str(), dahdi_pvt::dop, LOG_ERROR, and sub.

◆ my_distinctive_ring()

static int my_distinctive_ring ( struct ast_channel chan,
void *  pvt,
int  idx,
int *  ringdata 
)
static

Definition at line 1526 of file chan_dahdi.c.

1527{
1528 unsigned char buf[256];
1529 int distMatches;
1530 int curRingData[RING_PATTERNS];
1531 int receivedRingT;
1532 int counter1;
1533 int counter;
1534 int i;
1535 int res;
1536 int checkaftercid = 0;
1537 const char *matched_context;
1538 struct dahdi_pvt *p = pvt;
1539 struct analog_pvt *analog_p = p->sig_pvt;
1540
1541 if (ringdata == NULL) {
1542 ringdata = curRingData;
1543 } else {
1544 checkaftercid = 1;
1545 }
1546
1547 /* We must have a ring by now so lets try to listen for distinctive ringing */
1548 if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) {
1549 /* Clear the current ring data array so we don't have old data in it. */
1550 for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++)
1551 ringdata[receivedRingT] = 0;
1552 receivedRingT = 0;
1553
1554 if (checkaftercid && distinctiveringaftercid) {
1555 ast_verb(3, "Detecting post-CID distinctive ring\n");
1556 }
1557
1558 for (;;) {
1559 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
1560 res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i);
1561 if (res) {
1562 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
1563 ast_hangup(chan);
1564 return 1;
1565 }
1566 if (i & DAHDI_IOMUX_SIGEVENT) {
1567 res = dahdi_get_event(p->subs[idx].dfd);
1568 ast_debug(3, "Got event %d (%s)...\n", res, event2str(res));
1569 if (res == DAHDI_EVENT_NOALARM) {
1570 p->inalarm = 0;
1571 analog_p->inalarm = 0;
1572 } else if (res == DAHDI_EVENT_RINGOFFHOOK) {
1573 /* Let us detect distinctive ring */
1574 ringdata[receivedRingT] = analog_p->ringt;
1575
1576 if (analog_p->ringt < analog_p->ringt_base / 2) {
1577 break;
1578 }
1579 /* Increment the ringT counter so we can match it against
1580 values in chan_dahdi.conf for distinctive ring */
1581 if (++receivedRingT == RING_PATTERNS) {
1582 break;
1583 }
1584 }
1585 } else if (i & DAHDI_IOMUX_READ) {
1586 res = read(p->subs[idx].dfd, buf, sizeof(buf));
1587 if (res < 0) {
1588 if (errno != ELAST) {
1589 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1590 ast_hangup(chan);
1591 return 1;
1592 }
1593 break;
1594 }
1595 if (analog_p->ringt > 0) {
1596 if (!(--analog_p->ringt)) {
1597 break;
1598 }
1599 }
1600 }
1601 }
1602 }
1603
1604 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */
1605 ast_verb(3, "Detected ring pattern: %d,%d,%d\n", ringdata[0], ringdata[1], ringdata[2]);
1606 matched_context = p->defcontext;
1607 for (counter = 0; counter < 3; counter++) {
1608 int range = p->drings.ringnum[counter].range;
1609
1610 distMatches = 0;
1611 ast_verb(3, "Checking %d,%d,%d with +/- %d range\n",
1612 p->drings.ringnum[counter].ring[0],
1613 p->drings.ringnum[counter].ring[1],
1614 p->drings.ringnum[counter].ring[2],
1615 range);
1616 for (counter1 = 0; counter1 < 3; counter1++) {
1617 int ring = p->drings.ringnum[counter].ring[counter1];
1618
1619 if (ring == -1) {
1620 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
1621 ringdata[counter1]);
1622 distMatches++;
1623 } else if (ring - range <= ringdata[counter1] && ringdata[counter1] <= ring + range) {
1624 ast_verb(3, "Ring pattern %d is in range: %d to %d\n",
1625 ringdata[counter1], ring - range, ring + range);
1626 distMatches++;
1627 } else {
1628 /* The current dring pattern cannot match. */
1629 break;
1630 }
1631 }
1632
1633 if (distMatches == 3) {
1634 /* The ring matches, set the context to whatever is for distinctive ring.. */
1635 matched_context = S_OR(p->drings.ringContext[counter].contextData, p->defcontext);
1636 ast_verb(3, "Matched Distinctive Ring context %s\n", matched_context);
1637 break;
1638 }
1639 }
1640
1641 /* Set selected distinctive ring context if not already set. */
1642 if (strcmp(p->context, matched_context) != 0) {
1643 ast_copy_string(p->context, matched_context, sizeof(p->context));
1644 ast_channel_context_set(chan, matched_context);
1645 }
1646
1647 return 0;
1648}
#define RING_PATTERNS
Definition: sig_analog.h:35

References ast_channel_context_set(), ast_copy_string(), ast_debug, ast_hangup(), ast_log, ast_verb, buf, dahdi_pvt::context, ringContextData::contextData, dahdi_get_event(), dahdi_pvt::defcontext, dahdi_subchannel::dfd, distinctiveringaftercid, dahdi_pvt::drings, errno, event2str(), dahdi_pvt::inalarm, analog_pvt::inalarm, LOG_WARNING, NULL, distRingData::range, distRingData::ring, RING_PATTERNS, dahdi_distRings::ringContext, dahdi_distRings::ringnum, analog_pvt::ringt, analog_pvt::ringt_base, S_OR, dahdi_pvt::sig_pvt, and dahdi_pvt::subs.

◆ my_dsp_reset_and_flush_digits()

static int my_dsp_reset_and_flush_digits ( void *  pvt)
static

Definition at line 1751 of file chan_dahdi.c.

1752{
1753 struct dahdi_pvt *p = pvt;
1754 if (p->dsp)
1756
1757 return 0;
1758}

References ast_dsp_digitreset(), and dahdi_pvt::dsp.

◆ my_dsp_set_digitmode()

static int my_dsp_set_digitmode ( void *  pvt,
enum analog_dsp_digitmode  mode 
)
static

Definition at line 1760 of file chan_dahdi.c.

1761{
1762 struct dahdi_pvt *p = pvt;
1763
1764 if (p->channel == CHAN_PSEUDO)
1765 ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n");
1766
1767 if (mode == ANALOG_DIGITMODE_DTMF) {
1768 /* If we do hardware dtmf, no need for a DSP */
1769 if (p->hardwaredtmf) {
1770 if (p->dsp) {
1771 ast_dsp_free(p->dsp);
1772 p->dsp = NULL;
1773 }
1774 return 0;
1775 }
1776
1777 if (!p->dsp) {
1778 p->dsp = ast_dsp_new();
1779 if (!p->dsp) {
1780 ast_log(LOG_ERROR, "Unable to allocate DSP\n");
1781 return -1;
1782 }
1783 }
1784
1786 } else if (mode == ANALOG_DIGITMODE_MF) {
1787 if (!p->dsp) {
1788 p->dsp = ast_dsp_new();
1789 if (!p->dsp) {
1790 ast_log(LOG_ERROR, "Unable to allocate DSP\n");
1791 return -1;
1792 }
1793 }
1795 }
1796 return 0;
1797}
@ ANALOG_DIGITMODE_DTMF
Definition: sig_analog.h:115
@ ANALOG_DIGITMODE_MF
Definition: sig_analog.h:116

References ANALOG_DIGITMODE_DTMF, ANALOG_DIGITMODE_MF, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_digitmode(), ast_log, CHAN_PSEUDO, dahdi_pvt::channel, dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, dahdi_pvt::dtmfrelax, dahdi_pvt::hardwaredtmf, LOG_ERROR, and NULL.

◆ my_flash()

static int my_flash ( void *  pvt)
static

Definition at line 2774 of file chan_dahdi.c.

2775{
2776 struct dahdi_pvt *p = pvt;
2777 int func = DAHDI_FLASH;
2778 return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func);
2779}

References dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.

◆ my_get_and_handle_alarms()

static void my_get_and_handle_alarms ( void *  pvt)
static

Definition at line 2027 of file chan_dahdi.c.

2028{
2029 int res;
2030 struct dahdi_pvt *p = pvt;
2031
2032 res = get_alarms(p);
2033 handle_alarms(p, res);
2034}

References get_alarms(), and handle_alarms().

◆ my_get_callerid()

static int my_get_callerid ( void *  pvt,
char *  namebuf,
char *  numbuf,
enum analog_event ev,
size_t  timeout 
)
static

Definition at line 1429 of file chan_dahdi.c.

1430{
1431 struct dahdi_pvt *p = pvt;
1432 struct analog_pvt *analog_p = p->sig_pvt;
1433 struct pollfd poller;
1434 char *name, *num;
1435 int index = SUB_REAL;
1436 int res;
1437 unsigned char buf[256];
1438 int flags;
1439 int redirecting;
1440
1441 poller.fd = p->subs[SUB_REAL].dfd;
1442 poller.events = POLLPRI | POLLIN;
1443 poller.revents = 0;
1444
1445 res = poll(&poller, 1, timeout);
1446
1447 if (poller.revents & POLLPRI) {
1449 return 1;
1450 }
1451
1452 if (poller.revents & POLLIN) {
1453 /*** NOTES ***/
1454 /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function
1455 * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until
1456 * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be
1457 * a failure and die, and returning 2 means no event was received. */
1458 res = read(p->subs[index].dfd, buf, sizeof(buf));
1459 if (res < 0) {
1460 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1461 return -1;
1462 }
1463
1464 if (analog_p->ringt > 0) {
1465 if (!(--analog_p->ringt)) {
1466 /* only return if we timeout from a ring event */
1467 return -1;
1468 }
1469 }
1470
1471 if (p->cid_signalling == CID_SIG_V23_JP) {
1472 res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p));
1473 } else {
1474 res = callerid_feed(p->cs, buf, res, AST_LAW(p));
1475 }
1476 if (res < 0) {
1477 /*
1478 * The previous diagnostic message output likely
1479 * explains why it failed.
1480 */
1481 ast_log(LOG_WARNING, "Failed to decode CallerID\n");
1482 return -1;
1483 }
1484
1485 if (res == 1) {
1486 struct ast_channel *chan = analog_p->ss_astchan;
1488 if (name)
1490 if (num)
1491 ast_copy_string(numbuf, num, ANALOG_MAX_CID);
1492
1494 /* If we got a presentation, we must set it on the channel */
1495 struct ast_party_caller caller;
1496
1498 caller.id.name.presentation = caller.id.number.presentation = (flags & CID_PRIVATE_NUMBER) ?
1501 ast_party_caller_free(&caller);
1502 }
1503 if (redirecting) {
1504 /* There is a redirecting reason available in the Caller*ID received.
1505 * No idea what the redirecting number is, since the Caller*ID protocol
1506 * has no parameter for that, but at least we know WHY it was redirected. */
1507 ast_channel_redirecting(chan)->reason.code = redirecting;
1508 }
1509
1510 if (flags & CID_QUALIFIER) {
1511 /* This is the inverse of how the qualifier is set in sig_analog */
1512 pbx_builtin_setvar_helper(chan, "CALL_QUALIFIER", "1");
1513 }
1514
1515 ast_debug(1, "CallerID number: %s, name: %s, flags=%d, redirecting=%s\n", num, name, flags, ast_redirecting_reason_name(&ast_channel_redirecting(chan)->reason));
1516 return 0;
1517 }
1518 }
1519
1520 *ev = ANALOG_EVENT_NONE;
1521 return 2;
1522}
#define CID_UNKNOWN_NUMBER
Definition: callerid.h:55
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:426
#define AST_PRES_UNAVAILABLE
Definition: callerid.h:434
#define AST_PRES_RESTRICTED
Definition: callerid.h:433
void callerid_get_with_redirecting(struct callerid_state *cid, char **name, char **number, int *flags, int *redirecting)
Extract info out of callerID state machine. Flags are listed above.
Definition: callerid.c:189
const char * ast_redirecting_reason_name(const struct ast_party_redirecting_reason *data)
Convert redirecting reason value to text code.
Definition: callerid.c:1449
#define CID_PRIVATE_NUMBER
Definition: callerid.h:53
#define CID_QUALIFIER
Definition: callerid.h:58
void ast_party_caller_set(struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update)
Set the caller information based on another caller source.
Definition: channel.c:2007
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
Definition: channel.c:1999
void ast_party_caller_free(struct ast_party_caller *doomed)
Destroy the caller party contents.
Definition: channel.c:2015
#define ANALOG_MAX_CID
Definition: sig_analog.h:33
@ ANALOG_EVENT_NONE
Definition: sig_analog.h:80
struct ast_channel * ss_astchan
Definition: sig_analog.h:372
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
struct ast_flags flags
Caller Party information.
Definition: channel.h:418
int code
enum AST_REDIRECTING_REASON value for redirection
Definition: channel.h:510
struct ast_party_redirecting_reason reason
Reason for the redirection.
Definition: channel.h:542
struct callerid_state * cs
Definition: chan_dahdi.h:126

References ANALOG_EVENT_NONE, ANALOG_MAX_CID, ast_channel_caller(), ast_channel_redirecting(), ast_copy_string(), ast_debug, AST_LAW, ast_log, ast_party_caller_free(), ast_party_caller_set(), ast_party_caller_set_init(), AST_PRES_RESTRICTED, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_UNSCREENED, ast_redirecting_reason_name(), buf, callerid_feed(), callerid_feed_jp(), callerid_get_with_redirecting(), CID_PRIVATE_NUMBER, CID_QUALIFIER, CID_SIG_V23_JP, dahdi_pvt::cid_signalling, CID_UNKNOWN_NUMBER, ast_party_redirecting_reason::code, dahdi_pvt::cs, dahdi_get_event(), dahdievent_to_analogevent(), dahdi_subchannel::dfd, errno, ast_channel::flags, ast_party_caller::id, LOG_WARNING, name, ast_party_id::name, NULL, ast_party_id::number, pbx_builtin_setvar_helper(), ast_party_name::presentation, ast_party_number::presentation, ast_party_redirecting::reason, ast_channel::redirecting, analog_pvt::ringt, dahdi_pvt::sig_pvt, analog_pvt::ss_astchan, SUB_REAL, and dahdi_pvt::subs.

◆ my_get_event()

static int my_get_event ( void *  pvt)
static

Definition at line 2710 of file chan_dahdi.c.

2711{
2712 struct dahdi_pvt *p = pvt;
2713 int res;
2714
2715 if (p->fake_event) {
2716 res = p->fake_event;
2717 p->fake_event = 0;
2718 } else
2719 res = dahdi_get_event(p->subs[SUB_REAL].dfd);
2720
2721 return dahdievent_to_analogevent(res);
2722}

References dahdi_get_event(), dahdievent_to_analogevent(), dahdi_subchannel::dfd, dahdi_pvt::fake_event, SUB_REAL, and dahdi_pvt::subs.

◆ my_get_orig_dialstring()

static const char * my_get_orig_dialstring ( void *  pvt)
static

Definition at line 2241 of file chan_dahdi.c.

2242{
2243 struct dahdi_pvt *p = pvt;
2244
2245 return p->dialstring;
2246}

References dahdi_pvt::dialstring.

◆ my_get_sigpvt_bridged_channel()

static void * my_get_sigpvt_bridged_channel ( struct ast_channel chan)
static

Definition at line 2036 of file chan_dahdi.c.

2037{
2039
2040 if (bridged && ast_channel_tech(bridged) == &dahdi_tech) {
2041 struct dahdi_pvt *p = ast_channel_tech_pvt(bridged);
2042
2043 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
2044 return p->sig_pvt;
2045 }
2046 }
2047 return NULL;
2048}

References ast_channel_bridge_peer(), ast_channel_cleanup, ast_channel_tech(), ast_channel_tech_pvt(), dahdi_analog_lib_handles(), dahdi_tech, NULL, dahdi_pvt::oprmode, dahdi_pvt::radio, RAII_VAR, dahdi_pvt::sig, and dahdi_pvt::sig_pvt.

◆ my_get_sub_fd()

static int my_get_sub_fd ( void *  pvt,
enum analog_sub  sub 
)
static

Definition at line 2050 of file chan_dahdi.c.

2051{
2052 struct dahdi_pvt *p = pvt;
2053 int dahdi_sub = analogsub_to_dahdisub(sub);
2054 return p->subs[dahdi_sub].dfd;
2055}

References analogsub_to_dahdisub(), dahdi_subchannel::dfd, sub, and dahdi_pvt::subs.

◆ my_getsigstr()

static int my_getsigstr ( struct ast_channel chan,
char *  str,
const char *  term,
int  ms 
)
static

Definition at line 9777 of file chan_dahdi.c.

9778{
9779 char c;
9780
9781 *str = 0; /* start with empty output buffer */
9782 for (;;)
9783 {
9784 /* Wait for the first digit (up to specified ms). */
9785 c = ast_waitfordigit(chan, ms);
9786 /* if timeout, hangup or error, return as such */
9787 if (c < 1)
9788 return c;
9789 *str++ = c;
9790 *str = 0;
9791 if (strchr(term, c))
9792 return 1;
9793 }
9794}
const char * str
Definition: app_jack.c:147

References ast_waitfordigit(), c, and str.

Referenced by analog_ss_thread().

◆ my_handle_dtmf()

static void my_handle_dtmf ( void *  pvt,
struct ast_channel ast,
enum analog_sub  analog_index,
struct ast_frame **  dest 
)
static

Definition at line 1817 of file chan_dahdi.c.

1818{
1819 struct ast_frame *f = *dest;
1820 struct dahdi_pvt *p = pvt;
1821 int idx = analogsub_to_dahdisub(analog_index);
1822
1823 ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
1824 f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
1825 (unsigned)f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
1826
1827 if (f->subclass.integer == 'f') {
1828 if (f->frametype == AST_FRAME_DTMF_END) {
1829 /* Fax tone -- Handle and return NULL */
1830 if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
1831 /* If faxbuffers are configured, use them for the fax transmission */
1832 if (p->usefaxbuffers && !p->bufferoverrideinuse) {
1833 struct dahdi_bufferinfo bi = {
1834 .txbufpolicy = p->faxbuf_policy,
1835 .bufsize = p->bufsize,
1836 .numbufs = p->faxbuf_no
1837 };
1838 int res;
1839
1840 if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
1841 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno));
1842 } else {
1843 p->bufferoverrideinuse = 1;
1844 }
1845 }
1846 p->faxhandled = 1;
1847 if (p->dsp) {
1848 p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
1850 ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
1851 }
1852 if (strcmp(ast_channel_exten(ast), "fax")) {
1853 const char *target_context = ast_channel_context(ast);
1854
1855 /*
1856 * We need to unlock 'ast' here because ast_exists_extension has the
1857 * potential to start autoservice on the channel. Such action is prone
1858 * to deadlock if the channel is locked.
1859 *
1860 * ast_async_goto() has its own restriction on not holding the
1861 * channel lock.
1862 */
1864 ast_channel_unlock(ast);
1865 if (ast_exists_extension(ast, target_context, "fax", 1,
1866 S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, NULL))) {
1867 ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast));
1868 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
1869 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
1870 if (ast_async_goto(ast, target_context, "fax", 1))
1871 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
1872 } else {
1873 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
1874 }
1875 ast_channel_lock(ast);
1876 ast_mutex_lock(&p->lock);
1877 } else {
1878 ast_debug(1, "Already in a fax extension, not redirecting\n");
1879 }
1880 } else {
1881 ast_debug(1, "Fax already handled\n");
1882 }
1883 dahdi_confmute(p, 0);
1884 }
1885 p->subs[idx].f.frametype = AST_FRAME_NULL;
1886 p->subs[idx].f.subclass.integer = 0;
1887 *dest = &p->subs[idx].f;
1888 }
1889}

References analogsub_to_dahdisub(), ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_debug, ast_dsp_set_features(), ast_exists_extension(), AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_verb, dahdi_pvt::bufferoverrideinuse, dahdi_pvt::bufsize, dahdi_pvt::callprogress, CALLPROGRESS_FAX, dahdi_confmute(), dahdi_subchannel::dfd, dahdi_pvt::dsp, dahdi_pvt::dsp_features, errno, dahdi_subchannel::f, dahdi_pvt::faxbuf_no, dahdi_pvt::faxbuf_policy, dahdi_pvt::faxhandled, ast_frame::frametype, ast_frame_subclass::integer, dahdi_pvt::lock, LOG_NOTICE, LOG_WARNING, NULL, pbx_builtin_setvar_helper(), S_COR, ast_frame::subclass, dahdi_pvt::subs, and dahdi_pvt::usefaxbuffers.

◆ my_handle_notify_message()

static void my_handle_notify_message ( struct ast_channel chan,
void *  pvt,
int  cid_flags,
int  neon_mwievent 
)
static

Definition at line 3568 of file chan_dahdi.c.

3569{
3570 struct dahdi_pvt *p = pvt;
3571
3572 if (neon_mwievent > -1 && !p->mwimonitor_neon)
3573 return;
3574
3575 if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) {
3576 ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox);
3577 notify_message(p->mailbox, 1);
3578 } else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) {
3579 ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox);
3580 notify_message(p->mailbox, 0);
3581 }
3582 /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
3583 /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
3584 if (neon_mwievent == -1 && p->mwimonitor_rpas) {
3585 ast_hangup(chan);
3586 return;
3587 }
3588}
unsigned int mwimonitor_rpas
TRUE if the FXO port monitors for rpas precursor to fsk MWI indications from the other end.
Definition: chan_dahdi.h:429

References ANALOG_EVENT_NEONMWI_ACTIVE, ANALOG_EVENT_NEONMWI_INACTIVE, ast_hangup(), ast_log, dahdi_pvt::channel, CID_MSGWAITING, CID_NOMSGWAITING, LOG_NOTICE, dahdi_pvt::mailbox, dahdi_pvt::mwimonitor_neon, dahdi_pvt::mwimonitor_rpas, and notify_message().

Referenced by analog_ss_thread().

◆ my_hangup_polarityswitch()

static void my_hangup_polarityswitch ( void *  pvt)
static

Definition at line 2826 of file chan_dahdi.c.

2827{
2828 struct dahdi_pvt *p = pvt;
2829
2830 if (!p->hanguponpolarityswitch) {
2831 return;
2832 }
2833
2834 if (p->answeronpolarityswitch) {
2835 my_set_polarity(pvt, 0);
2836 } else {
2837 my_set_polarity(pvt, 1);
2838 }
2839}

References dahdi_pvt::answeronpolarityswitch, dahdi_pvt::hanguponpolarityswitch, and my_set_polarity().

◆ my_has_voicemail()

static int my_has_voicemail ( void *  pvt)
static

Definition at line 2589 of file chan_dahdi.c.

2590{
2591 struct dahdi_pvt *p = pvt;
2592
2593 return has_voicemail(p);
2594}

References has_voicemail().

◆ my_have_progressdetect()

static int my_have_progressdetect ( void *  pvt)
static

Definition at line 3590 of file chan_dahdi.c.

3591{
3592 struct dahdi_pvt *p = pvt;
3593
3595 && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
3596 return 1;
3597 } else {
3598 /* Don't have progress detection. */
3599 return 0;
3600 }
3601}

References dahdi_pvt::callprogress, CALLPROGRESS_PROGRESS, CANPROGRESSDETECT, dahdi_pvt::dsp, and dahdi_pvt::outgoing.

◆ my_increase_ss_count()

static void my_increase_ss_count ( void  )
static

◆ my_is_dialing()

static int my_is_dialing ( void *  pvt,
enum analog_sub  sub 
)
static

Definition at line 2958 of file chan_dahdi.c.

2959{
2960 struct dahdi_pvt *p = pvt;
2961 int index;
2962 int x;
2963
2964 index = analogsub_to_dahdisub(sub);
2965
2966 if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) {
2967 ast_debug(1, "DAHDI_DIALING ioctl failed!\n");
2968 return -1;
2969 }
2970
2971 return x;
2972}

References analogsub_to_dahdisub(), ast_debug, dahdi_subchannel::dfd, sub, and dahdi_pvt::subs.

◆ my_is_off_hook()

static int my_is_off_hook ( void *  pvt)
static

Definition at line 2724 of file chan_dahdi.c.

2725{
2726 struct dahdi_pvt *p = pvt;
2727 int res;
2728 struct dahdi_params par;
2729
2730 memset(&par, 0, sizeof(par));
2731
2732 if (p->subs[SUB_REAL].dfd > -1)
2733 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
2734 else {
2735 /* Assume not off hook on CVRS */
2736 res = 0;
2737 par.rxisoffhook = 0;
2738 }
2739 if (res) {
2740 ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno));
2741 }
2742
2743 if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
2744 /* When "onhook" that means no battery on the line, and thus
2745 it is out of service..., if it's on a TDM card... If it's a channel
2746 bank, there is no telling... */
2747 return (par.rxbits > -1) || par.rxisoffhook;
2748 }
2749
2750 return par.rxisoffhook;
2751}

References ast_log, dahdi_pvt::channel, dahdi_subchannel::dfd, errno, LOG_WARNING, dahdi_pvt::sig, SIG_FXSGS, SIG_FXSKS, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_hangup(), and do_monitor().

◆ my_lock_private()

static void my_lock_private ( void *  pvt)
static

Definition at line 1891 of file chan_dahdi.c.

1892{
1893 struct dahdi_pvt *p = pvt;
1894 ast_mutex_lock(&p->lock);
1895}

References ast_mutex_lock, and dahdi_pvt::lock.

◆ my_new_analog_ast_channel()

static struct ast_channel * my_new_analog_ast_channel ( void *  pvt,
int  state,
int  startpbx,
enum analog_sub  sub,
const struct ast_channel requestor 
)
static

Definition at line 2423 of file chan_dahdi.c.

2424{
2425 ast_callid callid = 0;
2426 int callid_created = ast_callid_threadstorage_auto(&callid);
2427 struct dahdi_pvt *p = pvt;
2428 int dsub = analogsub_to_dahdisub(sub);
2429
2430 return dahdi_new_callid_clean(p, state, startpbx, dsub, 0, NULL, requestor, callid, callid_created);
2431}
static struct ast_channel * dahdi_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)
Definition: chan_dahdi.c:9521

References analogsub_to_dahdisub(), ast_callid_threadstorage_auto(), ast_channel::callid, dahdi_new_callid_clean(), NULL, and sub.

◆ my_off_hook()

static int my_off_hook ( void *  pvt)
static

Definition at line 2783 of file chan_dahdi.c.

2784{
2785 struct dahdi_pvt *p = pvt;
2786 return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
2787}

References dahdi_set_hook(), dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_hangup().

◆ my_on_hook()

static int my_on_hook ( void *  pvt)
static

Definition at line 2974 of file chan_dahdi.c.

2975{
2976 struct dahdi_pvt *p = pvt;
2977 return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK);
2978}

References ANALOG_SUB_REAL, dahdi_set_hook(), dahdi_subchannel::dfd, and dahdi_pvt::subs.

◆ my_play_tone()

static int my_play_tone ( void *  pvt,
enum analog_sub  sub,
enum analog_tone  tone 
)
static

Definition at line 2596 of file chan_dahdi.c.

2597{
2598 struct dahdi_pvt *p = pvt;
2599 int index;
2600
2601 index = analogsub_to_dahdisub(sub);
2602
2603 return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone));
2604}
static int analog_tone_to_dahditone(enum analog_tone tone)
Definition: chan_dahdi.c:1233

References analog_tone_to_dahditone(), analogsub_to_dahdisub(), dahdi_subchannel::dfd, sub, and dahdi_pvt::subs.

Referenced by dahdi_hangup().

◆ my_ring()

static int my_ring ( void *  pvt)
static

Definition at line 2767 of file chan_dahdi.c.

2768{
2769 struct dahdi_pvt *p = pvt;
2770
2771 return dahdi_ring_phone(p);
2772}

References dahdi_ring_phone().

◆ my_send_callerid()

static int my_send_callerid ( void *  pvt,
int  cwcid,
struct ast_party_caller caller 
)
static

Definition at line 1698 of file chan_dahdi.c.

1699{
1700 struct dahdi_pvt *p = pvt;
1701 struct analog_pvt *analog_p = p->sig_pvt;
1702
1703 ast_debug(2, "Starting cid spill\n");
1704
1705 if (p->cidspill) {
1706 ast_log(LOG_WARNING, "cidspill already exists??\n");
1707 ast_free(p->cidspill);
1708 }
1709
1711 int pres = ast_party_id_presentation(&caller->id);
1712 if (cwcid == 0) {
1713 /* Some CPE support additional parameters for on-hook Caller*ID,
1714 * such as redirecting reason and call qualifier, so send those
1715 * if available.
1716 * I don't know of any CPE that supports this for Call Waiting (unfortunately),
1717 * so don't send those for call waiting as that will just lengthen the CID spill
1718 * for no good reason.
1719 */
1721 caller->id.name.str,
1723 NULL,
1724 analog_p->redirecting_reason,
1725 pres,
1726 analog_p->call_qualifier,
1728 AST_LAW(p));
1729 } else {
1730 ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n",
1732 p->callwaitcas = 0;
1733 p->cidcwexpire = 0;
1735 caller->id.name.str,
1737 NULL,
1738 -1,
1739 pres,
1740 0,
1741 AST_LAW(p));
1742 p->cidlen += READ_SIZE * 4;
1743 }
1744 p->cidpos = 0;
1745 p->cid_suppress_expire = 0;
1746 send_callerid(p);
1747 }
1748 return 0;
1749}
int ast_callerid_callwaiting_full_generate(unsigned char *buf, const char *name, const char *number, const char *ddn, int redirecting, int pres, int qualifier, struct ast_format *codec)
Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)
Definition: callerid.c:1253
#define CID_TYPE_MDMF
Definition: callerid.h:75
int ast_callerid_full_generate(unsigned char *buf, const char *name, const char *number, const char *ddn, int redirecting, int pres, int qualifier, int format, struct ast_format *codec)
Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format)
Definition: callerid.c:1247
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1821
int redirecting_reason
Definition: sig_analog.h:356
unsigned int call_qualifier
Definition: sig_analog.h:349
struct ast_party_caller caller
Definition: sig_analog.h:355

References ast_callerid_callwaiting_full_generate(), ast_callerid_full_generate(), ast_debug, ast_free, AST_LAW, ast_log, ast_malloc, ast_party_id_presentation(), ast_verb, analog_pvt::call_qualifier, analog_pvt::caller, dahdi_pvt::callwaitcas, dahdi_pvt::cid_suppress_expire, CID_TYPE_MDMF, dahdi_pvt::cidcwexpire, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, ast_party_caller::id, LOG_WARNING, MAX_CALLERID_SIZE, ast_party_id::name, NULL, ast_party_id::number, READ_SIZE, analog_pvt::redirecting_reason, send_callerid(), dahdi_pvt::sig_pvt, ast_party_name::str, and ast_party_number::str.

◆ my_set_alarm()

static void my_set_alarm ( void *  pvt,
int  in_alarm 
)
static

Definition at line 2076 of file chan_dahdi.c.

2077{
2078 struct dahdi_pvt *p = pvt;
2079
2080 p->inalarm = in_alarm;
2081}

References dahdi_pvt::inalarm.

◆ my_set_cadence()

static void my_set_cadence ( void *  pvt,
int *  cid_rings,
struct ast_channel ast 
)
static

Definition at line 2057 of file chan_dahdi.c.

2058{
2059 struct dahdi_pvt *p = pvt;
2060
2061 /* Choose proper cadence */
2062 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
2063 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
2064 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast_channel_name(ast), strerror(errno));
2065 *cid_rings = cidrings[p->distinctivering - 1];
2066 } else {
2067 if (p->distinctivering > 0) {
2068 ast_log(LOG_WARNING, "Cadence %d is not defined, falling back to default ring cadence\n", p->distinctivering);
2069 }
2070 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
2071 ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast_channel_name(ast), strerror(errno));
2072 *cid_rings = p->sendcalleridafter;
2073 }
2074}
int sendcalleridafter
Send caller ID on FXS after this many rings. Set to 1 for US.
Definition: chan_dahdi.h:734

References ast_channel_name(), ast_log, cadences, cidrings, dahdi_subchannel::dfd, dahdi_pvt::distinctivering, errno, LOG_WARNING, NULL, num_cadence, dahdi_pvt::sendcalleridafter, SUB_REAL, and dahdi_pvt::subs.

◆ my_set_callwaiting()

static void my_set_callwaiting ( void *  pvt,
int  callwaiting_enable 
)
static

Definition at line 2206 of file chan_dahdi.c.

2207{
2208 struct dahdi_pvt *p = pvt;
2209
2210 p->callwaiting = callwaiting_enable;
2211}

References dahdi_pvt::callwaiting.

◆ my_set_confirmanswer()

static void my_set_confirmanswer ( void *  pvt,
int  flag 
)
static

Definition at line 2190 of file chan_dahdi.c.

2191{
2192 struct dahdi_pvt *p = pvt;
2193 p->confirmanswer = flag;
2194}

References dahdi_pvt::confirmanswer.

◆ my_set_dialing()

static void my_set_dialing ( void *  pvt,
int  is_dialing 
)
static

Definition at line 2083 of file chan_dahdi.c.

2084{
2085 struct dahdi_pvt *p = pvt;
2086
2087 p->dialing = is_dialing;
2088}

References dahdi_pvt::dialing.

◆ my_set_echocanceller()

static int my_set_echocanceller ( void *  pvt,
int  enable 
)
static

Definition at line 2753 of file chan_dahdi.c.

2754{
2755 struct dahdi_pvt *p = pvt;
2756
2757 if (enable)
2758 dahdi_ec_enable(p);
2759 else
2761
2762 return 0;
2763}

References dahdi_ec_disable(), and dahdi_ec_enable().

◆ my_set_inthreeway()

static void my_set_inthreeway ( void *  pvt,
enum analog_sub  sub,
int  inthreeway 
)
static

Definition at line 2017 of file chan_dahdi.c.

2018{
2019 struct dahdi_pvt *p = pvt;
2020 int idx = analogsub_to_dahdisub(sub);
2021
2022 p->subs[idx].inthreeway = inthreeway;
2023}

References analogsub_to_dahdisub(), dahdi_subchannel::inthreeway, sub, and dahdi_pvt::subs.

◆ my_set_linear_mode()

static int my_set_linear_mode ( void *  pvt,
enum analog_sub  sub,
int  linear_mode 
)
static

Definition at line 2005 of file chan_dahdi.c.

2006{
2007 struct dahdi_pvt *p = pvt;
2008 int oldval;
2009 int idx = analogsub_to_dahdisub(sub);
2010
2011 dahdi_setlinear(p->subs[idx].dfd, linear_mode);
2012 oldval = p->subs[idx].linear;
2013 p->subs[idx].linear = linear_mode ? 1 : 0;
2014 return oldval;
2015}

References analogsub_to_dahdisub(), dahdi_setlinear(), dahdi_subchannel::dfd, dahdi_subchannel::linear, sub, and dahdi_pvt::subs.

◆ my_set_needringing()

static void my_set_needringing ( void *  pvt,
int  value 
)
static

Definition at line 2789 of file chan_dahdi.c.

2790{
2791 struct dahdi_pvt *p = pvt;
2793}

References dahdi_subchannel::needringing, SUB_REAL, dahdi_pvt::subs, and value.

◆ my_set_new_owner()

static void my_set_new_owner ( void *  pvt,
struct ast_channel new_owner 
)
static

Definition at line 2234 of file chan_dahdi.c.

2235{
2236 struct dahdi_pvt *p = pvt;
2237
2238 p->owner = new_owner;
2239}

References dahdi_pvt::owner.

◆ my_set_outgoing()

static void my_set_outgoing ( void *  pvt,
int  is_outgoing 
)
static

Definition at line 2090 of file chan_dahdi.c.

2091{
2092 struct dahdi_pvt *p = pvt;
2093
2094 p->outgoing = is_outgoing;
2095}

References dahdi_pvt::outgoing.

◆ my_set_polarity()

static void my_set_polarity ( void *  pvt,
int  value 
)
static

Definition at line 2795 of file chan_dahdi.c.

2796{
2797 struct dahdi_pvt *p = pvt;
2798
2799 if (p->channel == CHAN_PSEUDO) {
2800 return;
2801 }
2802 p->polarity = value;
2803 ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETPOLARITY, &value);
2804}

References CHAN_PSEUDO, dahdi_pvt::channel, dahdi_subchannel::dfd, dahdi_pvt::polarity, SUB_REAL, dahdi_pvt::subs, and value.

Referenced by my_answer_polarityswitch(), my_hangup_polarityswitch(), my_start_polarityswitch(), and polarity_write().

◆ my_set_pulsedial()

static void my_set_pulsedial ( void *  pvt,
int  flag 
)
static

Definition at line 2228 of file chan_dahdi.c.

2229{
2230 struct dahdi_pvt *p = pvt;
2231 p->pulsedial = flag;
2232}

References dahdi_pvt::pulsedial.

◆ my_set_ringtimeout()

static void my_set_ringtimeout ( void *  pvt,
int  ringt 
)
static

Definition at line 2133 of file chan_dahdi.c.

2134{
2135 struct dahdi_pvt *p = pvt;
2136 p->ringt = ringt;
2137}

References dahdi_pvt::ringt.

◆ my_set_waitingfordt()

static void my_set_waitingfordt ( void *  pvt,
struct ast_channel ast 
)
static

Definition at line 2139 of file chan_dahdi.c.

2140{
2141 struct dahdi_pvt *p = pvt;
2142
2143 /* We reset p->waitfordialtonetemp here, to prevent leaking to future calls,
2144 * but we also need to check against this value until we get dialtone
2145 * or the timer expires, since waitingfordt is when the timer started,
2146 * not when it should expire.
2147 *
2148 * Critically, we only set p->waitingfordt here if waitfordialtone or waitfordialtonetemp
2149 * has already been set, as waitingfordt is what is checked at runtime to determine
2150 * if we should be waiting for dial tone. This ensures that if a second call
2151 * is initiated concurrently, the first one "consumes" waitfordialtonetemp and resets it,
2152 * preventing leaking to other calls while remaining available to check on the first one while dialing.
2153 */
2155 p->waitfordialtonetemp = 0;
2156
2158 return;
2159 }
2160
2161 /* Because the DSP is allocated when the channel is created,
2162 * if we requested waitfordialtone later (in a predial handler),
2163 * we need to create it now */
2164 if (!p->dsp) {
2165 p->dsp = ast_dsp_new();
2166 if (!p->dsp) {
2167 ast_log(LOG_ERROR, "Unable to allocate DSP\n");
2168 return;
2169 }
2170 }
2173
2174 ast_debug(1, "Defer dialing for %dms or dialtone\n", p->waitfordialtoneduration);
2175 gettimeofday(&p->waitingfordt, NULL);
2177}
@ AST_STATE_OFFHOOK
Definition: channelstate.h:38

References ast_debug, ast_dsp_new(), ast_dsp_set_features(), ast_log, ast_setstate(), AST_STATE_OFFHOOK, CANPROGRESSDETECT, dahdi_pvt::dsp, DSP_FEATURE_WAITDIALTONE, dahdi_pvt::dsp_features, LOG_ERROR, NULL, dahdi_pvt::waitfordialtone, dahdi_pvt::waitfordialtoneduration, dahdi_pvt::waitfordialtonetemp, and dahdi_pvt::waitingfordt.

◆ my_start()

static int my_start ( void *  pvt)
static

Definition at line 2921 of file chan_dahdi.c.

2922{
2923 struct dahdi_pvt *p = pvt;
2924 int x = DAHDI_START;
2925
2926 return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
2927}

References dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.

◆ my_start_cid_detect()

static int my_start_cid_detect ( void *  pvt,
int  cid_signalling 
)
static

Definition at line 1396 of file chan_dahdi.c.

1397{
1398 struct dahdi_pvt *p = pvt;
1399 int index = SUB_REAL;
1401 if (!p->cs) {
1402 ast_log(LOG_ERROR, "Unable to alloc callerid\n");
1403 return -1;
1404 }
1405 bump_gains(p);
1406 dahdi_setlinear(p->subs[index].dfd, 0);
1407
1408 return 0;
1409}

References ast_log, bump_gains(), callerid_new(), dahdi_pvt::cid_signalling, dahdi_pvt::cs, dahdi_setlinear(), dahdi_subchannel::dfd, LOG_ERROR, SUB_REAL, and dahdi_pvt::subs.

◆ my_start_polarityswitch()

static void my_start_polarityswitch ( void *  pvt)
static

Definition at line 2806 of file chan_dahdi.c.

2807{
2808 struct dahdi_pvt *p = pvt;
2809
2811 my_set_polarity(pvt, 0);
2812 }
2813}

References dahdi_pvt::answeronpolarityswitch, dahdi_pvt::hanguponpolarityswitch, and my_set_polarity().

◆ my_stop_callwait()

static int my_stop_callwait ( void *  pvt)
static

Definition at line 1650 of file chan_dahdi.c.

1651{
1652 struct dahdi_pvt *p = pvt;
1653 p->callwaitingrepeat = 0;
1654 p->cidcwexpire = 0;
1655 p->cid_suppress_expire = 0;
1656
1657 return 0;
1658}

References dahdi_pvt::callwaitingrepeat, dahdi_pvt::cid_suppress_expire, and dahdi_pvt::cidcwexpire.

◆ my_stop_cid_detect()

static int my_stop_cid_detect ( void *  pvt)
static

Definition at line 1413 of file chan_dahdi.c.

1414{
1415 struct dahdi_pvt *p = pvt;
1416 int index = SUB_REAL;
1417
1418 if (p->cs) {
1419 callerid_free(p->cs);
1420 }
1421
1422 /* Restore linear mode after Caller*ID processing */
1423 dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
1424 restore_gains(p);
1425
1426 return 0;
1427}

References callerid_free(), dahdi_pvt::cs, dahdi_setlinear(), dahdi_subchannel::dfd, dahdi_subchannel::linear, restore_gains(), SUB_REAL, and dahdi_pvt::subs.

◆ my_swap_subchannels()

static void my_swap_subchannels ( void *  pvt,
enum analog_sub  a,
struct ast_channel ast_a,
enum analog_sub  b,
struct ast_channel ast_b 
)
static

Definition at line 2379 of file chan_dahdi.c.

2380{
2381 struct dahdi_pvt *p = pvt;
2382 int da, db;
2383 int tchan;
2384 int tinthreeway;
2385
2388
2389 tchan = p->subs[da].chan;
2390 p->subs[da].chan = p->subs[db].chan;
2391 p->subs[db].chan = tchan;
2392
2393 tinthreeway = p->subs[da].inthreeway;
2394 p->subs[da].inthreeway = p->subs[db].inthreeway;
2395 p->subs[db].inthreeway = tinthreeway;
2396
2397 p->subs[da].owner = ast_a;
2398 p->subs[db].owner = ast_b;
2399
2400 if (ast_a)
2401 ast_channel_set_fd(ast_a, 0, p->subs[da].dfd);
2402 if (ast_b)
2403 ast_channel_set_fd(ast_b, 0, p->subs[db].dfd);
2404
2405 wakeup_sub(p, a);
2406 wakeup_sub(p, b);
2407
2408 return;
2409}
static sqlite3 * db
static void wakeup_sub(struct dahdi_pvt *p, int a)
Definition: chan_dahdi.c:3740
static struct test_val b

References a, analogsub_to_dahdisub(), ast_channel_set_fd(), b, dahdi_subchannel::chan, db, dahdi_subchannel::dfd, dahdi_subchannel::inthreeway, dahdi_subchannel::owner, dahdi_pvt::subs, and wakeup_sub().

◆ my_train_echocanceller()

static int my_train_echocanceller ( void *  pvt)
static

Definition at line 2949 of file chan_dahdi.c.

2950{
2951 struct dahdi_pvt *p = pvt;
2952
2953 dahdi_train_ec(p);
2954
2955 return 0;
2956}

References dahdi_train_ec().

◆ my_unallocate_sub()

static int my_unallocate_sub ( void *  pvt,
enum analog_sub  analogsub 
)
static

Definition at line 2571 of file chan_dahdi.c.

2572{
2573 struct dahdi_pvt *p = pvt;
2574
2575 return unalloc_sub(p, analogsub_to_dahdisub(analogsub));
2576}

References analogsub_to_dahdisub(), and unalloc_sub().

◆ my_unlock_private()

static void my_unlock_private ( void *  pvt)
static

Definition at line 1897 of file chan_dahdi.c.

1898{
1899 struct dahdi_pvt *p = pvt;
1901}

References ast_mutex_unlock, and dahdi_pvt::lock.

◆ my_wait_event()

static int my_wait_event ( void *  pvt)
static

Definition at line 2703 of file chan_dahdi.c.

2704{
2705 struct dahdi_pvt *p = pvt;
2706
2707 return dahdi_wait_event(p->subs[SUB_REAL].dfd);
2708}

References dahdi_wait_event(), dahdi_subchannel::dfd, SUB_REAL, and dahdi_pvt::subs.

◆ my_wink()

static int my_wink ( void *  pvt,
enum analog_sub  sub 
)
static

Definition at line 1801 of file chan_dahdi.c.

1802{
1803 struct dahdi_pvt *p = pvt;
1804 int index = analogsub_to_dahdisub(sub);
1805 if (index != SUB_REAL) {
1806 ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n");
1807 }
1808 return dahdi_wink(p, index);
1809}

References analogsub_to_dahdisub(), ast_log, dahdi_wink(), LOG_ERROR, sub, and SUB_REAL.

◆ notify_message()

static void notify_message ( char *  mailbox,
int  thereornot 
)
static

Send MWI state change.

Parameters
mailboxThis is the mailbox associated with the FXO line that the MWI state has changed on.
thereornotThis argument should simply be set to 1 or 0, to indicate whether there are messages waiting or not.

This function does two things:

1) It generates an internal Asterisk event notifying any other module that cares about MWI that the state of a mailbox has changed.

2) It runs the script specified by the mwimonitornotify option to allow some custom handling of the state change.

Definition at line 3553 of file chan_dahdi.c.

3554{
3555 char s[sizeof(mwimonitornotify) + 164];
3556
3557 if (ast_strlen_zero(mailbox)) {
3558 return;
3559 }
3560
3561 ast_publish_mwi_state(mailbox, NULL, thereornot, thereornot);
3563 snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
3564 ast_safe_system(s);
3565 }
3566}
static char mwimonitornotify[PATH_MAX]
Definition: chan_dahdi.c:721
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: extconf.c:829
#define ast_publish_mwi_state(mailbox, context, new_msgs, old_msgs)
Publish a MWI state update via stasis.
Definition: mwi.h:378

References ast_publish_mwi_state, ast_safe_system(), ast_strlen_zero(), voicemailpwcheck::mailbox, mwimonitornotify, and NULL.

Referenced by handle_init_event(), mwi_thread(), and my_handle_notify_message().

◆ parse_buffers_policy()

static int parse_buffers_policy ( const char *  parse,
int *  num_buffers,
int *  policy 
)
static

Definition at line 7202 of file chan_dahdi.c.

7203{
7204 int res;
7205 char policy_str[21] = "";
7206
7207 if ((res = sscanf(parse, "%30d,%20s", num_buffers, policy_str)) != 2) {
7208 ast_log(LOG_WARNING, "Parsing buffer string '%s' failed.\n", parse);
7209 return 1;
7210 }
7211 if (*num_buffers < 0) {
7212 ast_log(LOG_WARNING, "Invalid buffer count given '%d'.\n", *num_buffers);
7213 return -1;
7214 }
7215 if (!strcasecmp(policy_str, "full")) {
7216 *policy = DAHDI_POLICY_WHEN_FULL;
7217 } else if (!strcasecmp(policy_str, "immediate")) {
7218 *policy = DAHDI_POLICY_IMMEDIATE;
7219#if defined(HAVE_DAHDI_HALF_FULL)
7220 } else if (!strcasecmp(policy_str, "half")) {
7221 *policy = DAHDI_POLICY_HALF_FULL;
7222#endif
7223 } else {
7224 ast_log(LOG_WARNING, "Invalid policy name given '%s'.\n", policy_str);
7225 return -1;
7226 }
7227
7228 return 0;
7229}

References ast_log, and LOG_WARNING.

Referenced by dahdi_func_write(), and process_dahdi().

◆ parse_busy_pattern()

static void parse_busy_pattern ( struct ast_variable v,
struct ast_dsp_busy_pattern busy_cadence 
)
static

Definition at line 18436 of file chan_dahdi.c.

18437{
18438 int count_pattern = 0;
18439 int norval = 0;
18440 char *temp = NULL;
18441
18442 for (; ;) {
18443 /* Scans the string for the next value in the pattern. If none, it checks to see if any have been entered so far. */
18444 if (!sscanf(v->value, "%30d", &norval) && count_pattern == 0) {
18445 ast_log(LOG_ERROR, "busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->lineno);
18446 break;
18447 }
18448
18449 busy_cadence->pattern[count_pattern] = norval;
18450
18451 count_pattern++;
18452 if (count_pattern == 4) {
18453 break;
18454 }
18455
18456 temp = strchr(v->value, ',');
18457 if (temp == NULL) {
18458 break;
18459 }
18460 v->value = temp + 1;
18461 }
18462 busy_cadence->length = count_pattern;
18463
18464 if (count_pattern % 2 != 0) {
18465 /* The pattern length must be divisible by two */
18466 ast_log(LOG_ERROR, "busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->lineno);
18467 }
18468
18469}
int pattern[4]
Definition: dsp.h:68

References ast_log, ast_dsp_busy_pattern::length, ast_variable::lineno, LOG_ERROR, NULL, ast_dsp_busy_pattern::pattern, and ast_variable::value.

Referenced by process_dahdi().

◆ polarity_read()

static int polarity_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buffer,
size_t  buflen 
)
static

Definition at line 2874 of file chan_dahdi.c.

2875{
2876 struct dahdi_pvt *pvt;
2877
2878 pvt = fxo_pvt(chan);
2879 if (!pvt) {
2880 return -1;
2881 }
2882
2883 snprintf(buffer, buflen, "%d", pvt->polarity);
2884
2885 return 0;
2886}
static struct dahdi_pvt * fxo_pvt(struct ast_channel *chan)
Return DAHDI pivot if channel is FXO signalled.
Definition: chan_dahdi.c:2842

References fxo_pvt(), and dahdi_pvt::polarity.

◆ polarity_write()

static int polarity_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)
static

Definition at line 2888 of file chan_dahdi.c.

2889{
2890 struct dahdi_pvt *pvt;
2891 int polarity;
2892
2893 pvt = fxo_pvt(chan);
2894 if (!pvt) {
2895 return -1;
2896 }
2897
2898 if (!strcasecmp(value, "idle")) {
2900 } else if (!strcasecmp(value, "reverse")) {
2902 } else {
2903 polarity = atoi(value);
2904 }
2905
2907 ast_log(LOG_WARNING, "Invalid polarity: '%s'\n", value);
2908 return -1;
2909 }
2910
2912 return 0;
2913}

References ast_log, fxo_pvt(), LOG_WARNING, my_set_polarity(), dahdi_pvt::polarity, POLARITY_IDLE, POLARITY_REV, and value.

◆ process_dahdi()

static int process_dahdi ( struct dahdi_chan_conf confp,
const char *  cat,
struct ast_variable v,
int  reload,
int  options 
)
static

Definition at line 18471 of file chan_dahdi.c.

18472{
18473 struct dahdi_pvt *tmp;
18474 int y;
18475 struct ast_variable *dahdichan = NULL;
18476
18477 /* Re-parse any cadences from beginning, rather than appending until we run out of room */
18479
18480 for (; v; v = v->next) {
18482 continue;
18483
18484 /* Create the interface list */
18485 if (!strcasecmp(v->name, "channel") || !strcasecmp(v->name, "channels")) {
18487 ast_log(LOG_WARNING, "Channel '%s' ignored.\n", v->value);
18488 continue;
18489 }
18490 if (build_channels(confp, v->value, reload, v->lineno)) {
18491 if (confp->ignore_failed_channels) {
18492 ast_log(LOG_WARNING, "Channel '%s' failure ignored: ignore_failed_channels.\n", v->value);
18493 continue;
18494 } else {
18495 return -1;
18496 }
18497 }
18498 ast_debug(1, "Channel '%s' configured.\n", v->value);
18499 } else if (!strcasecmp(v->name, "ignore_failed_channels")) {
18501 } else if (!strcasecmp(v->name, "buffers")) {
18502 if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) {
18503 ast_log(LOG_WARNING, "Using default buffer policy.\n");
18504 confp->chan.buf_no = numbufs;
18505 confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE;
18506 }
18507 } else if (!strcasecmp(v->name, "faxbuffers")) {
18508 if (!parse_buffers_policy(v->value, &confp->chan.faxbuf_no, &confp->chan.faxbuf_policy)) {
18509 confp->chan.usefaxbuffers = 1;
18510 }
18511 } else if (!strcasecmp(v->name, "dahdichan")) {
18512 /* Only process the last dahdichan value. */
18513 dahdichan = v;
18514 } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
18516 } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
18518 } else if (!strcasecmp(v->name, "dring1context")) {
18520 } else if (!strcasecmp(v->name, "dring2context")) {
18522 } else if (!strcasecmp(v->name, "dring3context")) {
18524 } else if (!strcasecmp(v->name, "dring1range")) {
18525 confp->chan.drings.ringnum[0].range = atoi(v->value);
18526 } else if (!strcasecmp(v->name, "dring2range")) {
18527 confp->chan.drings.ringnum[1].range = atoi(v->value);
18528 } else if (!strcasecmp(v->name, "dring3range")) {
18529 confp->chan.drings.ringnum[2].range = atoi(v->value);
18530 } else if (!strcasecmp(v->name, "dring1")) {
18531 sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[0].ring[0], &confp->chan.drings.ringnum[0].ring[1], &confp->chan.drings.ringnum[0].ring[2]);
18532 } else if (!strcasecmp(v->name, "dring2")) {
18533 sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[1].ring[0], &confp->chan.drings.ringnum[1].ring[1], &confp->chan.drings.ringnum[1].ring[2]);
18534 } else if (!strcasecmp(v->name, "dring3")) {
18535 sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[2].ring[0], &confp->chan.drings.ringnum[2].ring[1], &confp->chan.drings.ringnum[2].ring[2]);
18536 } else if (!strcasecmp(v->name, "usecallerid")) {
18537 confp->chan.use_callerid = ast_true(v->value);
18538 } else if (!strcasecmp(v->name, "cidsignalling")) {
18539 if (!strcasecmp(v->value, "bell"))
18541 else if (!strcasecmp(v->value, "v23"))
18543 else if (!strcasecmp(v->value, "dtmf"))
18545 else if (!strcasecmp(v->value, "smdi"))
18547 else if (!strcasecmp(v->value, "v23_jp"))
18549 else if (ast_true(v->value))
18551 } else if (!strcasecmp(v->name, "cidstart")) {
18552 if (!strcasecmp(v->value, "ring"))
18553 confp->chan.cid_start = CID_START_RING;
18554 else if (!strcasecmp(v->value, "polarity_in"))
18556 else if (!strcasecmp(v->value, "polarity"))
18558 else if (!strcasecmp(v->value, "dtmf"))
18560 else if (ast_true(v->value))
18561 confp->chan.cid_start = CID_START_RING;
18562 } else if (!strcasecmp(v->name, "threewaycalling")) {
18563 confp->chan.threewaycalling = ast_true(v->value);
18564 } else if (!strcasecmp(v->name, "threewaysilenthold")) {
18566 } else if (!strcasecmp(v->name, "cancallforward")) {
18567 confp->chan.cancallforward = ast_true(v->value);
18568 } else if (!strcasecmp(v->name, "relaxdtmf")) {
18569 if (ast_true(v->value))
18571 else
18572 confp->chan.dtmfrelax = 0;
18573 } else if (!strcasecmp(v->name, "mailbox")) {
18574 ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
18575 } else if (!strcasecmp(v->name, "description")) {
18576 ast_copy_string(confp->chan.description, v->value, sizeof(confp->chan.description));
18577 } else if (!strcasecmp(v->name, "hasvoicemail")) {
18578 if (ast_true(v->value) && ast_strlen_zero(confp->chan.mailbox)) {
18579 /*
18580 * hasvoicemail is a users.conf legacy voicemail enable method.
18581 * hasvoicemail is only going to work for app_voicemail mailboxes.
18582 */
18583 if (strchr(cat, '@')) {
18584 ast_copy_string(confp->chan.mailbox, cat, sizeof(confp->chan.mailbox));
18585 } else {
18586 snprintf(confp->chan.mailbox, sizeof(confp->chan.mailbox),
18587 "%s@default", cat);
18588 }
18589 }
18590 } else if (!strcasecmp(v->name, "adsi")) {
18591 confp->chan.adsi = ast_true(v->value);
18592 } else if (!strcasecmp(v->name, "usesmdi")) {
18593 confp->chan.use_smdi = ast_true(v->value);
18594 } else if (!strcasecmp(v->name, "smdiport")) {
18595 ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
18596 } else if (!strcasecmp(v->name, "transfer")) {
18597 confp->chan.transfer = ast_true(v->value);
18598 } else if (!strcasecmp(v->name, "canpark")) {
18599 confp->chan.canpark = ast_true(v->value);
18600 } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
18601 confp->chan.echocanbridged = ast_true(v->value);
18602 } else if (!strcasecmp(v->name, "busydetect")) {
18603 confp->chan.busydetect = ast_true(v->value);
18604 } else if (!strcasecmp(v->name, "busycount")) {
18605 confp->chan.busycount = atoi(v->value);
18606 } else if (!strcasecmp(v->name, "busypattern")) {
18608 } else if (!strcasecmp(v->name, "calledsubscriberheld")) {
18610 } else if (!strcasecmp(v->name, "callprogress")) {
18611 confp->chan.callprogress &= ~CALLPROGRESS_PROGRESS;
18612 if (ast_true(v->value))
18614 } else if (!strcasecmp(v->name, "waitfordialtone")) {
18615 confp->chan.waitfordialtone = atoi(v->value);
18616 } else if (!strcasecmp(v->name, "dialtone_detect")) {
18617 if (!strcasecmp(v->value, "always")) {
18618 confp->chan.dialtone_detect = -1;
18619 } else if (ast_true(v->value)) {
18621 } else if (ast_false(v->value)) {
18622 confp->chan.dialtone_detect = 0;
18623 } else {
18624 confp->chan.dialtone_detect = ast_strlen_zero(v->value) ? 0 : (8 * atoi(v->value)) / READ_SIZE;
18625 }
18626 } else if (!strcasecmp(v->name, "faxdetect")) {
18627 confp->chan.callprogress &= ~CALLPROGRESS_FAX;
18628 if (!strcasecmp(v->value, "incoming")) {
18630 } else if (!strcasecmp(v->value, "outgoing")) {
18632 } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
18634 } else if (!strcasecmp(v->name, "faxdetect_timeout")) {
18635 if (sscanf(v->value, "%30u", &confp->chan.faxdetect_timeout) != 1) {
18636 confp->chan.faxdetect_timeout = 0;
18637 }
18638 } else if (!strcasecmp(v->name, "firstdigit_timeout")) {
18639 if (sscanf(v->value, "%30d", &confp->chan.firstdigit_timeout) != 1
18640 || confp->chan.firstdigit_timeout <= 0) {
18642 }
18643 } else if (!strcasecmp(v->name, "interdigit_timeout")) {
18644 if (sscanf(v->value, "%30d", &confp->chan.interdigit_timeout) != 1
18645 || confp->chan.interdigit_timeout <= 0) {
18647 }
18648 } else if (!strcasecmp(v->name, "matchdigit_timeout")) {
18649 if (sscanf(v->value, "%30d", &confp->chan.matchdigit_timeout) != 1
18650 || confp->chan.matchdigit_timeout <= 0) {
18652 }
18653 } else if (!strcasecmp(v->name, "echocancel")) {
18654 process_echocancel(confp, v->value, v->lineno);
18655 } else if (!strcasecmp(v->name, "echotraining")) {
18656 if (sscanf(v->value, "%30d", &y) == 1) {
18657 if ((y < 10) || (y > 4000)) {
18658 ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d.\n", v->lineno);
18659 } else {
18660 confp->chan.echotraining = y;
18661 }
18662 } else if (ast_true(v->value)) {
18663 confp->chan.echotraining = 400;
18664 } else
18665 confp->chan.echotraining = 0;
18666 } else if (!strcasecmp(v->name, "hidecallerid")) {
18667 confp->chan.hidecallerid = ast_true(v->value);
18668 } else if (!strcasecmp(v->name, "hidecalleridname")) {
18669 confp->chan.hidecalleridname = ast_true(v->value);
18670 } else if (!strcasecmp(v->name, "pulsedial")) {
18671 confp->chan.pulse = ast_true(v->value);
18672 } else if (!strcasecmp(v->name, "callreturn")) {
18673 confp->chan.callreturn = ast_true(v->value);
18674 } else if (!strcasecmp(v->name, "callwaiting")) {
18675 confp->chan.callwaiting = ast_true(v->value);
18676 } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
18678 } else if (!strcasecmp(v->name, "context")) {
18679 ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
18680 } else if (!strcasecmp(v->name, "language")) {
18681 ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
18682 } else if (!strcasecmp(v->name, "progzone")) {
18683 ast_copy_string(progzone, v->value, sizeof(progzone));
18684 } else if (!strcasecmp(v->name, "mohinterpret")
18685 ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
18686 ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
18687 } else if (!strcasecmp(v->name, "mohsuggest")) {
18688 ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
18689 } else if (!strcasecmp(v->name, "parkinglot")) {
18690 ast_copy_string(confp->chan.parkinglot, v->value, sizeof(confp->chan.parkinglot));
18691 } else if (!strcasecmp(v->name, "stripmsd")) {
18692 ast_log(LOG_NOTICE, "Configuration option \"%s\" has been deprecated. Please use dialplan instead\n", v->name);
18693 confp->chan.stripmsd = atoi(v->value);
18694 } else if (!strcasecmp(v->name, "jitterbuffers")) {
18695 numbufs = atoi(v->value);
18696 } else if (!strcasecmp(v->name, "group")) {
18697 confp->chan.group = ast_get_group(v->value);
18698 } else if (!strcasecmp(v->name, "callgroup")) {
18699 if (!((confp->chan.sig == SIG_FXOKS) || (confp->chan.sig == SIG_FXOGS) || (confp->chan.sig == SIG_FXOLS))) {
18700 ast_log(LOG_WARNING, "Only FXO signalled channels may belong to a call group\n");
18701 }
18702 if (!strcasecmp(v->value, "none"))
18703 confp->chan.callgroup = 0;
18704 else
18705 confp->chan.callgroup = ast_get_group(v->value);
18706 } else if (!strcasecmp(v->name, "pickupgroup")) {
18707 if (!((confp->chan.sig == SIG_FXOKS) || (confp->chan.sig == SIG_FXOGS) || (confp->chan.sig == SIG_FXOLS))) {
18708 ast_log(LOG_WARNING, "Only FXO signalled channels may belong to a pickup group\n");
18709 }
18710 if (!strcasecmp(v->value, "none"))
18711 confp->chan.pickupgroup = 0;
18712 else
18713 confp->chan.pickupgroup = ast_get_group(v->value);
18714 } else if (!strcasecmp(v->name, "namedcallgroup")) {
18715 if (!((confp->chan.sig == SIG_FXOKS) || (confp->chan.sig == SIG_FXOGS) || (confp->chan.sig == SIG_FXOLS))) {
18716 ast_log(LOG_WARNING, "Only FXO signalled channels may belong to a named call group\n");
18717 }
18719 } else if (!strcasecmp(v->name, "namedpickupgroup")) {
18720 if (!((confp->chan.sig == SIG_FXOKS) || (confp->chan.sig == SIG_FXOGS) || (confp->chan.sig == SIG_FXOLS))) {
18721 ast_log(LOG_WARNING, "Only FXO signalled channels may belong to a named pickup group\n");
18722 }
18724 } else if (!strcasecmp(v->name, "setvar")) {
18725 if (v->value) {
18726 char *varval = NULL;
18727 struct ast_variable *tmpvar;
18728 char varname[strlen(v->value) + 1];
18729 strcpy(varname, v->value); /* safe */
18730 if ((varval = strchr(varname, '='))) {
18731 *varval++ = '\0';
18732 if ((tmpvar = ast_variable_new(varname, varval, ""))) {
18733 if (ast_variable_list_replace(&confp->chan.vars, tmpvar)) {
18734 tmpvar->next = confp->chan.vars;
18735 confp->chan.vars = tmpvar;
18736 }
18737 }
18738 }
18739 }
18740 } else if (!strcasecmp(v->name, "immediate")) {
18741 confp->chan.immediate = ast_true(v->value);
18742 } else if (!strcasecmp(v->name, "immediatering")) {
18743 confp->chan.immediatering = ast_true(v->value);
18744 } else if (!strcasecmp(v->name, "transfertobusy")) {
18745 confp->chan.transfertobusy = ast_true(v->value);
18746 } else if (!strcasecmp(v->name, "dialmode")) {
18747 if (!strcasecmp(v->value, "pulse")) {
18749 } else if (!strcasecmp(v->value, "dtmf") || !strcasecmp(v->value, "tone")) {
18751 } else if (!strcasecmp(v->value, "none")) {
18753 } else {
18755 }
18756 } else if (!strcasecmp(v->name, "mwimonitor")) {
18757 confp->chan.mwimonitor_neon = 0;
18758 confp->chan.mwimonitor_fsk = 0;
18759 confp->chan.mwimonitor_rpas = 0;
18760 if (strcasestr(v->value, "fsk")) {
18761 confp->chan.mwimonitor_fsk = 1;
18762 }
18763 if (strcasestr(v->value, "rpas")) {
18764 confp->chan.mwimonitor_rpas = 1;
18765 }
18766 if (strcasestr(v->value, "neon")) {
18767 confp->chan.mwimonitor_neon = 1;
18768 }
18769 /* If set to true or yes, assume that simple fsk is desired */
18770 if (ast_true(v->value)) {
18771 confp->chan.mwimonitor_fsk = 1;
18772 }
18773 } else if (!strcasecmp(v->name, "hwrxgain")) {
18774 confp->chan.hwrxgain_enabled = 0;
18775 if (strcasecmp(v->value, "disabled")) {
18776 if (sscanf(v->value, "%30f", &confp->chan.hwrxgain) == 1) {
18777 confp->chan.hwrxgain_enabled = 1;
18778 } else {
18779 ast_log(LOG_WARNING, "Invalid hwrxgain: %s at line %d.\n", v->value, v->lineno);
18780 }
18781 }
18782 } else if (!strcasecmp(v->name, "hwtxgain")) {
18783 confp->chan.hwtxgain_enabled = 0;
18784 if (strcasecmp(v->value, "disabled")) {
18785 if (sscanf(v->value, "%30f", &confp->chan.hwtxgain) == 1) {
18786 confp->chan.hwtxgain_enabled = 1;
18787 } else {
18788 ast_log(LOG_WARNING, "Invalid hwtxgain: %s at line %d.\n", v->value, v->lineno);
18789 }
18790 }
18791 } else if (!strcasecmp(v->name, "cid_rxgain")) {
18792 if (sscanf(v->value, "%30f", &confp->chan.cid_rxgain) != 1) {
18793 ast_log(LOG_WARNING, "Invalid cid_rxgain: %s at line %d.\n", v->value, v->lineno);
18794 }
18795 } else if (!strcasecmp(v->name, "rxgain")) {
18796 if (sscanf(v->value, "%30f", &confp->chan.rxgain) != 1) {
18797 ast_log(LOG_WARNING, "Invalid rxgain: %s at line %d.\n", v->value, v->lineno);
18798 }
18799 } else if (!strcasecmp(v->name, "txgain")) {
18800 if (sscanf(v->value, "%30f", &confp->chan.txgain) != 1) {
18801 ast_log(LOG_WARNING, "Invalid txgain: %s at line %d.\n", v->value, v->lineno);
18802 }
18803 } else if (!strcasecmp(v->name, "txdrc")) {
18804 if (sscanf(v->value, "%f", &confp->chan.txdrc) != 1) {
18805 ast_log(LOG_WARNING, "Invalid txdrc: %s\n", v->value);
18806 }
18807 } else if (!strcasecmp(v->name, "rxdrc")) {
18808 if (sscanf(v->value, "%f", &confp->chan.rxdrc) != 1) {
18809 ast_log(LOG_WARNING, "Invalid rxdrc: %s\n", v->value);
18810 }
18811 } else if (!strcasecmp(v->name, "tonezone")) {
18812 if (sscanf(v->value, "%30d", &confp->chan.tonezone) != 1) {
18813 ast_log(LOG_WARNING, "Invalid tonezone: %s at line %d.\n", v->value, v->lineno);
18814 }
18815 } else if (!strcasecmp(v->name, "callerid")) {
18816 if (!strcasecmp(v->value, "asreceived")) {
18817 confp->chan.cid_num[0] = '\0';
18818 confp->chan.cid_name[0] = '\0';
18819 } else {
18820 ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
18821 }
18822 } else if (!strcasecmp(v->name, "fullname")) {
18823 ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
18824 } else if (!strcasecmp(v->name, "cid_number")) {
18825 ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
18826 } else if (!strcasecmp(v->name, "cid_tag")) {
18827 ast_copy_string(confp->chan.cid_tag, v->value, sizeof(confp->chan.cid_tag));
18828 } else if (!strcasecmp(v->name, "useincomingcalleridondahditransfer")) {
18829 confp->chan.dahditrcallerid = ast_true(v->value);
18830 } else if (!strcasecmp(v->name, "restrictcid")) {
18831 confp->chan.restrictcid = ast_true(v->value);
18832 } else if (!strcasecmp(v->name, "usecallingpres")) {
18833 confp->chan.use_callingpres = ast_true(v->value);
18834 } else if (!strcasecmp(v->name, "accountcode")) {
18835 ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
18836 } else if (!strcasecmp(v->name, "amaflags")) {
18838 if (y < 0)
18839 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d.\n", v->value, v->lineno);
18840 else
18841 confp->chan.amaflags = y;
18842 } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
18843 confp->chan.polarityonanswerdelay = atoi(v->value);
18844 } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
18846 } else if (!strcasecmp(v->name, "ani_info_digits")) {
18847 confp->chan.ani_info_digits = atoi(v->value);
18848 } else if (!strcasecmp(v->name, "ani_wink_time")) {
18849 confp->chan.ani_wink_time = atoi(v->value);
18850 } else if (!strcasecmp(v->name, "ani_timeout")) {
18851 confp->chan.ani_timeout = atoi(v->value);
18852 } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
18854 } else if (!strcasecmp(v->name, "autoreoriginate")) {
18855 confp->chan.reoriginate = ast_true(v->value);
18856 } else if (!strcasecmp(v->name, "sendcalleridafter")) {
18857 confp->chan.sendcalleridafter = atoi(v->value);
18858 } else if (!strcasecmp(v->name, "mwimonitornotify")) {
18860 } else if (ast_cc_is_config_param(v->name)) {
18861 ast_cc_set_param(confp->chan.cc_params, v->name, v->value);
18862 } else if (!strcasecmp(v->name, "mwisendtype")) {
18863#ifndef HAVE_DAHDI_LINEREVERSE_VMWI /* backward compatibility for older dahdi VMWI implementation */
18864 if (!strcasecmp(v->value, "rpas")) { /* Ring Pulse Alert Signal */
18865 mwisend_rpas = 1;
18866 } else {
18867 mwisend_rpas = 0;
18868 }
18869#else
18870 /* Default is fsk, to turn it off you must specify nofsk */
18871 memset(&confp->chan.mwisend_setting, 0, sizeof(confp->chan.mwisend_setting));
18872 if (strcasestr(v->value, "nofsk")) { /* NoFSK */
18873 confp->chan.mwisend_fsk = 0;
18874 } else { /* Default FSK */
18875 confp->chan.mwisend_fsk = 1;
18876 }
18877 if (strcasestr(v->value, "rpas")) { /* Ring Pulse Alert Signal, normally followed by FSK */
18878 confp->chan.mwisend_rpas = 1;
18879 } else {
18880 confp->chan.mwisend_rpas = 0;
18881 }
18882 if (strcasestr(v->value, "lrev")) { /* Line Reversal */
18883 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV;
18884 }
18885 if (strcasestr(v->value, "hvdc")) { /* HV 90VDC */
18886 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC;
18887 }
18888 if ( (strcasestr(v->value, "neon")) || (strcasestr(v->value, "hvac")) ) { /* 90V DC pulses */
18889 confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC;
18890 }
18891#endif
18892 } else if (reload != 1) {
18893 if (!strcasecmp(v->name, "signalling") || !strcasecmp(v->name, "signaling")) {
18894 int orig_radio = confp->chan.radio;
18895 int orig_outsigmod = confp->chan.outsigmod;
18896 int orig_auto = confp->is_sig_auto;
18897
18898 confp->chan.radio = 0;
18899 confp->chan.outsigmod = -1;
18900 confp->is_sig_auto = 0;
18901 if (!strcasecmp(v->value, "em")) {
18902 confp->chan.sig = SIG_EM;
18903 } else if (!strcasecmp(v->value, "em_e1")) {
18904 confp->chan.sig = SIG_EM_E1;
18905 } else if (!strcasecmp(v->value, "em_w")) {
18906 confp->chan.sig = SIG_EMWINK;
18907 } else if (!strcasecmp(v->value, "fxs_ls")) {
18908 confp->chan.sig = SIG_FXSLS;
18909 } else if (!strcasecmp(v->value, "fxs_gs")) {
18910 confp->chan.sig = SIG_FXSGS;
18911 } else if (!strcasecmp(v->value, "fxs_ks")) {
18912 confp->chan.sig = SIG_FXSKS;
18913 } else if (!strcasecmp(v->value, "fxo_ls")) {
18914 confp->chan.sig = SIG_FXOLS;
18915 } else if (!strcasecmp(v->value, "fxo_gs")) {
18916 confp->chan.sig = SIG_FXOGS;
18917 } else if (!strcasecmp(v->value, "fxo_ks")) {
18918 confp->chan.sig = SIG_FXOKS;
18919 } else if (!strcasecmp(v->value, "fxs_rx")) {
18920 confp->chan.sig = SIG_FXSKS;
18921 confp->chan.radio = 1;
18922 } else if (!strcasecmp(v->value, "fxo_rx")) {
18923 confp->chan.sig = SIG_FXOLS;
18924 confp->chan.radio = 1;
18925 } else if (!strcasecmp(v->value, "fxs_tx")) {
18926 confp->chan.sig = SIG_FXSLS;
18927 confp->chan.radio = 1;
18928 } else if (!strcasecmp(v->value, "fxo_tx")) {
18929 confp->chan.sig = SIG_FXOGS;
18930 confp->chan.radio = 1;
18931 } else if (!strcasecmp(v->value, "em_rx")) {
18932 confp->chan.sig = SIG_EM;
18933 confp->chan.radio = 1;
18934 } else if (!strcasecmp(v->value, "em_tx")) {
18935 confp->chan.sig = SIG_EM;
18936 confp->chan.radio = 1;
18937 } else if (!strcasecmp(v->value, "em_rxtx")) {
18938 confp->chan.sig = SIG_EM;
18939 confp->chan.radio = 2;
18940 } else if (!strcasecmp(v->value, "em_txrx")) {
18941 confp->chan.sig = SIG_EM;
18942 confp->chan.radio = 2;
18943 } else if (!strcasecmp(v->value, "sf")) {
18944 confp->chan.sig = SIG_SF;
18945 } else if (!strcasecmp(v->value, "sf_w")) {
18946 confp->chan.sig = SIG_SFWINK;
18947 } else if (!strcasecmp(v->value, "sf_featd")) {
18948 confp->chan.sig = SIG_FEATD;
18949 } else if (!strcasecmp(v->value, "sf_featdmf")) {
18950 confp->chan.sig = SIG_FEATDMF;
18951 } else if (!strcasecmp(v->value, "sf_featb")) {
18952 confp->chan.sig = SIG_SF_FEATB;
18953 } else if (!strcasecmp(v->value, "sf")) {
18954 confp->chan.sig = SIG_SF;
18955 } else if (!strcasecmp(v->value, "sf_rx")) {
18956 confp->chan.sig = SIG_SF;
18957 confp->chan.radio = 1;
18958 } else if (!strcasecmp(v->value, "sf_tx")) {
18959 confp->chan.sig = SIG_SF;
18960 confp->chan.radio = 1;
18961 } else if (!strcasecmp(v->value, "sf_rxtx")) {
18962 confp->chan.sig = SIG_SF;
18963 confp->chan.radio = 2;
18964 } else if (!strcasecmp(v->value, "sf_txrx")) {
18965 confp->chan.sig = SIG_SF;
18966 confp->chan.radio = 2;
18967 } else if (!strcasecmp(v->value, "featd")) {
18968 confp->chan.sig = SIG_FEATD;
18969 } else if (!strcasecmp(v->value, "featdmf")) {
18970 confp->chan.sig = SIG_FEATDMF;
18971 } else if (!strcasecmp(v->value, "featdmf_ta")) {
18972 confp->chan.sig = SIG_FEATDMF_TA;
18973 } else if (!strcasecmp(v->value, "e911")) {
18974 confp->chan.sig = SIG_E911;
18975 } else if (!strcasecmp(v->value, "fgccama")) {
18976 confp->chan.sig = SIG_FGC_CAMA;
18977 } else if (!strcasecmp(v->value, "fgccamamf")) {
18978 confp->chan.sig = SIG_FGC_CAMAMF;
18979 } else if (!strcasecmp(v->value, "featb")) {
18980 confp->chan.sig = SIG_FEATB;
18981#ifdef HAVE_PRI
18982 } else if (!strcasecmp(v->value, "pri_net")) {
18983 confp->chan.sig = SIG_PRI;
18984 confp->pri.pri.nodetype = PRI_NETWORK;
18985 } else if (!strcasecmp(v->value, "pri_cpe")) {
18986 confp->chan.sig = SIG_PRI;
18987 confp->pri.pri.nodetype = PRI_CPE;
18988 } else if (!strcasecmp(v->value, "bri_cpe")) {
18989 confp->chan.sig = SIG_BRI;
18990 confp->pri.pri.nodetype = PRI_CPE;
18991 } else if (!strcasecmp(v->value, "bri_net")) {
18992 confp->chan.sig = SIG_BRI;
18993 confp->pri.pri.nodetype = PRI_NETWORK;
18994 } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) {
18995 confp->chan.sig = SIG_BRI_PTMP;
18996 confp->pri.pri.nodetype = PRI_CPE;
18997 } else if (!strcasecmp(v->value, "bri_net_ptmp")) {
18998#if defined(HAVE_PRI_CALL_HOLD)
18999 confp->chan.sig = SIG_BRI_PTMP;
19000 confp->pri.pri.nodetype = PRI_NETWORK;
19001#else
19002 ast_log(LOG_WARNING, "How cool would it be if someone implemented this mode! For now, sucks for you. (line %d)\n", v->lineno);
19003#endif /* !defined(HAVE_PRI_CALL_HOLD) */
19004#endif
19005#if defined(HAVE_SS7)
19006 } else if (!strcasecmp(v->value, "ss7")) {
19007 confp->chan.sig = SIG_SS7;
19008#endif /* defined(HAVE_SS7) */
19009#ifdef HAVE_OPENR2
19010 } else if (!strcasecmp(v->value, "mfcr2")) {
19011 confp->chan.sig = SIG_MFCR2;
19012#endif
19013 } else if (!strcasecmp(v->value, "auto")) {
19014 confp->is_sig_auto = 1;
19015 } else {
19016 confp->chan.outsigmod = orig_outsigmod;
19017 confp->chan.radio = orig_radio;
19018 confp->is_sig_auto = orig_auto;
19019 ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno);
19020 }
19021 } else if (!strcasecmp(v->name, "outsignalling") || !strcasecmp(v->name, "outsignaling")) {
19022 if (!strcasecmp(v->value, "em")) {
19023 confp->chan.outsigmod = SIG_EM;
19024 } else if (!strcasecmp(v->value, "em_e1")) {
19025 confp->chan.outsigmod = SIG_EM_E1;
19026 } else if (!strcasecmp(v->value, "em_w")) {
19027 confp->chan.outsigmod = SIG_EMWINK;
19028 } else if (!strcasecmp(v->value, "sf")) {
19029 confp->chan.outsigmod = SIG_SF;
19030 } else if (!strcasecmp(v->value, "sf_w")) {
19031 confp->chan.outsigmod = SIG_SFWINK;
19032 } else if (!strcasecmp(v->value, "sf_featd")) {
19033 confp->chan.outsigmod = SIG_FEATD;
19034 } else if (!strcasecmp(v->value, "sf_featdmf")) {
19035 confp->chan.outsigmod = SIG_FEATDMF;
19036 } else if (!strcasecmp(v->value, "sf_featb")) {
19037 confp->chan.outsigmod = SIG_SF_FEATB;
19038 } else if (!strcasecmp(v->value, "sf")) {
19039 confp->chan.outsigmod = SIG_SF;
19040 } else if (!strcasecmp(v->value, "featd")) {
19041 confp->chan.outsigmod = SIG_FEATD;
19042 } else if (!strcasecmp(v->value, "featdmf")) {
19043 confp->chan.outsigmod = SIG_FEATDMF;
19044 } else if (!strcasecmp(v->value, "featdmf_ta")) {
19045 confp->chan.outsigmod = SIG_FEATDMF_TA;
19046 } else if (!strcasecmp(v->value, "e911")) {
19047 confp->chan.outsigmod = SIG_E911;
19048 } else if (!strcasecmp(v->value, "fgccama")) {
19049 confp->chan.outsigmod = SIG_FGC_CAMA;
19050 } else if (!strcasecmp(v->value, "fgccamamf")) {
19051 confp->chan.outsigmod = SIG_FGC_CAMAMF;
19052 } else if (!strcasecmp(v->value, "featb")) {
19053 confp->chan.outsigmod = SIG_FEATB;
19054 } else {
19055 ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno);
19056 }
19057#ifdef HAVE_PRI
19058 } else if (!strcasecmp(v->name, "pridialplan")) {
19059 if (!strcasecmp(v->value, "national")) {
19060 confp->pri.pri.dialplan = PRI_NATIONAL_ISDN + 1;
19061 } else if (!strcasecmp(v->value, "unknown")) {
19062 confp->pri.pri.dialplan = PRI_UNKNOWN + 1;
19063 } else if (!strcasecmp(v->value, "private")) {
19064 confp->pri.pri.dialplan = PRI_PRIVATE + 1;
19065 } else if (!strcasecmp(v->value, "international")) {
19066 confp->pri.pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
19067 } else if (!strcasecmp(v->value, "local")) {
19068 confp->pri.pri.dialplan = PRI_LOCAL_ISDN + 1;
19069 } else if (!strcasecmp(v->value, "dynamic")) {
19070 confp->pri.pri.dialplan = -1;
19071 } else if (!strcasecmp(v->value, "redundant")) {
19072 confp->pri.pri.dialplan = -2;
19073 } else {
19074 ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
19075 }
19076 } else if (!strcasecmp(v->name, "prilocaldialplan")) {
19077 if (!strcasecmp(v->value, "national")) {
19078 confp->pri.pri.localdialplan = PRI_NATIONAL_ISDN + 1;
19079 } else if (!strcasecmp(v->value, "unknown")) {
19080 confp->pri.pri.localdialplan = PRI_UNKNOWN + 1;
19081 } else if (!strcasecmp(v->value, "private")) {
19082 confp->pri.pri.localdialplan = PRI_PRIVATE + 1;
19083 } else if (!strcasecmp(v->value, "international")) {
19084 confp->pri.pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
19085 } else if (!strcasecmp(v->value, "local")) {
19086 confp->pri.pri.localdialplan = PRI_LOCAL_ISDN + 1;
19087 } else if (!strcasecmp(v->value, "from_channel")) {
19088 confp->pri.pri.localdialplan = 0;
19089 } else if (!strcasecmp(v->value, "dynamic")) {
19090 confp->pri.pri.localdialplan = -1;
19091 } else if (!strcasecmp(v->value, "redundant")) {
19092 confp->pri.pri.localdialplan = -2;
19093 } else {
19094 ast_log(LOG_WARNING, "Unknown PRI localdialplan '%s' at line %d.\n", v->value, v->lineno);
19095 }
19096 } else if (!strcasecmp(v->name, "pricpndialplan")) {
19097 if (!strcasecmp(v->value, "national")) {
19098 confp->pri.pri.cpndialplan = PRI_NATIONAL_ISDN + 1;
19099 } else if (!strcasecmp(v->value, "unknown")) {
19100 confp->pri.pri.cpndialplan = PRI_UNKNOWN + 1;
19101 } else if (!strcasecmp(v->value, "private")) {
19102 confp->pri.pri.cpndialplan = PRI_PRIVATE + 1;
19103 } else if (!strcasecmp(v->value, "international")) {
19104 confp->pri.pri.cpndialplan = PRI_INTERNATIONAL_ISDN + 1;
19105 } else if (!strcasecmp(v->value, "local")) {
19106 confp->pri.pri.cpndialplan = PRI_LOCAL_ISDN + 1;
19107 } else if (!strcasecmp(v->value, "from_channel")) {
19108 confp->pri.pri.cpndialplan = 0;
19109 } else if (!strcasecmp(v->value, "dynamic")) {
19110 confp->pri.pri.cpndialplan = -1;
19111 } else if (!strcasecmp(v->value, "redundant")) {
19112 confp->pri.pri.cpndialplan = -2;
19113 } else {
19114 ast_log(LOG_WARNING, "Unknown PRI cpndialplan '%s' at line %d.\n", v->value, v->lineno);
19115 }
19116 } else if (!strcasecmp(v->name, "switchtype")) {
19117 if (!strcasecmp(v->value, "national"))
19118 confp->pri.pri.switchtype = PRI_SWITCH_NI2;
19119 else if (!strcasecmp(v->value, "ni1"))
19120 confp->pri.pri.switchtype = PRI_SWITCH_NI1;
19121 else if (!strcasecmp(v->value, "dms100"))
19122 confp->pri.pri.switchtype = PRI_SWITCH_DMS100;
19123 else if (!strcasecmp(v->value, "4ess"))
19124 confp->pri.pri.switchtype = PRI_SWITCH_ATT4ESS;
19125 else if (!strcasecmp(v->value, "5ess"))
19126 confp->pri.pri.switchtype = PRI_SWITCH_LUCENT5E;
19127 else if (!strcasecmp(v->value, "euroisdn"))
19128 confp->pri.pri.switchtype = PRI_SWITCH_EUROISDN_E1;
19129 else if (!strcasecmp(v->value, "qsig"))
19130 confp->pri.pri.switchtype = PRI_SWITCH_QSIG;
19131 else {
19132 ast_log(LOG_ERROR, "Unknown switchtype '%s' at line %d.\n", v->value, v->lineno);
19133 return -1;
19134 }
19135 } else if (!strcasecmp(v->name, "msn")) {
19136 ast_copy_string(confp->pri.pri.msn_list, v->value,
19137 sizeof(confp->pri.pri.msn_list));
19138 } else if (!strcasecmp(v->name, "nsf")) {
19139 if (!strcasecmp(v->value, "sdn"))
19140 confp->pri.pri.nsf = PRI_NSF_SDN;
19141 else if (!strcasecmp(v->value, "megacom"))
19142 confp->pri.pri.nsf = PRI_NSF_MEGACOM;
19143 else if (!strcasecmp(v->value, "tollfreemegacom"))
19144 confp->pri.pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;
19145 else if (!strcasecmp(v->value, "accunet"))
19146 confp->pri.pri.nsf = PRI_NSF_ACCUNET;
19147 else if (!strcasecmp(v->value, "none"))
19148 confp->pri.pri.nsf = PRI_NSF_NONE;
19149 else {
19150 ast_log(LOG_WARNING, "Unknown network-specific facility '%s' at line %d.\n", v->value, v->lineno);
19151 confp->pri.pri.nsf = PRI_NSF_NONE;
19152 }
19153 } else if (!strcasecmp(v->name, "priindication")) {
19154 if (!strcasecmp(v->value, "outofband"))
19155 confp->chan.priindication_oob = 1;
19156 else if (!strcasecmp(v->value, "inband"))
19157 confp->chan.priindication_oob = 0;
19158 else
19159 ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d.\n",
19160 v->value, v->lineno);
19161 } else if (!strcasecmp(v->name, "priexclusive")) {
19162 confp->chan.priexclusive = ast_true(v->value);
19163 } else if (!strcasecmp(v->name, "internationalprefix")) {
19164 ast_copy_string(confp->pri.pri.internationalprefix, v->value, sizeof(confp->pri.pri.internationalprefix));
19165 } else if (!strcasecmp(v->name, "nationalprefix")) {
19166 ast_copy_string(confp->pri.pri.nationalprefix, v->value, sizeof(confp->pri.pri.nationalprefix));
19167 } else if (!strcasecmp(v->name, "localprefix")) {
19168 ast_copy_string(confp->pri.pri.localprefix, v->value, sizeof(confp->pri.pri.localprefix));
19169 } else if (!strcasecmp(v->name, "privateprefix")) {
19170 ast_copy_string(confp->pri.pri.privateprefix, v->value, sizeof(confp->pri.pri.privateprefix));
19171 } else if (!strcasecmp(v->name, "unknownprefix")) {
19172 ast_copy_string(confp->pri.pri.unknownprefix, v->value, sizeof(confp->pri.pri.unknownprefix));
19173 } else if (!strcasecmp(v->name, "resetinterval")) {
19174 if (!strcasecmp(v->value, "never"))
19175 confp->pri.pri.resetinterval = -1;
19176 else if (atoi(v->value) >= 60)
19177 confp->pri.pri.resetinterval = atoi(v->value);
19178 else
19179 ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n",
19180 v->value, v->lineno);
19181 } else if (!strcasecmp(v->name, "force_restart_unavailable_chans")) {
19182 confp->pri.pri.force_restart_unavailable_chans = ast_true(v->value);
19183 } else if (!strcasecmp(v->name, "minunused")) {
19184 confp->pri.pri.minunused = atoi(v->value);
19185 } else if (!strcasecmp(v->name, "minidle")) {
19186 confp->pri.pri.minidle = atoi(v->value);
19187 } else if (!strcasecmp(v->name, "idleext")) {
19188 ast_copy_string(confp->pri.pri.idleext, v->value, sizeof(confp->pri.pri.idleext));
19189 } else if (!strcasecmp(v->name, "idledial")) {
19190 ast_copy_string(confp->pri.pri.idledial, v->value, sizeof(confp->pri.pri.idledial));
19191 } else if (!strcasecmp(v->name, "overlapdial")) {
19192 if (ast_true(v->value)) {
19193 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
19194 } else if (!strcasecmp(v->value, "incoming")) {
19195 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_INCOMING;
19196 } else if (!strcasecmp(v->value, "outgoing")) {
19197 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_OUTGOING;
19198 } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) {
19199 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
19200 } else {
19201 confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_NONE;
19202 }
19203#ifdef HAVE_PRI_PROG_W_CAUSE
19204 } else if (!strcasecmp(v->name, "qsigchannelmapping")) {
19205 if (!strcasecmp(v->value, "logical")) {
19206 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_LOGICAL;
19207 } else if (!strcasecmp(v->value, "physical")) {
19208 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL;
19209 } else {
19210 confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL;
19211 }
19212#endif
19213 } else if (!strcasecmp(v->name, "discardremoteholdretrieval")) {
19214 confp->pri.pri.discardremoteholdretrieval = ast_true(v->value);
19215#if defined(HAVE_PRI_SERVICE_MESSAGES)
19216 } else if (!strcasecmp(v->name, "service_message_support")) {
19217 /* assuming switchtype for this channel group has been configured already */
19218 if ((confp->pri.pri.switchtype == PRI_SWITCH_ATT4ESS
19219 || confp->pri.pri.switchtype == PRI_SWITCH_LUCENT5E
19220 || confp->pri.pri.switchtype == PRI_SWITCH_NI2) && ast_true(v->value)) {
19221 confp->pri.pri.enable_service_message_support = 1;
19222 } else {
19223 confp->pri.pri.enable_service_message_support = 0;
19224 }
19225#endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
19226#ifdef HAVE_PRI_INBANDDISCONNECT
19227 } else if (!strcasecmp(v->name, "inbanddisconnect")) {
19228 confp->pri.pri.inbanddisconnect = ast_true(v->value);
19229#endif
19230 } else if (!strcasecmp(v->name, "pritimer")) {
19231#ifdef PRI_GETSET_TIMERS
19232 char tmp[20];
19233 char *timerc;
19234 char *c;
19235 int timer;
19236 int timeridx;
19237
19238 ast_copy_string(tmp, v->value, sizeof(tmp));
19239 c = tmp;
19240 timerc = strsep(&c, ",");
19241 if (!ast_strlen_zero(timerc) && !ast_strlen_zero(c)) {
19242 timeridx = pri_timer2idx(timerc);
19243 timer = atoi(c);
19244 if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) {
19246 "'%s' is not a valid ISDN timer at line %d.\n", timerc,
19247 v->lineno);
19248 } else if (!timer) {
19250 "'%s' is not a valid value for ISDN timer '%s' at line %d.\n",
19251 c, timerc, v->lineno);
19252 } else {
19253 confp->pri.pri.pritimers[timeridx] = timer;
19254 }
19255 } else {
19257 "'%s' is not a valid ISDN timer configuration string at line %d.\n",
19258 v->value, v->lineno);
19259 }
19260#endif /* PRI_GETSET_TIMERS */
19261 } else if (!strcasecmp(v->name, "facilityenable")) {
19262 confp->pri.pri.facilityenable = ast_true(v->value);
19263#if defined(HAVE_PRI_AOC_EVENTS)
19264 } else if (!strcasecmp(v->name, "aoc_enable")) {
19265 confp->pri.pri.aoc_passthrough_flag = 0;
19266 if (strchr(v->value, 's') || strchr(v->value, 'S')) {
19267 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_S;
19268 }
19269 if (strchr(v->value, 'd') || strchr(v->value, 'D')) {
19270 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_D;
19271 }
19272 if (strchr(v->value, 'e') || strchr(v->value, 'E')) {
19273 confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_E;
19274 }
19275 } else if (!strcasecmp(v->name, "aoce_delayhangup")) {
19276 confp->pri.pri.aoce_delayhangup = ast_true(v->value);
19277#endif /* defined(HAVE_PRI_AOC_EVENTS) */
19278#if defined(HAVE_PRI_CALL_HOLD)
19279 } else if (!strcasecmp(v->name, "hold_disconnect_transfer")) {
19280 confp->pri.pri.hold_disconnect_transfer = ast_true(v->value);
19281#endif /* defined(HAVE_PRI_CALL_HOLD) */
19282 } else if (!strcasecmp(v->name, "moh_signaling")
19283 || !strcasecmp(v->name, "moh_signalling")) {
19284 if (!strcasecmp(v->value, "moh")) {
19285 confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_MOH;
19286 } else if (!strcasecmp(v->value, "notify")) {
19287 confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_NOTIFY;
19288#if defined(HAVE_PRI_CALL_HOLD)
19289 } else if (!strcasecmp(v->value, "hold")) {
19290 confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_HOLD;
19291#endif /* defined(HAVE_PRI_CALL_HOLD) */
19292 } else {
19293 confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_MOH;
19294 }
19295#if defined(HAVE_PRI_CCSS)
19296 } else if (!strcasecmp(v->name, "cc_ptmp_recall_mode")) {
19297 if (!strcasecmp(v->value, "global")) {
19298 confp->pri.pri.cc_ptmp_recall_mode = 0;/* globalRecall */
19299 } else if (!strcasecmp(v->value, "specific")) {
19300 confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */
19301 } else {
19302 confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */
19303 }
19304 } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_req")) {
19305 if (!strcasecmp(v->value, "release")) {
19306 confp->pri.pri.cc_qsig_signaling_link_req = 0;/* release */
19307 } else if (!strcasecmp(v->value, "retain")) {
19308 confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */
19309 } else if (!strcasecmp(v->value, "do_not_care")) {
19310 confp->pri.pri.cc_qsig_signaling_link_req = 2;/* do-not-care */
19311 } else {
19312 confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */
19313 }
19314 } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_rsp")) {
19315 if (!strcasecmp(v->value, "release")) {
19316 confp->pri.pri.cc_qsig_signaling_link_rsp = 0;/* release */
19317 } else if (!strcasecmp(v->value, "retain")) {
19318 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */
19319 } else {
19320 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */
19321 }
19322#endif /* defined(HAVE_PRI_CCSS) */
19323#if defined(HAVE_PRI_CALL_WAITING)
19324 } else if (!strcasecmp(v->name, "max_call_waiting_calls")) {
19325 confp->pri.pri.max_call_waiting_calls = atoi(v->value);
19326 if (confp->pri.pri.max_call_waiting_calls < 0) {
19327 /* Negative values are not allowed. */
19328 confp->pri.pri.max_call_waiting_calls = 0;
19329 }
19330 } else if (!strcasecmp(v->name, "allow_call_waiting_calls")) {
19331 confp->pri.pri.allow_call_waiting_calls = ast_true(v->value);
19332#endif /* defined(HAVE_PRI_CALL_WAITING) */
19333#if defined(HAVE_PRI_MWI)
19334 } else if (!strcasecmp(v->name, "mwi_mailboxes")) {
19335 ast_copy_string(confp->pri.pri.mwi_mailboxes, v->value,
19336 sizeof(confp->pri.pri.mwi_mailboxes));
19337 } else if (!strcasecmp(v->name, "mwi_vm_boxes")) {
19338 ast_copy_string(confp->pri.pri.mwi_vm_boxes, v->value,
19339 sizeof(confp->pri.pri.mwi_vm_boxes));
19340 } else if (!strcasecmp(v->name, "mwi_vm_numbers")) {
19341 ast_copy_string(confp->pri.pri.mwi_vm_numbers, v->value,
19342 sizeof(confp->pri.pri.mwi_vm_numbers));
19343#endif /* defined(HAVE_PRI_MWI) */
19344 } else if (!strcasecmp(v->name, "append_msn_to_cid_tag")) {
19345 confp->pri.pri.append_msn_to_user_tag = ast_true(v->value);
19346 } else if (!strcasecmp(v->name, "inband_on_setup_ack")) {
19347 confp->pri.pri.inband_on_setup_ack = ast_true(v->value);
19348 } else if (!strcasecmp(v->name, "inband_on_proceeding")) {
19349 confp->pri.pri.inband_on_proceeding = ast_true(v->value);
19350#if defined(HAVE_PRI_DISPLAY_TEXT)
19351 } else if (!strcasecmp(v->name, "display_send")) {
19352 confp->pri.pri.display_flags_send = dahdi_display_text_option(v->value);
19353 } else if (!strcasecmp(v->name, "display_receive")) {
19354 confp->pri.pri.display_flags_receive = dahdi_display_text_option(v->value);
19355#endif /* defined(HAVE_PRI_DISPLAY_TEXT) */
19356#if defined(HAVE_PRI_MCID)
19357 } else if (!strcasecmp(v->name, "mcid_send")) {
19358 confp->pri.pri.mcid_send = ast_true(v->value);
19359#endif /* defined(HAVE_PRI_MCID) */
19360#if defined(HAVE_PRI_DATETIME_SEND)
19361 } else if (!strcasecmp(v->name, "datetime_send")) {
19362 confp->pri.pri.datetime_send = dahdi_datetime_send_option(v->value);
19363#endif /* defined(HAVE_PRI_DATETIME_SEND) */
19364 } else if (!strcasecmp(v->name, "layer1_presence")) {
19365 if (!strcasecmp(v->value, "required")) {
19366 confp->pri.pri.layer1_ignored = 0;
19367 } else if (!strcasecmp(v->value, "ignore")) {
19368 confp->pri.pri.layer1_ignored = 1;
19369 } else {
19370 /* Default */
19371 confp->pri.pri.layer1_ignored = 0;
19372 }
19373#if defined(HAVE_PRI_L2_PERSISTENCE)
19374 } else if (!strcasecmp(v->name, "layer2_persistence")) {
19375 if (!strcasecmp(v->value, "keep_up")) {
19376 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_KEEP_UP;
19377 } else if (!strcasecmp(v->value, "leave_down")) {
19378 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_LEAVE_DOWN;
19379 } else {
19380 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_DEFAULT;
19381 }
19382#endif /* defined(HAVE_PRI_L2_PERSISTENCE) */
19383 } else if (!strcasecmp(v->name, "colp_send")) {
19384 if (!strcasecmp(v->value, "block")) {
19385 confp->pri.pri.colp_send = SIG_PRI_COLP_BLOCK;
19386 } else if (!strcasecmp(v->value, "connect")) {
19387 confp->pri.pri.colp_send = SIG_PRI_COLP_CONNECT;
19388 } else if (!strcasecmp(v->value, "update")) {
19389 confp->pri.pri.colp_send = SIG_PRI_COLP_UPDATE;
19390 } else {
19391 confp->pri.pri.colp_send = SIG_PRI_COLP_UPDATE;
19392 }
19393#endif /* HAVE_PRI */
19394#if defined(HAVE_SS7)
19395 } else if (!strcasecmp(v->name, "ss7type")) {
19396 if (!strcasecmp(v->value, "itu")) {
19397 cur_ss7type = SS7_ITU;
19398 } else if (!strcasecmp(v->value, "ansi")) {
19399 cur_ss7type = SS7_ANSI;
19400 } else {
19401 ast_log(LOG_WARNING, "'%s' is an unknown ss7 switch type at line %d.!\n", v->value, v->lineno);
19402 }
19403 } else if (!strcasecmp(v->name, "slc")) {
19404 cur_slc = atoi(v->value);
19405 } else if (!strcasecmp(v->name, "linkset")) {
19406 cur_linkset = atoi(v->value);
19407 } else if (!strcasecmp(v->name, "pointcode")) {
19408 cur_pointcode = parse_pointcode(v->value);
19409 } else if (!strcasecmp(v->name, "adjpointcode")) {
19410 cur_adjpointcode = parse_pointcode(v->value);
19411 } else if (!strcasecmp(v->name, "defaultdpc")) {
19412 cur_defaultdpc = parse_pointcode(v->value);
19413 } else if (!strcasecmp(v->name, "cicbeginswith")) {
19414 cur_cicbeginswith = atoi(v->value);
19415 } else if (!strcasecmp(v->name, "networkindicator")) {
19416 if (!strcasecmp(v->value, "national")) {
19417 cur_networkindicator = SS7_NI_NAT;
19418 } else if (!strcasecmp(v->value, "national_spare")) {
19419 cur_networkindicator = SS7_NI_NAT_SPARE;
19420 } else if (!strcasecmp(v->value, "international")) {
19421 cur_networkindicator = SS7_NI_INT;
19422 } else if (!strcasecmp(v->value, "international_spare")) {
19423 cur_networkindicator = SS7_NI_INT_SPARE;
19424 } else {
19425 cur_networkindicator = -1;
19426 }
19427 } else if (!strcasecmp(v->name, "ss7_internationalprefix")) {
19428 ast_copy_string(confp->ss7.ss7.internationalprefix, v->value, sizeof(confp->ss7.ss7.internationalprefix));
19429 } else if (!strcasecmp(v->name, "ss7_nationalprefix")) {
19430 ast_copy_string(confp->ss7.ss7.nationalprefix, v->value, sizeof(confp->ss7.ss7.nationalprefix));
19431 } else if (!strcasecmp(v->name, "ss7_subscriberprefix")) {
19432 ast_copy_string(confp->ss7.ss7.subscriberprefix, v->value, sizeof(confp->ss7.ss7.subscriberprefix));
19433 } else if (!strcasecmp(v->name, "ss7_unknownprefix")) {
19434 ast_copy_string(confp->ss7.ss7.unknownprefix, v->value, sizeof(confp->ss7.ss7.unknownprefix));
19435 } else if (!strcasecmp(v->name, "ss7_networkroutedprefix")) {
19436 ast_copy_string(confp->ss7.ss7.networkroutedprefix, v->value, sizeof(confp->ss7.ss7.networkroutedprefix));
19437 } else if (!strcasecmp(v->name, "ss7_called_nai")) {
19438 if (!strcasecmp(v->value, "national")) {
19439 confp->ss7.ss7.called_nai = SS7_NAI_NATIONAL;
19440 } else if (!strcasecmp(v->value, "international")) {
19441 confp->ss7.ss7.called_nai = SS7_NAI_INTERNATIONAL;
19442 } else if (!strcasecmp(v->value, "subscriber")) {
19443 confp->ss7.ss7.called_nai = SS7_NAI_SUBSCRIBER;
19444 } else if (!strcasecmp(v->value, "unknown")) {
19445 confp->ss7.ss7.called_nai = SS7_NAI_UNKNOWN;
19446 } else if (!strcasecmp(v->value, "dynamic")) {
19447 confp->ss7.ss7.called_nai = SS7_NAI_DYNAMIC;
19448 } else {
19449 ast_log(LOG_WARNING, "Unknown SS7 called_nai '%s' at line %d.\n", v->value, v->lineno);
19450 }
19451 } else if (!strcasecmp(v->name, "ss7_calling_nai")) {
19452 if (!strcasecmp(v->value, "national")) {
19453 confp->ss7.ss7.calling_nai = SS7_NAI_NATIONAL;
19454 } else if (!strcasecmp(v->value, "international")) {
19455 confp->ss7.ss7.calling_nai = SS7_NAI_INTERNATIONAL;
19456 } else if (!strcasecmp(v->value, "subscriber")) {
19457 confp->ss7.ss7.calling_nai = SS7_NAI_SUBSCRIBER;
19458 } else if (!strcasecmp(v->value, "unknown")) {
19459 confp->ss7.ss7.calling_nai = SS7_NAI_UNKNOWN;
19460 } else if (!strcasecmp(v->value, "dynamic")) {
19461 confp->ss7.ss7.calling_nai = SS7_NAI_DYNAMIC;
19462 } else {
19463 ast_log(LOG_WARNING, "Unknown SS7 calling_nai '%s' at line %d.\n", v->value, v->lineno);
19464 }
19465 } else if (!strcasecmp(v->name, "sigchan")) {
19466 int sigchan, res;
19467 sigchan = atoi(v->value);
19468 res = linkset_addsigchan(sigchan);
19469 if (res < 0) {
19470 return -1;
19471 }
19472 } else if (!strcasecmp(v->name, "ss7_explicitacm")) {
19473 struct dahdi_ss7 *link;
19474 link = ss7_resolve_linkset(cur_linkset);
19475 if (!link) {
19476 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19477 return -1;
19478 }
19479 if (ast_true(v->value)) {
19480 link->ss7.flags |= LINKSET_FLAG_EXPLICITACM;
19481 } else {
19482 link->ss7.flags &= ~LINKSET_FLAG_EXPLICITACM;
19483 }
19484 } else if (!strcasecmp(v->name, "ss7_autoacm")) {
19485 struct dahdi_ss7 *link;
19486 link = ss7_resolve_linkset(cur_linkset);
19487 if (!link) {
19488 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19489 return -1;
19490 }
19491 if (ast_true(v->value)) {
19492 link->ss7.flags |= LINKSET_FLAG_AUTOACM;
19493 } else {
19494 link->ss7.flags &= ~LINKSET_FLAG_AUTOACM;
19495 }
19496 } else if (!strcasecmp(v->name, "ss7_initialhwblo")) {
19497 struct dahdi_ss7 *link;
19498 link = ss7_resolve_linkset(cur_linkset);
19499 if (!link) {
19500 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19501 return -1;
19502 }
19503 if (ast_true(v->value)) {
19504 link->ss7.flags |= LINKSET_FLAG_INITIALHWBLO;
19505 } else {
19506 link->ss7.flags &= ~LINKSET_FLAG_INITIALHWBLO;
19507 }
19508 } else if (!strcasecmp(v->name, "ss7_use_echocontrol")) {
19509 struct dahdi_ss7 *link;
19510 link = ss7_resolve_linkset(cur_linkset);
19511 if (!link) {
19512 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19513 return -1;
19514 }
19515 if (ast_true(v->value)) {
19516 link->ss7.flags |= LINKSET_FLAG_USEECHOCONTROL;
19517 } else {
19518 link->ss7.flags &= ~LINKSET_FLAG_USEECHOCONTROL;
19519 }
19520 } else if (!strcasecmp(v->name, "ss7_default_echocontrol")) {
19521 struct dahdi_ss7 *link;
19522 link = ss7_resolve_linkset(cur_linkset);
19523 if (!link) {
19524 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19525 return -1;
19526 }
19527 if (ast_true(v->value)) {
19528 link->ss7.flags |= LINKSET_FLAG_DEFAULTECHOCONTROL;
19529 } else {
19530 link->ss7.flags &= ~LINKSET_FLAG_DEFAULTECHOCONTROL;
19531 }
19532 } else if (!strncasecmp(v->name, "isup_timer.", 11)) {
19533 struct dahdi_ss7 *link;
19534 link = ss7_resolve_linkset(cur_linkset);
19535 if (!link) {
19536 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19537 return -1;
19538 }
19539 if (!link->ss7.ss7) {
19540 ast_log(LOG_ERROR, "Please specify isup timers after sigchan!\n");
19541 } else if (!ss7_set_isup_timer(link->ss7.ss7, strstr(v->name, ".") + 1, atoi(v->value))) {
19542 ast_log(LOG_ERROR, "Invalid isup timer %s\n", v->name);
19543 }
19544 } else if (!strncasecmp(v->name, "mtp3_timer.", 11)) {
19545 struct dahdi_ss7 *link;
19546 link = ss7_resolve_linkset(cur_linkset);
19547 if (!link) {
19548 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19549 return -1;
19550 }
19551 if (!link->ss7.ss7) {
19552 ast_log(LOG_ERROR, "Please specify mtp3 timers after sigchan!\n");
19553 } else if (!ss7_set_mtp3_timer(link->ss7.ss7, strstr(v->name, ".") + 1, atoi(v->value))) {
19554 ast_log(LOG_ERROR, "Invalid mtp3 timer %s\n", v->name);
19555 }
19556 } else if (!strcasecmp(v->name, "inr_if_no_calling")) {
19557 struct dahdi_ss7 *link;
19558 link = ss7_resolve_linkset(cur_linkset);
19559 if (!link) {
19560 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19561 return -1;
19562 }
19563 if (!link->ss7.ss7) {
19564 ast_log(LOG_ERROR, "Please specify inr_if_no_calling after sigchan!\n");
19565 } else if (ast_true(v->value)) {
19566 ss7_set_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
19567 } else {
19568 ss7_clear_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
19569 }
19570 } else if (!strcasecmp(v->name, "non_isdn_access")) {
19571 struct dahdi_ss7 *link;
19572 link = ss7_resolve_linkset(cur_linkset);
19573 if (!link) {
19574 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19575 return -1;
19576 }
19577 if (!link->ss7.ss7) {
19578 ast_log(LOG_ERROR, "Please specify non_isdn_access after sigchan!\n");
19579 } else if (ast_true(v->value)) {
19580 ss7_clear_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
19581 } else {
19582 ss7_set_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
19583 }
19584 } else if (!strcasecmp(v->name, "sls_shift")) {
19585 struct dahdi_ss7 *link;
19586 int sls_shift = atoi(v->value);
19587
19588 if (sls_shift < 0 || sls_shift > 7) {
19589 ast_log(LOG_ERROR, "Invalid sls_shift value. Must be between 0 and 7\n");
19590 return -1;
19591 }
19592
19593 link = ss7_resolve_linkset(cur_linkset);
19594 if (!link) {
19595 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19596 return -1;
19597 }
19598 if (!link->ss7.ss7) {
19599 ast_log(LOG_ERROR, "Please specify sls_shift after sigchan!\n");
19600 } else {
19601 ss7_set_sls_shift(link->ss7.ss7, sls_shift);
19602 }
19603 } else if (!strcasecmp(v->name, "cause_location")) {
19604 struct dahdi_ss7 *link;
19605 int cause_location = atoi(v->value);
19606
19607 if (cause_location < 0 || cause_location > 15) {
19608 ast_log(LOG_ERROR, "Invalid cause_location value. Must be between 0 and 15\n");
19609 return -1;
19610 }
19611 link = ss7_resolve_linkset(cur_linkset);
19612 if (!link) {
19613 ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19614 return -1;
19615 }
19616 if (!link->ss7.ss7) {
19617 ast_log(LOG_ERROR, "Please specify cause_location after sigchan!\n");
19618 } else {
19619 ss7_set_cause_location(link->ss7.ss7, cause_location);
19620 }
19621#endif /* defined(HAVE_SS7) */
19622#ifdef HAVE_OPENR2
19623 } else if (!strcasecmp(v->name, "mfcr2_advanced_protocol_file")) {
19624 ast_copy_string(confp->mfcr2.r2proto_file, v->value, sizeof(confp->mfcr2.r2proto_file));
19625 ast_log(LOG_WARNING, "MFC/R2 Protocol file '%s' will be used, you only should use this if you *REALLY KNOW WHAT YOU ARE DOING*.\n", confp->mfcr2.r2proto_file);
19626 } else if (!strcasecmp(v->name, "mfcr2_logdir")) {
19627 ast_copy_string(confp->mfcr2.logdir, v->value, sizeof(confp->mfcr2.logdir));
19628 } else if (!strcasecmp(v->name, "mfcr2_variant")) {
19629 confp->mfcr2.variant = openr2_proto_get_variant(v->value);
19630 if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) {
19631 ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d, defaulting to ITU.\n", v->value, v->lineno);
19632 confp->mfcr2.variant = OR2_VAR_ITU;
19633 }
19634 } else if (!strcasecmp(v->name, "mfcr2_mfback_timeout")) {
19635 confp->mfcr2.mfback_timeout = atoi(v->value);
19636 if (!confp->mfcr2.mfback_timeout) {
19637 ast_log(LOG_WARNING, "MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n");
19638 confp->mfcr2.mfback_timeout = -1;
19639 } else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) {
19640 ast_log(LOG_WARNING, "MF timeout less than 500ms is not recommended, you have been warned!\n");
19641 }
19642 } else if (!strcasecmp(v->name, "mfcr2_metering_pulse_timeout")) {
19643 confp->mfcr2.metering_pulse_timeout = atoi(v->value);
19644 if (confp->mfcr2.metering_pulse_timeout > 500) {
19645 ast_log(LOG_WARNING, "Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n");
19646 }
19647#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
19648 } else if (!strcasecmp(v->name, "mfcr2_dtmf_detection")) {
19649 confp->mfcr2.dtmf_detection = ast_true(v->value) ? 1 : 0;
19650 } else if (!strcasecmp(v->name, "mfcr2_dtmf_dialing")) {
19651 confp->mfcr2.dtmf_dialing = ast_true(v->value) ? 1 : 0;
19652 } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_on")) {
19653 confp->mfcr2.dtmf_time_on = atoi(v->value);
19654 } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_off")) {
19655 confp->mfcr2.dtmf_time_off = atoi(v->value);
19656#endif
19657#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
19658 } else if (!strcasecmp(v->name, "mfcr2_dtmf_end_timeout")) {
19659 confp->mfcr2.dtmf_end_timeout = atoi(v->value);
19660#endif
19661 } else if (!strcasecmp(v->name, "mfcr2_get_ani_first")) {
19662 confp->mfcr2.get_ani_first = ast_true(v->value) ? 1 : 0;
19663 } else if (!strcasecmp(v->name, "mfcr2_double_answer")) {
19664 confp->mfcr2.double_answer = ast_true(v->value) ? 1 : 0;
19665 } else if (!strcasecmp(v->name, "mfcr2_charge_calls")) {
19666 confp->mfcr2.charge_calls = ast_true(v->value) ? 1 : 0;
19667 } else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) {
19668 confp->mfcr2.accept_on_offer = ast_true(v->value) ? 1 : 0;
19669 } else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) {
19670 confp->mfcr2.allow_collect_calls = ast_true(v->value) ? 1 : 0;
19671 } else if (!strcasecmp(v->name, "mfcr2_forced_release")) {
19672 confp->mfcr2.forced_release = ast_true(v->value) ? 1 : 0;
19673 } else if (!strcasecmp(v->name, "mfcr2_immediate_accept")) {
19674 confp->mfcr2.immediate_accept = ast_true(v->value) ? 1 : 0;
19675#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
19676 } else if (!strcasecmp(v->name, "mfcr2_skip_category")) {
19677 confp->mfcr2.skip_category_request = ast_true(v->value) ? 1 : 0;
19678#endif
19679 } else if (!strcasecmp(v->name, "mfcr2_call_files")) {
19680 confp->mfcr2.call_files = ast_true(v->value) ? 1 : 0;
19681 } else if (!strcasecmp(v->name, "mfcr2_max_ani")) {
19682 confp->mfcr2.max_ani = atoi(v->value);
19683 if (confp->mfcr2.max_ani >= AST_MAX_EXTENSION) {
19684 confp->mfcr2.max_ani = AST_MAX_EXTENSION - 1;
19685 }
19686 } else if (!strcasecmp(v->name, "mfcr2_max_dnis")) {
19687 confp->mfcr2.max_dnis = atoi(v->value);
19688 if (confp->mfcr2.max_dnis >= AST_MAX_EXTENSION) {
19689 confp->mfcr2.max_dnis = AST_MAX_EXTENSION - 1;
19690 }
19691 } else if (!strcasecmp(v->name, "mfcr2_category")) {
19692 confp->mfcr2.category = openr2_proto_get_category(v->value);
19693 if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) {
19694 confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
19695 ast_log(LOG_WARNING, "Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n",
19696 v->value, v->lineno);
19697 }
19698 } else if (!strcasecmp(v->name, "mfcr2_logging")) {
19699 openr2_log_level_t tmplevel;
19700 char *clevel;
19701 char *logval;
19702 char copy[strlen(v->value) + 1];
19703 strcpy(copy, v->value); /* safe */
19704 logval = copy;
19705 while (logval) {
19706 clevel = strsep(&logval,",");
19707 if (-1 == (tmplevel = openr2_log_get_level(clevel))) {
19708 ast_log(LOG_WARNING, "Ignoring invalid logging level: '%s' at line %d.\n", clevel, v->lineno);
19709 continue;
19710 }
19711 confp->mfcr2.loglevel |= tmplevel;
19712 }
19713#endif /* HAVE_OPENR2 */
19714 } else if (!strcasecmp(v->name, "cadence")) {
19715 /* setup to scan our argument */
19716 int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
19717 int i;
19718 struct dahdi_ring_cadence new_cadence;
19719 int cid_location = -1;
19720 int firstcadencepos = 0;
19721 char original_args[80];
19722 int cadence_is_ok = 1;
19723
19724 ast_copy_string(original_args, v->value, sizeof(original_args));
19725 /* 16 cadences allowed (8 pairs) */
19726 element_count = sscanf(v->value, "%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d", &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12], &c[13], &c[14], &c[15]);
19727
19728 /* Cadence must be even (on/off) */
19729 if (element_count % 2 == 1) {
19730 ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s at line %d.\n", original_args, v->lineno);
19731 cadence_is_ok = 0;
19732 }
19733
19734 /* This check is only needed to satisfy the compiler that element_count can't cause an out of bounds */
19735 if (element_count > ARRAY_LEN(c)) {
19736 element_count = ARRAY_LEN(c);
19737 }
19738
19739 /* Ring cadences cannot be negative */
19740 for (i = 0; i < element_count; i++) {
19741 if (c[i] == 0) {
19742 ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s at line %d.\n", original_args, v->lineno);
19743 cadence_is_ok = 0;
19744 break;
19745 } else if (c[i] < 0) {
19746 if (i % 2 == 1) {
19747 /* Silence duration, negative possibly okay */
19748 if (cid_location == -1) {
19749 cid_location = i;
19750 c[i] *= -1;
19751 } else {
19752 ast_log(LOG_ERROR, "CID location specified twice: %s at line %d.\n", original_args, v->lineno);
19753 cadence_is_ok = 0;
19754 break;
19755 }
19756 } else {
19757 if (firstcadencepos == 0) {
19758 firstcadencepos = i; /* only recorded to avoid duplicate specification */
19759 /* duration will be passed negative to the DAHDI driver */
19760 } else {
19761 ast_log(LOG_ERROR, "First cadence position specified twice: %s at line %d.\n", original_args, v->lineno);
19762 cadence_is_ok = 0;
19763 break;
19764 }
19765 }
19766 }
19767 }
19768
19769 /* Substitute our scanned cadence */
19770 for (i = 0; i < 16; i++) {
19771 new_cadence.ringcadence[i] = c[i];
19772 }
19773
19774 if (cadence_is_ok) {
19775 /* ---we scanned it without getting annoyed; now some sanity checks--- */
19776 if (element_count < 2) {
19777 ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s at line %d.\n", original_args, v->lineno);
19778 } else {
19779 if (cid_location == -1) {
19780 /* user didn't say; default to first pause */
19781 cid_location = 1;
19782 } else {
19783 /* convert element_index to cidrings value */
19784 cid_location = (cid_location + 1) / 2;
19785 }
19786 /* ---we like their cadence; try to install it--- */
19788 /* this is the first user-defined cadence; clear the default user cadences */
19789 num_cadence = 0;
19790 if ((num_cadence+1) >= NUM_CADENCE_MAX)
19791 ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s at line %d.\n", NUM_CADENCE_MAX, original_args, v->lineno);
19792 else {
19793 cadences[num_cadence] = new_cadence;
19794 cidrings[num_cadence++] = cid_location;
19795 ast_verb(3, "cadence 'r%d' added: %s\n",num_cadence,original_args);
19796 }
19797 }
19798 }
19799 } else if (!strcasecmp(v->name, "ringtimeout")) {
19800 ringt_base = (atoi(v->value) * 8) / READ_SIZE;
19801 } else if (!strcasecmp(v->name, "prewink")) {
19802 confp->timing.prewinktime = atoi(v->value);
19803 } else if (!strcasecmp(v->name, "preflash")) {
19804 confp->timing.preflashtime = atoi(v->value);
19805 } else if (!strcasecmp(v->name, "wink")) {
19806 confp->timing.winktime = atoi(v->value);
19807 } else if (!strcasecmp(v->name, "flash")) {
19808 confp->timing.flashtime = atoi(v->value);
19809 } else if (!strcasecmp(v->name, "start")) {
19810 confp->timing.starttime = atoi(v->value);
19811 } else if (!strcasecmp(v->name, "rxwink")) {
19812 confp->timing.rxwinktime = atoi(v->value);
19813 } else if (!strcasecmp(v->name, "rxflash")) {
19814 confp->timing.rxflashtime = atoi(v->value);
19815 } else if (!strcasecmp(v->name, "debounce")) {
19816 confp->timing.debouncetime = atoi(v->value);
19817 } else if (!strcasecmp(v->name, "toneduration")) {
19818 int toneduration;
19819 int ctlfd;
19820 int res;
19821 struct dahdi_dialparams dps;
19822
19823 ctlfd = open("/dev/dahdi/ctl", O_RDWR);
19824 if (ctlfd == -1) {
19825 ast_log(LOG_ERROR, "Unable to open /dev/dahdi/ctl to set toneduration at line %d.\n", v->lineno);
19826 return -1;
19827 }
19828
19829 toneduration = atoi(v->value);
19830 if (toneduration > -1) {
19831 memset(&dps, 0, sizeof(dps));
19832
19833 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
19834 res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps);
19835 if (res < 0) {
19836 ast_log(LOG_ERROR, "Invalid tone duration: %d ms at line %d: %s\n", toneduration, v->lineno, strerror(errno));
19837 close(ctlfd);
19838 return -1;
19839 }
19840 }
19841 close(ctlfd);
19842 } else if (!strcasecmp(v->name, "defaultcic")) {
19844 } else if (!strcasecmp(v->name, "defaultozz")) {
19846 } else if (!strcasecmp(v->name, "mwilevel")) {
19847 mwilevel = atoi(v->value);
19848 } else if (!strcasecmp(v->name, "dtmfcidlevel")) {
19849 dtmfcid_level = atoi(v->value);
19850 } else if (!strcasecmp(v->name, "reportalarms")) {
19851 if (!strcasecmp(v->value, "all"))
19853 if (!strcasecmp(v->value, "none"))
19854 report_alarms = 0;
19855 else if (!strcasecmp(v->value, "channels"))
19857 else if (!strcasecmp(v->value, "spans"))
19859 }
19860 } else if (!(options & PROC_DAHDI_OPT_NOWARN) )
19861 ast_log(LOG_NOTICE, "Ignoring any changes to '%s' (on reload) at line %d.\n", v->name, v->lineno);
19862 }
19863
19864 if (dahdichan) {
19865 /* Process the deferred dahdichan value. */
19866 if (build_channels(confp, dahdichan->value, reload, dahdichan->lineno)) {
19867 if (confp->ignore_failed_channels) {
19869 "Dahdichan '%s' failure ignored: ignore_failed_channels.\n",
19870 dahdichan->value);
19871 } else {
19872 return -1;
19873 }
19874 }
19875 }
19876
19877 /*
19878 * Since confp has already filled individual dahdi_pvt objects with channels
19879 * at this point, clear the variables in confp's pvt.
19880 */
19881 if (confp->chan.vars) {
19883 confp->chan.vars = NULL;
19884 }
19885
19886 /* mark the first channels of each DAHDI span to watch for their span alarms */
19887 for (tmp = iflist, y=-1; tmp; tmp = tmp->next) {
19888 if (!tmp->destroy && tmp->span != y) {
19889 tmp->manages_span_alarms = 1;
19890 y = tmp->span;
19891 } else {
19892 tmp->manages_span_alarms = 0;
19893 }
19894 }
19895
19896 /*< \todo why check for the pseudo in the per-channel section.
19897 * Any actual use for manual setup of the pseudo channel? */
19898 if (!has_pseudo && reload != 1 && !(options & PROC_DAHDI_OPT_NOCHAN)) {
19899 /* use the default configuration for a channel, so
19900 that any settings from real configured channels
19901 don't "leak" into the pseudo channel config
19902 */
19904
19905 if (conf.chan.cc_params) {
19907 } else {
19908 tmp = NULL;
19909 }
19910 if (tmp) {
19911 ast_verb(3, "Automatically generated pseudo channel\n");
19912 has_pseudo = 1;
19913 } else {
19914 ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
19915 }
19916 ast_cc_config_params_destroy(conf.chan.cc_params);
19917 }
19918
19919 /* Since named callgroup and named pickup group are ref'd to dahdi_pvt at this point, unref container in confp's pvt. */
19922
19923 return 0;
19924}
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
Definition: abstract_jb.c:545
static int copy(char *infile, char *outfile)
Utility function to copy a file.
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1292
int ast_cc_is_config_param(const char *const name)
Is this a CCSS configuration parameter?
Definition: ccss.c:840
int ast_cc_set_param(struct ast_cc_config_params *params, const char *const name, const char *value)
set a CCSS configuration parameter, given its name
Definition: ccss.c:801
static int build_channels(struct dahdi_chan_conf *conf, const char *value, int reload, int lineno)
Definition: chan_dahdi.c:18238
static int user_has_defined_cadences
Definition: chan_dahdi.c:686
#define PROC_DAHDI_OPT_NOCHAN
Definition: chan_dahdi.c:18432
static void parse_busy_pattern(struct ast_variable *v, struct ast_dsp_busy_pattern *busy_cadence)
Definition: chan_dahdi.c:18436
static char defaultcic[64]
Definition: chan_dahdi.c:717
static void process_echocancel(struct dahdi_chan_conf *confp, const char *data, unsigned int line)
Definition: chan_dahdi.c:18299
#define DEFAULT_DIALTONE_DETECT_TIMEOUT
Definition: chan_dahdi.c:805
#define PROC_DAHDI_OPT_NOWARN
Definition: chan_dahdi.c:18434
static char defaultozz[64]
Definition: chan_dahdi.c:718
#define NUM_CADENCE_MAX
Definition: chan_dahdi.c:684
static struct ast_timer * timer
Definition: chan_iax2.c:364
struct ast_namedgroups * ast_get_namedgroups(const char *s)
Create an ast_namedgroups set with group names from comma separated string.
Definition: channel.c:7675
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition: channel.c:4360
ast_group_t ast_get_group(const char *s)
Definition: channel.c:7618
char * strcasestr(const char *, const char *)
@ SIG_PRI_COLP_CONNECT
Definition: sig_pri.h:439
@ SIG_PRI_COLP_BLOCK
Definition: sig_pri.h:437
#define DAHDI_OVERLAPDIAL_BOTH
Definition: sig_pri.h:254
#define SIG_PRI_AOC_GRANT_D
Definition: sig_pri.h:54
#define DAHDI_OVERLAPDIAL_NONE
Definition: sig_pri.h:251
#define DAHDI_CHAN_MAPPING_LOGICAL
Definition: sig_pri.h:248
@ SIG_PRI_MOH_SIGNALING_MOH
Definition: sig_pri.h:75
@ SIG_PRI_MOH_SIGNALING_NOTIFY
Definition: sig_pri.h:77
#define SIG_PRI_AOC_GRANT_E
Definition: sig_pri.h:55
#define SIG_PRI_AOC_GRANT_S
Definition: sig_pri.h:53
#define LINKSET_FLAG_EXPLICITACM
Definition: sig_ss7.h:68
#define LINKSET_FLAG_AUTOACM
Definition: sig_ss7.h:72
#define LINKSET_FLAG_DEFAULTECHOCONTROL
Definition: sig_ss7.h:71
#define LINKSET_FLAG_USEECHOCONTROL
Definition: sig_ss7.h:70
#define SS7_NAI_DYNAMIC
Definition: sig_ss7.h:66
char smdi_port[SMDI_MAX_FILENAME_LEN]
The serial port to listen for SMDI data on.
Definition: chan_dahdi.c:974
int ignore_failed_channels
Definition: chan_dahdi.c:968
struct dahdi_params timing
Definition: chan_dahdi.c:965
unsigned int immediatering
TRUE if audible ringback should be provided when immediate = yes.
Definition: chan_dahdi.h:322
unsigned int threewaysilenthold
TRUE if a three way dial tone should time out to silence.
Definition: chan_dahdi.h:373
unsigned int hwtxgain_enabled
TRUE if hardware Tx gain set by Asterisk.
Definition: chan_dahdi.h:469
unsigned int ani_wink_time
INTEGER, length of time to wait before sending ANI wink in ms.
Definition: chan_dahdi.h:200
unsigned int use_callingpres
TRUE if we will use the calling presentation setting from the Asterisk channel for outgoing calls.
Definition: chan_dahdi.h:397
unsigned int priexclusive
TRUE if PRI B channels are always exclusively selected.
Definition: chan_dahdi.h:349
float hwrxgain
Hardware Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:154
int tonezone
Definition: chan_dahdi.h:167
float hwtxgain
Hardware Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:156
char description[32]
A description for the channel configuration.
Definition: chan_dahdi.h:496
unsigned int hwrxgain_enabled
TRUE if hardware Rx gain set by Asterisk.
Definition: chan_dahdi.h:467
unsigned int ani_timeout
INTEGER, length of ANI failure timeout in ms.
Definition: chan_dahdi.h:195
unsigned int restrictcid
TRUE if caller ID is restricted.
Definition: chan_dahdi.h:363
unsigned int priindication_oob
TRUE if PRI congestion/busy indications are sent out-of-band.
Definition: chan_dahdi.h:344
unsigned int ani_info_digits
INTEGER, number of ANI INFO digits on a CAMA trunk. older switches use 1 INFO digit,...
Definition: chan_dahdi.h:190
unsigned int hidecalleridname
TRUE if hide just the name not the number for legacy PBX use.
Definition: chan_dahdi.h:308
unsigned int echocanbridged
TRUE if echo cancellation enabled when bridged.
Definition: chan_dahdi.h:270
unsigned int calledsubscriberheld
TRUE if Called Subscriber held is enabled. This allows a single incoming call to hold a DAHDI channel...
Definition: chan_dahdi.h:213
static struct test_options options

References dahdi_pvt::accountcode, dahdi_pvt::adsi, dahdi_pvt::amaflags, ANALOG_DIALMODE_BOTH, ANALOG_DIALMODE_DTMF, ANALOG_DIALMODE_NONE, ANALOG_DIALMODE_PULSE, ANALOG_FIRST_DIGIT_TIMEOUT, ANALOG_INTER_DIGIT_TIMEOUT, ANALOG_MATCH_DIGIT_TIMEOUT, dahdi_pvt::ani_info_digits, dahdi_pvt::ani_timeout, dahdi_pvt::ani_wink_time, dahdi_pvt::answeronpolarityswitch, ARRAY_LEN, ast_callerid_split(), ast_cc_config_params_destroy(), ast_cc_is_config_param(), ast_cc_set_param(), ast_channel_string2amaflag(), ast_copy_string(), ast_debug, ast_false(), ast_get_group(), ast_get_namedgroups(), ast_jb_read_conf(), ast_log, AST_MAX_EXTENSION, ast_strlen_zero(), ast_true(), ast_unref_namedgroups(), ast_variable_list_replace(), ast_variable_new, ast_variables_destroy(), ast_verb, dahdi_pvt::buf_no, dahdi_pvt::buf_policy, build_channels(), dahdi_pvt::busy_cadence, dahdi_pvt::busycount, dahdi_pvt::busydetect, c, cadences, dahdi_pvt::calledsubscriberheld, dahdi_pvt::callgroup, dahdi_pvt::callprogress, CALLPROGRESS_FAX_INCOMING, CALLPROGRESS_FAX_OUTGOING, CALLPROGRESS_PROGRESS, dahdi_pvt::callreturn, dahdi_pvt::callwaiting, dahdi_pvt::callwaitingcallerid, dahdi_pvt::cancallforward, dahdi_pvt::canpark, dahdi_pvt::cc_params, dahdi_chan_conf::chan, CHAN_PSEUDO, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_rxgain, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, dahdi_pvt::cid_signalling, dahdi_pvt::cid_start, CID_START_DTMF_NOALERT, CID_START_POLARITY, CID_START_POLARITY_IN, CID_START_RING, dahdi_pvt::cid_tag, cidrings, dahdi_pvt::context, ringContextData::contextData, copy(), dahdi_chan_conf_default(), DAHDI_CHAN_MAPPING_LOGICAL, DAHDI_CHAN_MAPPING_PHYSICAL, DAHDI_OVERLAPDIAL_BOTH, DAHDI_OVERLAPDIAL_INCOMING, DAHDI_OVERLAPDIAL_NONE, DAHDI_OVERLAPDIAL_OUTGOING, dahdi_pvt::dahditrcallerid, DEFAULT_DIALTONE_DETECT_TIMEOUT, defaultcic, defaultozz, dahdi_pvt::description, dahdi_pvt::dialmode, dahdi_pvt::dialtone_detect, distinctiveringaftercid, dahdi_pvt::drings, DSP_DIGITMODE_RELAXDTMF, dtmfcid_level, dahdi_pvt::dtmfrelax, dahdi_pvt::echocanbridged, dahdi_pvt::echotraining, errno, dahdi_pvt::faxbuf_no, dahdi_pvt::faxbuf_policy, dahdi_pvt::faxdetect_timeout, dahdi_pvt::firstdigit_timeout, global_jbconf, dahdi_pvt::group, dahdi_pvt::hanguponpolarityswitch, has_pseudo, dahdi_pvt::hidecallerid, dahdi_pvt::hidecalleridname, dahdi_pvt::hwrxgain, dahdi_pvt::hwrxgain_enabled, dahdi_pvt::hwtxgain, dahdi_pvt::hwtxgain_enabled, iflist, dahdi_chan_conf::ignore_failed_channels, dahdi_pvt::immediate, dahdi_pvt::immediatering, dahdi_pvt::interdigit_timeout, dahdi_chan_conf::is_sig_auto, dahdi_pvt::language, ast_variable::lineno, LINKSET_FLAG_AUTOACM, LINKSET_FLAG_DEFAULTECHOCONTROL, LINKSET_FLAG_EXPLICITACM, LINKSET_FLAG_INITIALHWBLO, LINKSET_FLAG_USEECHOCONTROL, LOG_ERROR, LOG_NOTICE, LOG_WARNING, dahdi_pvt::mailbox, dahdi_pvt::matchdigit_timeout, mkintf(), dahdi_pvt::mohinterpret, dahdi_pvt::mohsuggest, mwilevel, dahdi_pvt::mwimonitor_fsk, dahdi_pvt::mwimonitor_neon, dahdi_pvt::mwimonitor_rpas, mwimonitornotify, mwisend_rpas, ast_variable::name, dahdi_pvt::named_callgroups, dahdi_pvt::named_pickupgroups, ast_variable::next, NULL, num_cadence, NUM_CADENCE_MAX, NUM_SPANS, numbufs, options, dahdi_pvt::outsigmod, dahdi_pvt::parkinglot, parse_buffers_policy(), parse_busy_pattern(), dahdi_pvt::pickupgroup, dahdi_pvt::polarityonanswerdelay, dahdi_pvt::priexclusive, dahdi_pvt::priindication_oob, PROC_DAHDI_OPT_NOCHAN, PROC_DAHDI_OPT_NOWARN, process_echocancel(), progzone, dahdi_pvt::pulse, dahdi_pvt::radio, distRingData::range, READ_SIZE, reload(), dahdi_pvt::reoriginate, report_alarms, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, dahdi_pvt::restrictcid, distRingData::ring, dahdi_distRings::ringContext, dahdi_distRings::ringnum, ringt_base, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, dahdi_pvt::sendcalleridafter, dahdi_pvt::sig, SIG_BRI, SIG_BRI_PTMP, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSGS, SIG_FXSKS, SIG_FXSLS, SIG_MFCR2, SIG_PRI, SIG_PRI_AOC_GRANT_D, SIG_PRI_AOC_GRANT_E, SIG_PRI_AOC_GRANT_S, SIG_PRI_COLP_BLOCK, SIG_PRI_COLP_CONNECT, SIG_PRI_COLP_UPDATE, SIG_PRI_MOH_SIGNALING_MOH, SIG_PRI_MOH_SIGNALING_NOTIFY, SIG_SF, SIG_SF_FEATB, SIG_SFWINK, SIG_SS7, dahdi_chan_conf::smdi_port, SS7_NAI_DYNAMIC, strcasestr(), dahdi_pvt::stripmsd, strsep(), dahdi_pvt::threewaycalling, dahdi_pvt::threewaysilenthold, timer, dahdi_chan_conf::timing, tmp(), dahdi_pvt::tonezone, dahdi_pvt::transfer, dahdi_pvt::transfertobusy, dahdi_pvt::txdrc, dahdi_pvt::txgain, dahdi_pvt::use_callerid, dahdi_pvt::use_callingpres, dahdi_pvt::use_smdi, usedistinctiveringdetection, dahdi_pvt::usefaxbuffers, user_has_defined_cadences, ast_variable::value, dahdi_pvt::vars, and dahdi_pvt::waitfordialtone.

Referenced by setup_dahdi_int().

◆ process_echocancel()

static void process_echocancel ( struct dahdi_chan_conf confp,
const char *  data,
unsigned int  line 
)
static

Definition at line 18299 of file chan_dahdi.c.

18300{
18301 char *parse = ast_strdupa(data);
18302 char *params[DAHDI_MAX_ECHOCANPARAMS + 1];
18303 unsigned int param_count;
18304 unsigned int x;
18305
18306 if (!(param_count = ast_app_separate_args(parse, ',', params, ARRAY_LEN(params))))
18307 return;
18308
18309 memset(&confp->chan.echocancel, 0, sizeof(confp->chan.echocancel));
18310
18311 /* first parameter is tap length, process it here */
18312
18313 x = ast_strlen_zero(params[0]) ? 0 : atoi(params[0]);
18314
18315 if ((x == 32) || (x == 64) || (x == 128) || (x == 256) || (x == 512) || (x == 1024))
18316 confp->chan.echocancel.head.tap_length = x;
18317 else if ((confp->chan.echocancel.head.tap_length = ast_true(params[0])))
18318 confp->chan.echocancel.head.tap_length = 128;
18319
18320 /* now process any remaining parameters */
18321
18322 for (x = 1; x < param_count; x++) {
18323 struct {
18324 char *name;
18325 char *value;
18326 } param;
18327
18328 if (ast_app_separate_args(params[x], '=', (char **) &param, 2) < 1) {
18329 ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %u: '%s'\n", line, params[x]);
18330 continue;
18331 }
18332
18333 if (ast_strlen_zero(param.name) || (strlen(param.name) > sizeof(confp->chan.echocancel.params[0].name)-1)) {
18334 ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %u: '%s'\n", line, param.name);
18335 continue;
18336 }
18337
18338 strcpy(confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].name, param.name);
18339
18340 if (param.value) {
18341 if (sscanf(param.value, "%30d", &confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].value) != 1) {
18342 ast_log(LOG_WARNING, "Invalid echocancel parameter value supplied at line %u: '%s'\n", line, param.value);
18343 continue;
18344 }
18345 }
18346 confp->chan.echocancel.head.param_count++;
18347 }
18348}
#define ast_app_separate_args(a, b, c, d)
struct dahdi_echocanparam params[DAHDI_MAX_ECHOCANPARAMS]
Definition: chan_dahdi.h:628

References ARRAY_LEN, ast_app_separate_args, ast_log, ast_strdupa, ast_strlen_zero(), ast_true(), dahdi_chan_conf::chan, dahdi_pvt::echocancel, dahdi_pvt::head, LOG_WARNING, name, dahdi_pvt::params, and value.

Referenced by process_dahdi().

◆ publish_channel_alarm()

static void publish_channel_alarm ( int  channel,
const char *  alarm_txt 
)
static

Definition at line 7708 of file chan_dahdi.c.

7709{
7710 RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
7711 RAII_VAR(struct ast_str *, dahdi_chan, ast_str_create(32), ast_free);
7712 if (!dahdi_chan) {
7713 return;
7714 }
7715
7716 ast_str_set(&dahdi_chan, 0, "%d", channel);
7717 body = ast_json_pack("{s: s, s: s}",
7718 "DAHDIChannel", ast_str_buffer(dahdi_chan),
7719 "Alarm", alarm_txt);
7720 if (!body) {
7721 return;
7722 }
7723
7725}
void ast_manager_publish_event(const char *type, int class_type, struct ast_json *obj)
Publish an event to AMI.
Definition: manager.c:2063
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612

References ast_free, ast_json_pack(), ast_json_unref(), ast_manager_publish_event(), ast_str_buffer(), ast_str_create, ast_str_set(), EVENT_FLAG_SYSTEM, NULL, and RAII_VAR.

Referenced by handle_alarms().

◆ publish_channel_alarm_clear()

static void publish_channel_alarm_clear ( int  channel)
static

Definition at line 3765 of file chan_dahdi.c.

3766{
3767 RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
3768 RAII_VAR(struct ast_str *, dahdi_chan, ast_str_create(32), ast_free);
3769 if (!dahdi_chan) {
3770 return;
3771 }
3772
3773 ast_str_set(&dahdi_chan, 0, "%d", channel);
3774 ast_log(LOG_NOTICE, "Alarm cleared on channel DAHDI/%d\n", channel);
3775 body = ast_json_pack("{s: s}", "DAHDIChannel", ast_str_buffer(dahdi_chan));
3776 if (!body) {
3777 return;
3778 }
3779
3780 ast_manager_publish_event("AlarmClear", EVENT_FLAG_SYSTEM, body);
3781}

References ast_free, ast_json_pack(), ast_json_unref(), ast_log, ast_manager_publish_event(), ast_str_buffer(), ast_str_create, ast_str_set(), dahdi_pvt::channel, EVENT_FLAG_SYSTEM, LOG_NOTICE, NULL, and RAII_VAR.

Referenced by handle_clear_alarms().

◆ publish_dahdichannel()

static void publish_dahdichannel ( struct ast_channel chan,
ast_group_t  group,
int  span,
const char *  dahdi_channel 
)
static

Sends a DAHDIChannel channel blob used to produce DAHDIChannel AMI messages.

Definition at line 1941 of file chan_dahdi.c.

1942{
1943 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
1944
1945 ast_assert(dahdi_channel != NULL);
1946
1947 blob = ast_json_pack("{s: I, s: i, s: s}",
1948 "group", (ast_json_int_t)group,
1949 "span", span,
1950 "channel", dahdi_channel);
1951 if (!blob) {
1952 return;
1953 }
1954
1955 ast_channel_lock(chan);
1956 ast_channel_publish_blob(chan, dahdichannel_type(), blob);
1957 ast_channel_unlock(chan);
1958}
void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message.
AST_JSON_INT_T ast_json_int_t
Primarily used to cast when packing to an "I" type.
Definition: json.h:87
#define ast_assert(a)
Definition: utils.h:739

References ast_assert, ast_channel_lock, ast_channel_publish_blob(), ast_channel_unlock, ast_json_pack(), ast_json_unref(), NULL, and RAII_VAR.

Referenced by dahdi_ami_channel_event().

◆ publish_dnd_state()

static void publish_dnd_state ( int  channel,
const char *  status 
)
static

Definition at line 9814 of file chan_dahdi.c.

9815{
9816 RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
9817 RAII_VAR(struct ast_str *, dahdichan, ast_str_create(32), ast_free);
9818 if (!dahdichan) {
9819 return;
9820 }
9821
9822 ast_str_set(&dahdichan, 0, "%d", channel);
9823
9824 body = ast_json_pack("{s: s, s: s}",
9825 "DAHDIChannel", ast_str_buffer(dahdichan),
9826 "Status", status);
9827 if (!body) {
9828 return;
9829 }
9830
9832}
jack_status_t status
Definition: app_jack.c:146

References ast_free, ast_json_pack(), ast_json_unref(), ast_manager_publish_event(), ast_str_buffer(), ast_str_create, ast_str_set(), EVENT_FLAG_SYSTEM, NULL, RAII_VAR, and status.

Referenced by dahdi_dnd().

◆ publish_span_alarm()

static void publish_span_alarm ( int  span,
const char *  alarm_txt 
)
static

Definition at line 7694 of file chan_dahdi.c.

7695{
7696 RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
7697
7698 body = ast_json_pack("{s: i, s: s}",
7699 "Span", span,
7700 "Alarm", alarm_txt);
7701 if (!body) {
7702 return;
7703 }
7704
7705 ast_manager_publish_event("SpanAlarm", EVENT_FLAG_SYSTEM, body);
7706}

References ast_json_pack(), ast_json_unref(), ast_manager_publish_event(), EVENT_FLAG_SYSTEM, NULL, and RAII_VAR.

Referenced by handle_alarms().

◆ publish_span_alarm_clear()

static void publish_span_alarm_clear ( int  span)
static

Definition at line 3783 of file chan_dahdi.c.

3784{
3785 RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
3786
3787 ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", span);
3788 body = ast_json_pack("{s: i}", "Span", span);
3789 if (!body) {
3790 return;
3791 }
3792
3793 ast_manager_publish_event("SpanAlarmClear", EVENT_FLAG_SYSTEM, body);
3794}

References ast_json_pack(), ast_json_unref(), ast_log, ast_manager_publish_event(), EVENT_FLAG_SYSTEM, LOG_NOTICE, NULL, RAII_VAR, and dahdi_pvt::span.

Referenced by handle_clear_alarms().

◆ release_doomed_pris()

static void release_doomed_pris ( void  )
static

Definition at line 1283 of file chan_dahdi.c.

1284{
1285#ifdef HAVE_PRI
1286 struct doomed_pri *entry;
1287
1288 AST_LIST_LOCK(&doomed_pris);
1289 while ((entry = AST_LIST_REMOVE_HEAD(&doomed_pris, list))) {
1290 /* The span destruction must be done with this lock not held */
1291 AST_LIST_UNLOCK(&doomed_pris);
1292 ast_debug(4, "Destroying span %d from doomed queue.\n",
1293 entry->pri->span);
1294 pri_destroy_span(entry->pri);
1295 ast_free(entry);
1296 AST_LIST_LOCK(&doomed_pris);
1297 }
1298 AST_LIST_UNLOCK(&doomed_pris);
1299#endif
1300}
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
Definition: search.h:40

References ast_debug, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.

Referenced by do_monitor().

◆ reload()

static int reload ( void  )
static

Definition at line 20509 of file chan_dahdi.c.

20510{
20511 int res = 0;
20512
20513 res = setup_dahdi(1);
20514 if (res) {
20515 ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n");
20516 return -1;
20517 }
20518 return 0;
20519}

References ast_log, LOG_WARNING, and setup_dahdi().

Referenced by build_channels(), process_dahdi(), setup_dahdi(), and setup_dahdi_int().

◆ reset_conf()

static int reset_conf ( struct dahdi_pvt p)
static

Definition at line 4829 of file chan_dahdi.c.

4830{
4831 p->confno = -1;
4832 memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
4833 if (p->subs[SUB_REAL].dfd > -1) {
4834 struct dahdi_confinfo zi;
4835
4836 memset(&zi, 0, sizeof(zi));
4837 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi))
4838 ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno));
4839 }
4840 return 0;
4841}

References ast_log, dahdi_pvt::channel, dahdi_pvt::confno, dahdi_subchannel::curconf, dahdi_subchannel::dfd, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_hangup(), and my_all_subchannels_hungup().

◆ restart_monitor()

static int restart_monitor ( void  )
static

Definition at line 12168 of file chan_dahdi.c.

12169{
12170 /* If we're supposed to be stopped -- stay stopped */
12172 return 0;
12174 if (monitor_thread == pthread_self()) {
12176 ast_log(LOG_WARNING, "Cannot kill myself\n");
12177 return -1;
12178 }
12180 /* Wake up the thread */
12181 pthread_kill(monitor_thread, SIGURG);
12182 } else {
12183 /* Start a new monitor */
12186 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
12187 return -1;
12188 }
12189 }
12191 return 0;
12192}
static void * do_monitor(void *data)
Definition: chan_dahdi.c:11859

References ast_log, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, monitor_thread, monlock, and NULL.

Referenced by dahdi_hangup(), dahdi_request(), my_all_subchannels_hungup(), and setup_dahdi_int().

◆ restore_conference()

static int restore_conference ( struct dahdi_pvt p)
static

Definition at line 5262 of file chan_dahdi.c.

5263{
5264 int res;
5265 if (p->saveconf.confmode) {
5266 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf);
5267 p->saveconf.confmode = 0;
5268 if (res) {
5269 ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
5270 return -1;
5271 }
5272 ast_debug(1, "Restored conferencing\n");
5273 }
5274 return 0;
5275}
struct dahdi_confinfo saveconf
Definition: chan_dahdi.h:132

References ast_debug, ast_log, dahdi_subchannel::dfd, errno, LOG_WARNING, dahdi_pvt::saveconf, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_handle_event(), dahdi_read(), handle_init_event(), my_cancel_cidspill(), and send_callerid().

◆ restore_gains()

static int restore_gains ( struct dahdi_pvt p)
static

Definition at line 5169 of file chan_dahdi.c.

5170{
5171 int res;
5172
5173 res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
5174 if (res) {
5175 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
5176 return -1;
5177 }
5178
5179 return 0;
5180}

References ast_log, dahdi_subchannel::dfd, errno, dahdi_pvt::law, LOG_WARNING, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, set_actual_gain(), SUB_REAL, dahdi_pvt::subs, dahdi_pvt::txdrc, and dahdi_pvt::txgain.

Referenced by analog_ss_thread(), dahdi_hangup(), mwi_thread(), and my_stop_cid_detect().

◆ revert_fax_buffers()

static int revert_fax_buffers ( struct dahdi_pvt p,
struct ast_channel ast 
)
static

Definition at line 6228 of file chan_dahdi.c.

6229{
6230 if (p->bufferoverrideinuse) {
6231 /* faxbuffers are in use, revert them */
6232 struct dahdi_bufferinfo bi = {
6233 .txbufpolicy = p->buf_policy,
6234 .rxbufpolicy = p->buf_policy,
6235 .bufsize = p->bufsize,
6236 .numbufs = p->buf_no
6237 };
6238 int bpres;
6239
6240 if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
6241 ast_log(LOG_WARNING, "Channel '%s' unable to revert buffer policy: %s\n", ast_channel_name(ast), strerror(errno));
6242 }
6243 p->bufferoverrideinuse = 0;
6244 return bpres;
6245 }
6246
6247 return -1;
6248}

References ast_channel_name(), ast_log, dahdi_pvt::buf_no, dahdi_pvt::buf_policy, dahdi_pvt::bufferoverrideinuse, dahdi_pvt::bufsize, dahdi_subchannel::dfd, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_hangup().

◆ save_conference()

static int save_conference ( struct dahdi_pvt p)
static

Definition at line 5236 of file chan_dahdi.c.

5237{
5238 struct dahdi_confinfo c;
5239 int res;
5240 if (p->saveconf.confmode) {
5241 ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
5242 return -1;
5243 }
5244 p->saveconf.chan = 0;
5245 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf);
5246 if (res) {
5247 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
5248 p->saveconf.confmode = 0;
5249 return -1;
5250 }
5251 memset(&c, 0, sizeof(c));
5252 c.confmode = DAHDI_CONF_NORMAL;
5253 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c);
5254 if (res) {
5255 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
5256 return -1;
5257 }
5258 ast_debug(1, "Disabled conferencing\n");
5259 return 0;
5260}

References ast_debug, ast_log, c, dahdi_subchannel::dfd, errno, LOG_WARNING, dahdi_pvt::saveconf, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_callwait(), dahdi_handle_event(), and my_callwait().

◆ send_callerid()

static int send_callerid ( struct dahdi_pvt p)
static

Definition at line 5323 of file chan_dahdi.c.

5324{
5325 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
5326 int res;
5327 /* Take out of linear mode if necessary */
5328 if (p->subs[SUB_REAL].linear) {
5329 p->subs[SUB_REAL].linear = 0;
5331 }
5332 while (p->cidpos < p->cidlen) {
5333 res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
5334 ast_debug(4, "writing callerid at pos %d of %d, res = %d\n", p->cidpos, p->cidlen, res);
5335 if (res < 0) {
5336 if (errno == EAGAIN)
5337 return 0;
5338 else {
5339 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
5340 return -1;
5341 }
5342 }
5343 if (!res)
5344 return 0;
5345 p->cidpos += res;
5346 }
5348 ast_free(p->cidspill);
5349 p->cidspill = NULL;
5350 if (p->callwaitcas) {
5351 /* Wait for CID/CW to expire */
5354 } else
5356 return 0;
5357}
#define CALLWAITING_SUPPRESS_SAMPLES
Definition: chan_dahdi.c:801
#define CIDCW_EXPIRE_SAMPLES
Definition: chan_dahdi.c:802

References ast_debug, ast_free, ast_log, dahdi_pvt::callwaitcas, CALLWAITING_SUPPRESS_SAMPLES, dahdi_pvt::cid_suppress_expire, CIDCW_EXPIRE_SAMPLES, dahdi_pvt::cidcwexpire, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, dahdi_setlinear(), dahdi_subchannel::dfd, errno, dahdi_subchannel::linear, LOG_WARNING, NULL, restore_conference(), SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_callwait(), dahdi_read(), my_callwait(), my_send_callerid(), and send_cwcidspill().

◆ send_cwcidspill()

static int send_cwcidspill ( struct dahdi_pvt p)
static

Definition at line 5277 of file chan_dahdi.c.

5278{
5279 p->callwaitcas = 0;
5280 p->cidcwexpire = 0;
5281 p->cid_suppress_expire = 0;
5283 return -1;
5285 /* Make sure we account for the end */
5286 p->cidlen += READ_SIZE * 4;
5287 p->cidpos = 0;
5288 send_callerid(p);
5289 ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
5290 return 0;
5291}
int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)
Definition: callerid.c:1242
char callwait_num[AST_MAX_EXTENSION]
Call waiting number.
Definition: chan_dahdi.h:541
char callwait_name[AST_MAX_EXTENSION]
Call waiting name.
Definition: chan_dahdi.h:543

References ast_callerid_callwaiting_generate(), AST_LAW, ast_malloc, ast_verb, dahdi_pvt::callwait_name, dahdi_pvt::callwait_num, dahdi_pvt::callwaitcas, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cidcwexpire, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, MAX_CALLERID_SIZE, READ_SIZE, and send_callerid().

Referenced by dahdi_handle_dtmf().

◆ set_actual_gain()

static int set_actual_gain ( int  fd,
float  rxgain,
float  txgain,
float  rxdrc,
float  txdrc,
int  law 
)
static

Definition at line 5150 of file chan_dahdi.c.

5151{
5152 return set_actual_txgain(fd, txgain, txdrc, law) | set_actual_rxgain(fd, rxgain, rxdrc, law);
5153}

References set_actual_rxgain(), and set_actual_txgain().

Referenced by bump_gains(), dahdi_call(), mkintf(), and restore_gains().

◆ set_actual_rxgain()

static int set_actual_rxgain ( int  fd,
float  gain,
float  drc,
int  law 
)
static

Definition at line 5133 of file chan_dahdi.c.

5134{
5135 struct dahdi_gains g;
5136 int res;
5137
5138 memset(&g, 0, sizeof(g));
5139 res = ioctl(fd, DAHDI_GETGAINS, &g);
5140 if (res) {
5141 ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
5142 return res;
5143 }
5144
5145 fill_rxgain(&g, gain, drc, law);
5146
5147 return ioctl(fd, DAHDI_SETGAINS, &g);
5148}
static void fill_rxgain(struct dahdi_gains *g, float gain, float drc, int law)
Definition: chan_dahdi.c:5068

References ast_debug, errno, and fill_rxgain().

Referenced by dahdi_set_swgain(), dahdi_setoption(), and set_actual_gain().

◆ set_actual_txgain()

static int set_actual_txgain ( int  fd,
float  gain,
float  drc,
int  law 
)
static

Definition at line 5116 of file chan_dahdi.c.

5117{
5118 struct dahdi_gains g;
5119 int res;
5120
5121 memset(&g, 0, sizeof(g));
5122 res = ioctl(fd, DAHDI_GETGAINS, &g);
5123 if (res) {
5124 ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
5125 return res;
5126 }
5127
5128 fill_txgain(&g, gain, drc, law);
5129
5130 return ioctl(fd, DAHDI_SETGAINS, &g);
5131}
static void fill_txgain(struct dahdi_gains *g, float gain, float drc, int law)
Definition: chan_dahdi.c:5018

References ast_debug, errno, and fill_txgain().

Referenced by dahdi_set_swgain(), dahdi_setoption(), and set_actual_gain().

◆ set_hwgain()

static int set_hwgain ( int  fd,
float  gain,
int  tx_direction 
)
static

Definition at line 4988 of file chan_dahdi.c.

4989{
4990 struct dahdi_hwgain hwgain;
4991
4992 hwgain.newgain = gain * 10.0;
4993 hwgain.tx = tx_direction;
4994 return ioctl(fd, DAHDI_SET_HWGAIN, &hwgain) < 0;
4995}

Referenced by dahdi_set_hwgain(), and mkintf().

◆ setup_dahdi()

static int setup_dahdi ( int  reload)
static

Definition at line 20250 of file chan_dahdi.c.

20251{
20252 int res;
20253 struct dahdi_chan_conf default_conf = dahdi_chan_conf_default();
20254 struct dahdi_chan_conf base_conf = dahdi_chan_conf_default();
20256
20257 if (default_conf.chan.cc_params && base_conf.chan.cc_params && conf.chan.cc_params) {
20258 res = setup_dahdi_int(reload, &default_conf, &base_conf, &conf);
20259 } else {
20260 res = -1;
20261 }
20264 ast_cc_config_params_destroy(conf.chan.cc_params);
20265
20266 return res;
20267}

References ast_cc_config_params_destroy(), dahdi_pvt::cc_params, dahdi_chan_conf::chan, dahdi_chan_conf_default(), reload(), and setup_dahdi_int().

Referenced by dahdi_restart(), load_module(), and reload().

◆ setup_dahdi_int()

static int setup_dahdi_int ( int  reload,
struct dahdi_chan_conf default_conf,
struct dahdi_chan_conf base_conf,
struct dahdi_chan_conf conf 
)
static

Definition at line 19956 of file chan_dahdi.c.

19957{
19958 struct ast_config *cfg;
19959 struct ast_config *ucfg;
19960 struct ast_variable *v;
19961 struct ast_flags config_flags = { reload == 1 ? CONFIG_FLAG_FILEUNCHANGED : 0 };
19962 const char *chans;
19963 const char *cat;
19964 int res;
19965
19966#ifdef HAVE_PRI
19967 char *c;
19968 int spanno;
19969 int i;
19970 int logicalspan;
19971 int trunkgroup;
19972 int dchannels[SIG_PRI_NUM_DCHANS];
19973#endif
19974 int have_cfg_now;
19975 static int had_cfg_before = 1;/* So initial load will complain if we don't have cfg. */
19976
19977 cfg = ast_config_load(config, config_flags);
19978 have_cfg_now = !!cfg;
19979 if (!cfg) {
19980 /* Error if we have no config file */
19981 if (had_cfg_before) {
19982 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
19984 }
19985 cfg = ast_config_new();/* Dummy config */
19986 if (!cfg) {
19987 return 0;
19988 }
19989 ucfg = ast_config_load("users.conf", config_flags);
19990 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
19991 ast_config_destroy(cfg);
19992 return 0;
19993 }
19994 if (ucfg == CONFIG_STATUS_FILEINVALID) {
19995 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n");
19996 ast_config_destroy(cfg);
19997 return 0;
19998 }
19999 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
20000 ucfg = ast_config_load("users.conf", config_flags);
20001 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
20002 return 0;
20003 }
20004 if (ucfg == CONFIG_STATUS_FILEINVALID) {
20005 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n");
20006 return 0;
20007 }
20009 cfg = ast_config_load(config, config_flags);
20010 have_cfg_now = !!cfg;
20011 if (!cfg) {
20012 if (had_cfg_before) {
20013 /* We should have been able to load the config. */
20014 ast_log(LOG_ERROR, "Bad. Unable to load config %s\n", config);
20015 ast_config_destroy(ucfg);
20016 return 0;
20017 }
20018 cfg = ast_config_new();/* Dummy config */
20019 if (!cfg) {
20020 ast_config_destroy(ucfg);
20021 return 0;
20022 }
20023 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
20024 ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config);
20025 ast_config_destroy(ucfg);
20026 return 0;
20027 }
20028 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
20029 ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config);
20030 return 0;
20031 } else {
20033 ucfg = ast_config_load("users.conf", config_flags);
20034 if (ucfg == CONFIG_STATUS_FILEINVALID) {
20035 ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n");
20036 ast_config_destroy(cfg);
20037 return 0;
20038 }
20039 }
20040 had_cfg_before = have_cfg_now;
20041
20042 /* It's a little silly to lock it, but we might as well just to be sure */
20044#ifdef HAVE_PRI
20045 if (reload != 1) {
20046 /* Process trunkgroups first */
20047 v = ast_variable_browse(cfg, "trunkgroups");
20048 while (v) {
20049 if (!strcasecmp(v->name, "trunkgroup")) {
20050 trunkgroup = atoi(v->value);
20051 if (trunkgroup > 0) {
20052 if ((c = strchr(v->value, ','))) {
20053 i = 0;
20054 memset(dchannels, 0, sizeof(dchannels));
20055 while (c && (i < SIG_PRI_NUM_DCHANS)) {
20056 dchannels[i] = atoi(c + 1);
20057 if (dchannels[i] < 0) {
20058 ast_log(LOG_WARNING, "D-channel for trunk group %d must be a postiive number at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
20059 } else
20060 i++;
20061 c = strchr(c + 1, ',');
20062 }
20063 if (i) {
20064 if (pri_create_trunkgroup(trunkgroup, dchannels)) {
20065 ast_log(LOG_WARNING, "Unable to create trunk group %d with Primary D-channel %d at line %d of chan_dahdi.conf\n", trunkgroup, dchannels[0], v->lineno);
20066 } else
20067 ast_verb(2, "Created trunk group %d with Primary D-channel %d and %d backup%s\n", trunkgroup, dchannels[0], i - 1, (i == 1) ? "" : "s");
20068 } else
20069 ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
20070 } else
20071 ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
20072 } else
20073 ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->lineno);
20074 } else if (!strcasecmp(v->name, "spanmap")) {
20075 spanno = atoi(v->value);
20076 if (spanno > 0) {
20077 if ((c = strchr(v->value, ','))) {
20078 trunkgroup = atoi(c + 1);
20079 if (trunkgroup > 0) {
20080 if ((c = strchr(c + 1, ',')))
20081 logicalspan = atoi(c + 1);
20082 else
20083 logicalspan = 0;
20084 if (logicalspan >= 0) {
20085 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
20086 ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
20087 } else
20088 ast_verb(2, "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
20089 } else
20090 ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of chan_dahdi.conf\n", v->lineno);
20091 } else
20092 ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of chan_dahdi.conf\n", v->lineno);
20093 } else
20094 ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of chan_dahdi.conf\n", v->lineno);
20095 } else
20096 ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of chan_dahdi.conf\n", v->lineno);
20097 } else {
20098 ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
20099 }
20100 v = v->next;
20101 }
20102 }
20103#endif
20104
20105 /* Copy the default jb config over global_jbconf */
20106 memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf));
20107
20108 mwimonitornotify[0] = '\0';
20109
20110 v = ast_variable_browse(cfg, "channels");
20111 if ((res = process_dahdi(base_conf,
20112 "" /* Must be empty for the channels category. Silly voicemail mailbox. */,
20113 v, reload, 0))) {
20115 ast_config_destroy(cfg);
20116 if (ucfg) {
20117 ast_config_destroy(ucfg);
20118 }
20119 return res;
20120 }
20121
20122 /* Now get configuration from all normal sections in chan_dahdi.conf: */
20123 for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
20124 /* [channels] and [trunkgroups] are used. Let's also reserve
20125 * [globals] and [general] for future use
20126 */
20127 if (!strcasecmp(cat, "general") ||
20128 !strcasecmp(cat, "trunkgroups") ||
20129 !strcasecmp(cat, "globals") ||
20130 !strcasecmp(cat, "channels")) {
20131 continue;
20132 }
20133
20134 chans = ast_variable_retrieve(cfg, cat, "dahdichan");
20135 if (ast_strlen_zero(chans)) {
20136 /* Section is useless without a dahdichan value present. */
20137 continue;
20138 }
20139
20140 /* Copy base_conf to conf. */
20141 deep_copy_dahdi_chan_conf(conf, base_conf);
20142
20143 if ((res = process_dahdi(conf, cat, ast_variable_browse(cfg, cat), reload, PROC_DAHDI_OPT_NOCHAN))) {
20145 ast_config_destroy(cfg);
20146 if (ucfg) {
20147 ast_config_destroy(ucfg);
20148 }
20149 return res;
20150 }
20151 }
20152
20153 ast_config_destroy(cfg);
20154
20155 if (ucfg) {
20156 /* Reset base_conf, so things don't leak from chan_dahdi.conf */
20157 deep_copy_dahdi_chan_conf(base_conf, default_conf);
20158 process_dahdi(base_conf,
20159 "" /* Must be empty for the general category. Silly voicemail mailbox. */,
20160 ast_variable_browse(ucfg, "general"), 1, 0);
20161
20162 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
20163 if (!strcasecmp(cat, "general")) {
20164 continue;
20165 }
20166
20167 chans = ast_variable_retrieve(ucfg, cat, "dahdichan");
20168 if (ast_strlen_zero(chans)) {
20169 /* Section is useless without a dahdichan value present. */
20170 continue;
20171 }
20172
20173 /* Copy base_conf to conf. */
20174 deep_copy_dahdi_chan_conf(conf, base_conf);
20175
20177 ast_config_destroy(ucfg);
20179 return res;
20180 }
20181 }
20182 ast_config_destroy(ucfg);
20183 }
20185
20186#ifdef HAVE_PRI
20187 if (reload != 1) {
20188 int x;
20189 for (x = 0; x < NUM_SPANS; x++) {
20190 if (pris[x].pri.pvts[0] &&
20191 pris[x].pri.master == AST_PTHREADT_NULL) {
20192 prepare_pri(pris + x);
20193 if (sig_pri_start_pri(&pris[x].pri)) {
20194 ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
20195 return -1;
20196 } else
20197 ast_verb(2, "Starting D-Channel on span %d\n", x + 1);
20198 }
20199 }
20200 }
20201#endif
20202#if defined(HAVE_SS7)
20203 if (reload != 1) {
20204 int x;
20205 for (x = 0; x < NUM_SPANS; x++) {
20206 if (linksets[x].ss7.ss7) {
20207 if (ast_pthread_create(&linksets[x].ss7.master, NULL, ss7_linkset, &linksets[x].ss7)) {
20208 ast_log(LOG_ERROR, "Unable to start SS7 linkset on span %d\n", x + 1);
20209 return -1;
20210 } else
20211 ast_verb(2, "Starting SS7 linkset on span %d\n", x + 1);
20212 }
20213 }
20214 }
20215#endif /* defined(HAVE_SS7) */
20216#ifdef HAVE_OPENR2
20217 if (reload != 1) {
20218 struct r2link_entry *cur;
20219 int x = 0;
20220 AST_LIST_LOCK(&r2links);
20221 AST_LIST_TRAVERSE(&r2links, cur, list) {
20222 struct dahdi_mfcr2 *r2 = &cur->mfcr2;
20223 if (r2->r2master == AST_PTHREADT_NULL) {
20224 if (ast_pthread_create(&r2->r2master, NULL, mfcr2_monitor, r2)) {
20225 ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1);
20226 return -1;
20227 } else {
20228 ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1);
20229 }
20230 x++;
20231 }
20232 }
20233 AST_LIST_UNLOCK(&r2links);
20234 }
20235#endif
20236 /* And start the monitor for the first time */
20238 return 0;
20239}
static struct chans chans
static struct ast_jb_conf default_jbconf
Definition: chan_dahdi.c:618
static const char config[]
Definition: chan_dahdi.c:669
static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct ast_variable *v, int reload, int options)
Definition: chan_dahdi.c:18471
static void deep_copy_dahdi_chan_conf(struct dahdi_chan_conf *dest, const struct dahdi_chan_conf *src)
Definition: chan_dahdi.c:19934
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: extconf.c:3274
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:783
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
@ CONFIG_FLAG_FILEUNCHANGED
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
int sig_pri_start_pri(struct sig_pri_span *pri)
void * ss7_linkset(void *data)
Structure used to handle boolean flags.
Definition: utils.h:199
Definition: astman.c:88
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:584

References ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_config_new(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create, AST_PTHREADT_NULL, ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, c, chans, config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, deep_copy_dahdi_chan_conf(), default_jbconf, global_jbconf, iflock, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sig_pri_span::master, sig_ss7_linkset::master, mwimonitornotify, ast_variable::name, ast_variable::next, NULL, NUM_SPANS, sig_pri_chan::pri, PROC_DAHDI_OPT_NOCHAN, PROC_DAHDI_OPT_NOWARN, process_dahdi(), sig_pri_span::pvts, reload(), restart_monitor(), SIG_PRI_NUM_DCHANS, sig_pri_start_pri(), sig_ss7_linkset::ss7, ss7_linkset(), and ast_variable::value.

Referenced by dahdi_create_channel_range(), and setup_dahdi().

◆ sigtype_to_signalling()

static int sigtype_to_signalling ( int  sigtype)
static

Definition at line 12474 of file chan_dahdi.c.

12475{
12476 return sigtype;
12477}
enum analog_sigtype sigtype
Definition: sig_analog.c:69

References sigtype.

Referenced by mkintf().

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL()

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( dahdichannel_type  ,
to_ami = dahdichannel_to_ami 
)

◆ swap_subs()

static void swap_subs ( struct dahdi_pvt p,
int  a,
int  b 
)
static

Definition at line 4318 of file chan_dahdi.c.

4319{
4320 int tchan;
4321 int tinthreeway;
4322 struct ast_channel *towner;
4323
4324 ast_debug(1, "Swapping %d and %d\n", a, b);
4325
4326 tchan = p->subs[a].chan;
4327 towner = p->subs[a].owner;
4328 tinthreeway = p->subs[a].inthreeway;
4329
4330 p->subs[a].chan = p->subs[b].chan;
4331 p->subs[a].owner = p->subs[b].owner;
4332 p->subs[a].inthreeway = p->subs[b].inthreeway;
4333
4334 p->subs[b].chan = tchan;
4335 p->subs[b].owner = towner;
4336 p->subs[b].inthreeway = tinthreeway;
4337
4338 if (p->subs[a].owner)
4339 ast_channel_set_fd(p->subs[a].owner, 0, p->subs[a].dfd);
4340 if (p->subs[b].owner)
4341 ast_channel_set_fd(p->subs[b].owner, 0, p->subs[b].dfd);
4342 wakeup_sub(p, a);
4343 wakeup_sub(p, b);
4344}

References a, ast_channel_set_fd(), ast_debug, b, dahdi_subchannel::chan, dahdi_subchannel::dfd, dahdi_subchannel::inthreeway, dahdi_subchannel::owner, dahdi_pvt::subs, and wakeup_sub().

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

◆ unalloc_sub()

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

Definition at line 4464 of file chan_dahdi.c.

4465{
4466 if (!x) {
4467 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
4468 return -1;
4469 }
4470 ast_debug(1, "Released sub %d of channel %d\n", x, p->channel);
4471 dahdi_close_sub(p, x);
4472 p->subs[x].linear = 0;
4473 p->subs[x].chan = 0;
4474 p->subs[x].owner = NULL;
4475 p->subs[x].inthreeway = 0;
4477 memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
4478 return 0;
4479}

References ast_debug, ast_log, dahdi_subchannel::chan, dahdi_pvt::channel, dahdi_subchannel::curconf, dahdi_close_sub(), dahdi_subchannel::inthreeway, dahdi_subchannel::linear, LOG_WARNING, NULL, dahdi_subchannel::owner, dahdi_pvt::polarity, POLARITY_IDLE, and dahdi_pvt::subs.

Referenced by analog_ss_thread(), dahdi_handle_event(), dahdi_hangup(), and my_unallocate_sub().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 18222 of file chan_dahdi.c.

18223{
18224#if defined(HAVE_PRI) || defined(HAVE_SS7)
18225 int y;
18226#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
18227#ifdef HAVE_PRI
18228 for (y = 0; y < NUM_SPANS; y++)
18229 ast_mutex_destroy(&pris[y].pri.lock);
18230#endif
18231#if defined(HAVE_SS7)
18232 for (y = 0; y < NUM_SPANS; y++)
18233 ast_mutex_destroy(&linksets[y].ss7.lock);
18234#endif /* defined(HAVE_SS7) */
18235 return __unload_module();
18236}

References __unload_module(), ast_mutex_destroy, sig_pri_span::lock, sig_ss7_linkset::lock, and NUM_SPANS.

◆ wakeup_sub()

static void wakeup_sub ( struct dahdi_pvt p,
int  a 
)
static

Definition at line 3740 of file chan_dahdi.c.

3741{
3743 if (p->subs[a].owner) {
3746 }
3747}
static void dahdi_lock_sub_owner(struct dahdi_pvt *pvt, int sub_idx)
Definition: chan_dahdi.c:3724

References a, ast_channel_unlock, ast_null_frame, ast_queue_frame(), dahdi_lock_sub_owner(), dahdi_subchannel::owner, and dahdi_pvt::subs.

Referenced by my_swap_subchannels(), and swap_subs().

Variable Documentation

◆ __mod_info

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", }
static

Definition at line 20533 of file chan_dahdi.c.

◆ alarm

int alarm

Definition at line 4620 of file chan_dahdi.c.

Referenced by alarm2str().

◆ 

struct { ... } alarms[]

Referenced by alarm2str().

◆ analog_callbacks

struct analog_callback analog_callbacks

Global analog callbacks to the upper layer.

Definition at line 3616 of file chan_dahdi.c.

Referenced by analog_all_subchannels_hungup(), analog_alloc_sub(), analog_answer_polarityswitch(), analog_callwait(), analog_cancel_cidspill(), analog_cb_handle_dtmf(), analog_check_confirmanswer(), analog_check_for_conference(), analog_check_waitingfordt(), analog_confmute(), analog_deadlock_avoidance_private(), analog_decrease_ss_count(), analog_dial_digits(), analog_distinctive_ring(), analog_dsp_reset_and_flush_digits(), analog_dsp_set_digitmode(), analog_flash(), analog_get_and_handle_alarms(), analog_get_bridged_channel(), analog_get_callerid(), analog_get_event(), analog_get_orig_dialstring(), analog_get_sub_fd(), analog_handle_notify_message(), analog_hangup_polarityswitch(), analog_has_voicemail(), analog_have_progressdetect(), analog_increase_ss_count(), analog_is_dialing(), analog_is_off_hook(), analog_lock_private(), analog_new_ast_channel(), analog_off_hook(), analog_on_hook(), analog_play_tone(), analog_ring(), analog_send_callerid(), analog_set_alarm(), analog_set_cadence(), analog_set_callwaiting(), analog_set_confirmanswer(), analog_set_dialing(), analog_set_echocanceller(), analog_set_inthreeway(), analog_set_linear_mode(), analog_set_needringing(), analog_set_new_owner(), analog_set_outgoing(), analog_set_pulsedial(), analog_set_ringtimeout(), analog_set_waitingfordt(), analog_start(), analog_start_cid_detect(), analog_start_polarityswitch(), analog_stop_callwait(), analog_stop_cid_detect(), analog_swap_subs(), analog_train_echocanceller(), analog_unalloc_sub(), analog_unlock_private(), analog_update_conf(), analog_wait_event(), and analog_wink().

◆ AS_RP_cadence

struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}}
static

Definition at line 709 of file chan_dahdi.c.

Referenced by mwi_send_process_buffer().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 20533 of file chan_dahdi.c.

◆ cadences

struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX]
static

◆ cidrings

int cidrings[NUM_CADENCE_MAX]
static

cidrings says in which pause to transmit the cid information, where the first pause is 1, the second pause is 2 and so on.

Definition at line 701 of file chan_dahdi.c.

Referenced by handle_dahdi_show_cadences(), my_set_cadence(), and process_dahdi().

◆ config

const char config[] = "chan_dahdi.conf"
static

Definition at line 669 of file chan_dahdi.c.

Referenced by setup_dahdi_int().

◆ dahdi_cli

struct ast_cli_entry dahdi_cli[]
static

Definition at line 16721 of file chan_dahdi.c.

Referenced by __unload_module(), and load_module().

◆ dahdi_tech

struct ast_channel_tech dahdi_tech
static

◆ default_jbconf

struct ast_jb_conf default_jbconf
static

Global jitterbuffer configuration - by default, jb is disabled

Note
Values shown here match the defaults shown in chan_dahdi.conf.sample

Definition at line 618 of file chan_dahdi.c.

Referenced by setup_dahdi_int().

◆ defaultcic

char defaultcic[64] = ""
static

Definition at line 717 of file chan_dahdi.c.

Referenced by process_dahdi().

◆ defaultozz

char defaultozz[64] = ""
static

Definition at line 718 of file chan_dahdi.c.

Referenced by process_dahdi().

◆ distinctiveringaftercid

int distinctiveringaftercid = 0
static

Definition at line 729 of file chan_dahdi.c.

Referenced by analog_ss_thread(), my_distinctive_ring(), and process_dahdi().

◆ dtmfcid_level

int dtmfcid_level = 256
static

Definition at line 734 of file chan_dahdi.c.

Referenced by do_monitor(), and process_dahdi().

◆ events

const char* const events[]
static

Definition at line 4597 of file chan_dahdi.c.

Referenced by event2str().

◆ global_jbconf

struct ast_jb_conf global_jbconf
static

Definition at line 626 of file chan_dahdi.c.

Referenced by dahdi_new(), process_dahdi(), and setup_dahdi_int().

◆ has_pseudo

int has_pseudo
static

Definition at line 688 of file chan_dahdi.c.

Referenced by build_channels(), and process_dahdi().

◆ ifcount

int ifcount = 0
static

Definition at line 749 of file chan_dahdi.c.

Referenced by destroy_all_channels(), do_monitor(), and mkintf().

◆ ifend

struct dahdi_pvt* ifend = NULL
static

Main interface list end

Definition at line 923 of file chan_dahdi.c.

Referenced by dahdi_cc_callback(), dahdi_iflist_extract(), dahdi_iflist_insert(), dahdi_request(), and determine_starting_point().

◆ iflist

struct dahdi_pvt* iflist = NULL
static

◆ iflock

ast_mutex_t iflock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

◆ lbostr

const char* const lbostr[]
static

Definition at line 605 of file chan_dahdi.c.

Referenced by action_dahdishowstatus(), and dahdi_show_status().

◆ monitor_thread

pthread_t monitor_thread = AST_PTHREADT_NULL
static

This is the thread for the monitor which checks for input on the channels which are not currently in use.

Definition at line 761 of file chan_dahdi.c.

Referenced by __unload_module(), dahdi_restart(), and restart_monitor().

◆ monlock

ast_mutex_t monlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.

Definition at line 757 of file chan_dahdi.c.

Referenced by __unload_module(), dahdi_restart(), and restart_monitor().

◆ mwilevel

int mwilevel = 512
static

Definition at line 733 of file chan_dahdi.c.

Referenced by do_monitor(), mwi_thread(), and process_dahdi().

◆ mwimonitornotify

char mwimonitornotify[PATH_MAX] = ""
static

Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled

Definition at line 721 of file chan_dahdi.c.

Referenced by notify_message(), process_dahdi(), and setup_dahdi_int().

◆ mwisend_rpas

int mwisend_rpas = 0
static

Definition at line 723 of file chan_dahdi.c.

Referenced by mwi_send_init(), and process_dahdi().

◆ name

char* name

◆ num_cadence

int num_cadence = 4
static

Definition at line 685 of file chan_dahdi.c.

Referenced by handle_dahdi_show_cadences(), my_set_cadence(), and process_dahdi().

◆ num_restart_pending

int num_restart_pending = 0
static

◆ numbufs

int numbufs = 4
static

Definition at line 731 of file chan_dahdi.c.

Referenced by dahdi_chan_conf_default(), and process_dahdi().

◆ polarity_function

struct ast_custom_function polarity_function
static
Initial value:
= {
.name = "POLARITY",
.write = polarity_write,
.read = polarity_read,
}
static int polarity_read(struct ast_channel *chan, const char *cmd, char *data, char *buffer, size_t buflen)
Definition: chan_dahdi.c:2874
static int polarity_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
Definition: chan_dahdi.c:2888

Definition at line 2915 of file chan_dahdi.c.

Referenced by __unload_module(), and load_module().

◆ progzone

char progzone[10] = ""
static

Definition at line 726 of file chan_dahdi.c.

Referenced by dahdi_new(), and process_dahdi().

◆ report_alarms

int report_alarms = REPORT_CHANNEL_ALARMS
static

Definition at line 738 of file chan_dahdi.c.

Referenced by handle_alarms(), handle_clear_alarms(), and process_dahdi().

◆ restart_lock

ast_mutex_t restart_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 764 of file chan_dahdi.c.

Referenced by dahdi_restart().

◆ ringt_base

int ringt_base = DEFAULT_RINGT
static

Configured ring timeout base.

Note
Value computed from "ringtimeout" read in from chan_dahdi.conf if it exists.

Definition at line 811 of file chan_dahdi.c.

Referenced by mkintf(), and process_dahdi().

◆ round_robin

struct dahdi_pvt* round_robin[64]
static

Round robin search locations.

Definition at line 3690 of file chan_dahdi.c.

Referenced by dahdi_request(), dahdi_restart(), determine_starting_point(), and load_module().

◆ ss_thread_complete

ast_cond_t ss_thread_complete
static

◆ ss_thread_count

int ss_thread_count = 0
static

◆ ss_thread_lock

ast_mutex_t ss_thread_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

◆ subnames

const char* const subnames[]
Initial value:
= {
"Real",
"Callwait",
"Threeway"
}

Definition at line 916 of file chan_dahdi.c.

Referenced by alloc_sub(), dahdi_new(), and native_start().

◆ tdesc

const char tdesc[] = "DAHDI Telephony"
static

Definition at line 648 of file chan_dahdi.c.

◆ usedistinctiveringdetection

int usedistinctiveringdetection = 0
static

Definition at line 728 of file chan_dahdi.c.

Referenced by mkintf(), and process_dahdi().

◆ user_has_defined_cadences

int user_has_defined_cadences = 0
static

Definition at line 686 of file chan_dahdi.c.

Referenced by process_dahdi().