Asterisk - The Open Source Telephony Project GIT-master-f36a736
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 16742 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 18302 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 18437 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 18439 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 16741 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:2968
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:2518
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1235
#define ast_channel_unlock(chan)
Definition: channel.h:2969
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:7408
@ 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 20538 of file chan_dahdi.c.

◆ __unload_module()

static int __unload_module ( void  )
static

Definition at line 18113 of file chan_dahdi.c.

18114{
18115 struct dahdi_pvt *p;
18116#if defined(HAVE_PRI) || defined(HAVE_SS7)
18117 int i, j;
18118#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
18119
18120#ifdef HAVE_PRI
18121 for (i = 0; i < NUM_SPANS; i++) {
18122 if (pris[i].pri.master != AST_PTHREADT_NULL) {
18123 pthread_cancel(pris[i].pri.master);
18124 pthread_kill(pris[i].pri.master, SIGURG);
18125 }
18126 }
18127 ast_cli_unregister_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
18128 ast_unregister_application(dahdi_send_keypad_facility_app);
18129#ifdef HAVE_PRI_PROG_W_CAUSE
18130 ast_unregister_application(dahdi_send_callrerouting_facility_app);
18131#endif
18132#endif
18133#if defined(HAVE_SS7)
18134 for (i = 0; i < NUM_SPANS; i++) {
18135 if (linksets[i].ss7.master != AST_PTHREADT_NULL) {
18136 pthread_cancel(linksets[i].ss7.master);
18137 pthread_kill(linksets[i].ss7.master, SIGURG);
18138 }
18139 }
18140 ast_cli_unregister_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli));
18141#endif /* defined(HAVE_SS7) */
18142#if defined(HAVE_OPENR2)
18143 dahdi_r2_destroy_links();
18144 ast_cli_unregister_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli));
18145 ast_unregister_application(dahdi_accept_r2_call_app);
18146#endif
18147
18149
18151 ast_manager_unregister("DAHDIDialOffhook");
18152 ast_manager_unregister("DAHDIHangup");
18153 ast_manager_unregister("DAHDITransfer");
18154 ast_manager_unregister("DAHDIDNDoff");
18155 ast_manager_unregister("DAHDIDNDon");
18156 ast_manager_unregister("DAHDIShowChannels");
18157 ast_manager_unregister("DAHDIShowStatus");
18158 ast_manager_unregister("DAHDIRestart");
18159#if defined(HAVE_PRI)
18160 ast_manager_unregister("PRIShowSpans");
18161 ast_manager_unregister("PRIDebugSet");
18162 ast_manager_unregister("PRIDebugFileSet");
18163 ast_manager_unregister("PRIDebugFileUnset");
18164#endif /* defined(HAVE_PRI) */
18166
18167 /* Hangup all interfaces if they have an owner */
18169 for (p = iflist; p; p = p->next) {
18170 if (p->owner)
18172 }
18174
18177 pthread_cancel(monitor_thread);
18178 pthread_kill(monitor_thread, SIGURG);
18179 pthread_join(monitor_thread, NULL);
18180 }
18183
18185
18186#if defined(HAVE_PRI)
18187 for (i = 0; i < NUM_SPANS; i++) {
18188 if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) {
18189 pthread_join(pris[i].pri.master, NULL);
18190 }
18191 for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) {
18192 dahdi_close_pri_fd(&(pris[i]), j);
18193 }
18194 sig_pri_stop_pri(&pris[i].pri);
18195 }
18196#if defined(HAVE_PRI_CCSS)
18197 ast_cc_agent_unregister(&dahdi_pri_cc_agent_callbacks);
18198 ast_cc_monitor_unregister(&dahdi_pri_cc_monitor_callbacks);
18199#endif /* defined(HAVE_PRI_CCSS) */
18201#endif
18202
18203#if defined(HAVE_SS7)
18204 for (i = 0; i < NUM_SPANS; i++) {
18205 if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) {
18206 pthread_join(linksets[i].ss7.master, NULL);
18207 }
18208 for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) {
18209 dahdi_close_ss7_fd(&(linksets[i]), j);
18210 }
18211 if (linksets[i].ss7.ss7) {
18212 ss7_destroy(linksets[i].ss7.ss7);
18213 linksets[i].ss7.ss7 = NULL;
18214 }
18215 }
18216#endif /* defined(HAVE_SS7) */
18218
18220
18223 STASIS_MESSAGE_TYPE_CLEANUP(dahdichannel_type);
18224 return 0;
18225}
#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:16726
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:2490
@ AST_SOFTHANGUP_APPUNLOAD
Definition: channel.h:1163
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:7608
#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:652
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 20538 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 16879 of file chan_dahdi.c.

16880{
16881 struct dahdi_pvt *p;
16882 const char *channel = astman_get_header(m, "DAHDIChannel");
16883 const char *number = astman_get_header(m, "Number");
16884 int i;
16885
16886 if (ast_strlen_zero(channel)) {
16887 astman_send_error(s, m, "No channel specified");
16888 return 0;
16889 }
16890 if (ast_strlen_zero(number)) {
16891 astman_send_error(s, m, "No number specified");
16892 return 0;
16893 }
16895 if (!p) {
16896 astman_send_error(s, m, "No such channel");
16897 return 0;
16898 }
16899 if (!p->owner) {
16900 astman_send_error(s, m, "Channel does not have it's owner");
16901 return 0;
16902 }
16903 for (i = 0; i < strlen(number); i++) {
16904 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = number[i] };
16905 dahdi_queue_frame(p, &f);
16906 }
16907 astman_send_ack(s, m, "DAHDIDialOffhook");
16908 return 0;
16909}
static struct dahdi_pvt * find_channel_from_str(const char *channel)
Definition: chan_dahdi.c:16783
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:1969
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2001
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1630
#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 16814 of file chan_dahdi.c.

16815{
16816 struct dahdi_pvt *p;
16817 const char *channel = astman_get_header(m, "DAHDIChannel");
16818
16819 if (ast_strlen_zero(channel)) {
16820 astman_send_error(s, m, "No channel specified");
16821 return 0;
16822 }
16824 if (!p) {
16825 astman_send_error(s, m, "No such channel");
16826 return 0;
16827 }
16828 dahdi_dnd(p, 0);
16829 astman_send_ack(s, m, "DND Disabled");
16830 return 0;
16831}
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 16795 of file chan_dahdi.c.

16796{
16797 struct dahdi_pvt *p;
16798 const char *channel = astman_get_header(m, "DAHDIChannel");
16799
16800 if (ast_strlen_zero(channel)) {
16801 astman_send_error(s, m, "No channel specified");
16802 return 0;
16803 }
16805 if (!p) {
16806 astman_send_error(s, m, "No such channel");
16807 return 0;
16808 }
16809 dahdi_dnd(p, 1);
16810 astman_send_ack(s, m, "DND Enabled");
16811 return 0;
16812}

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

15985{
15986 if (dahdi_restart() != 0) {
15987 astman_send_error(s, m, "Failed rereading DAHDI configuration");
15988 return 1;
15989 }
15990 astman_send_ack(s, m, "DAHDIRestart: Success");
15991 return 0;
15992}
static int dahdi_restart(void)
Definition: chan_dahdi.c:15846

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

16912{
16913 struct dahdi_pvt *tmp = NULL;
16914 const char *id = astman_get_header(m, "ActionID");
16915 const char *dahdichannel = astman_get_header(m, "DAHDIChannel");
16916 char idText[256];
16917 int channels = 0;
16918 int dahdichanquery;
16919
16920 if (!dahdichannel || sscanf(dahdichannel, "%30d", &dahdichanquery) != 1) {
16921 /* Not numeric string. */
16922 dahdichanquery = -1;
16923 }
16924
16925 idText[0] = '\0';
16926 if (!ast_strlen_zero(id)) {
16927 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
16928 }
16929
16930 astman_send_listack(s, m, "DAHDI channel status will follow", "start");
16931
16933
16934 for (tmp = iflist; tmp; tmp = tmp->next) {
16935 if (tmp->channel > 0) {
16936 int alm;
16937
16938 /* If a specific channel is queried for, only deliver status for that channel */
16939 if (dahdichanquery > 0 && tmp->channel != dahdichanquery)
16940 continue;
16941
16942 alm = get_alarms(tmp);
16943 channels++;
16944 if (tmp->owner) {
16945 /* Add data if we have a current call */
16946 astman_append(s,
16947 "Event: DAHDIShowChannels\r\n"
16948 "DAHDIChannel: %d\r\n"
16949 "Channel: %s\r\n"
16950 "Uniqueid: %s\r\n"
16951 "AccountCode: %s\r\n"
16952 "Signalling: %s\r\n"
16953 "SignallingCode: %d\r\n"
16954 "Context: %s\r\n"
16955 "DND: %s\r\n"
16956 "Alarm: %s\r\n"
16957 "Description: %s\r\n"
16958 "%s"
16959 "\r\n",
16960 tmp->channel,
16961 ast_channel_name(tmp->owner),
16962 ast_channel_uniqueid(tmp->owner),
16964 sig2str(tmp->sig),
16965 tmp->sig,
16966 tmp->context,
16967 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled",
16968 alarm2str(alm),
16969 tmp->description, idText);
16970 } else {
16971 astman_append(s,
16972 "Event: DAHDIShowChannels\r\n"
16973 "DAHDIChannel: %d\r\n"
16974 "Signalling: %s\r\n"
16975 "SignallingCode: %d\r\n"
16976 "Context: %s\r\n"
16977 "DND: %s\r\n"
16978 "Alarm: %s\r\n"
16979 "Description: %s\r\n"
16980 "%s"
16981 "\r\n",
16982 tmp->channel, sig2str(tmp->sig), tmp->sig,
16983 tmp->context,
16984 dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled",
16985 alarm2str(alm),
16986 tmp->description, idText);
16987 }
16988 }
16989 }
16990
16992
16993 astman_send_list_complete_start(s, m, "DAHDIShowChannelsComplete", channels);
16994 astman_append(s, "Items: %d\r\n", channels);
16996 return 0;
16997}
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:2011
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:2047
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2055
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1890

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

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

16834{
16835 struct dahdi_pvt *p;
16836 const char *channel = astman_get_header(m, "DAHDIChannel");
16837
16838 if (ast_strlen_zero(channel)) {
16839 astman_send_error(s, m, "No channel specified");
16840 return 0;
16841 }
16843 if (!p) {
16844 astman_send_error(s, m, "No such channel");
16845 return 0;
16846 }
16847 if (!dahdi_analog_lib_handles(p->sig, 0, 0)) {
16848 astman_send_error(s, m, "Channel signaling is not analog");
16849 return 0;
16850 }
16852 astman_send_ack(s, m, "DAHDITransfer");
16853 return 0;
16854}
#define TRANSFER
Definition: chan_dahdi.c:16741
static int dahdi_fake_event(struct dahdi_pvt *p, int mode)
Definition: chan_dahdi.c:16744
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 16856 of file chan_dahdi.c.

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

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:3194
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:1610
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
Definition: channel.c:1663
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2560
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:10586
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3181
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:4276
void ast_party_name_free(struct ast_party_name *doomed)
Destroy the party name contents.
Definition: channel.c:1657
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:7356
void ast_party_number_free(struct ast_party_number *doomed)
Destroy the party number contents.
Definition: channel.c:1710
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:10604
void ast_channel_context_set(struct ast_channel *chan, const char *value)
@ AST_FLAG_END_DTMF_ONLY
Definition: channel.h:1027
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:3015
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1593
#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 20538 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:2993
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3004
@ AST_SOFTHANGUP_DEV
Definition: channel.h:1141

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

13478{
13479 struct dahdi_pvt *p = *pvt;
13480
13481 if (p->inalarm)
13482 return 0;
13483
13484 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode))
13485 return analog_available(p->sig_pvt);
13486
13487 switch (p->sig) {
13488#if defined(HAVE_PRI)
13490 {
13491 struct sig_pri_chan *pvt_chan;
13492 int res;
13493
13494 pvt_chan = p->sig_pvt;
13495 res = sig_pri_available(&pvt_chan, is_specific_channel);
13496 *pvt = pvt_chan->chan_pvt;
13497 return res;
13498 }
13499#endif /* defined(HAVE_PRI) */
13500#if defined(HAVE_SS7)
13501 case SIG_SS7:
13502 return sig_ss7_available(p->sig_pvt);
13503#endif /* defined(HAVE_SS7) */
13504 default:
13505 break;
13506 }
13507
13508 if (p->locallyblocked || p->remotelyblocked) {
13509 return 0;
13510 }
13511
13512 /* If no owner definitely available */
13513 if (!p->owner) {
13514#ifdef HAVE_OPENR2
13515 /* Trust MFC/R2 */
13516 if (p->mfcr2) {
13517 if (p->mfcr2call) {
13518 return 0;
13519 } else {
13520 return 1;
13521 }
13522 }
13523#endif
13524 return 1;
13525 }
13526
13527 return 0;
13528}
#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 16314 of file chan_dahdi.c.

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

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

18244{
18245 char *c, *chan;
18246 int x, start, finish;
18247 struct dahdi_pvt *tmp;
18248
18249 if ((reload == 0) && (conf->chan.sig < 0) && !conf->is_sig_auto) {
18250 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
18251 return -1;
18252 }
18253
18254 c = ast_strdupa(value);
18255
18256 while ((chan = strsep(&c, ","))) {
18257 if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
18258 /* Range */
18259 } else if (sscanf(chan, "%30d", &start)) {
18260 /* Just one */
18261 finish = start;
18262 } else if (!strcasecmp(chan, "pseudo")) {
18263 finish = start = CHAN_PSEUDO;
18264 } else {
18265 ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
18266 return -1;
18267 }
18268 if (finish < start) {
18269 ast_log(LOG_WARNING, "Silliness: %d < %d\n", start, finish);
18270 x = finish;
18271 finish = start;
18272 start = x;
18273 }
18274
18275 for (x = start; x <= finish; x++) {
18276 if (conf->wanted_channels_start &&
18277 (x < conf->wanted_channels_start ||
18278 x > conf->wanted_channels_end)
18279 ) {
18280 continue;
18281 }
18282 tmp = mkintf(x, conf, reload);
18283
18284 if (tmp) {
18285 ast_verb(3, "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
18286 } else {
18287 ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
18288 (reload == 1) ? "reconfigure" : "register", value);
18289 return -1;
18290 }
18291 if (x == CHAN_PSEUDO) {
18292 has_pseudo = 1;
18293 }
18294 }
18295 }
18296
18297 return 0;
18298}
static struct dahdi_pvt * mkintf(int channel, const struct dahdi_chan_conf *conf, int reloading)
Definition: chan_dahdi.c:12498
static int has_pseudo
Definition: chan_dahdi.c:688
static int reload(void)
Definition: chan_dahdi.c:20514
#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:460
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:344
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:299
char * str
Subscriber phone number (Malloced)
Definition: channel.h:293
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 14151 of file chan_dahdi.c.

14152{
14153 struct dahdi_pvt *p;
14154 struct dahdi_pvt *exitpvt;
14155 struct dahdi_starting_point start;
14156 int groupmatched = 0;
14157 int channelmatched = 0;
14158
14160 p = determine_starting_point(dest, &start);
14161 if (!p) {
14163 return -1;
14164 }
14165 exitpvt = p;
14166 for (;;) {
14167 if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)) {
14168 /* We found a potential match. call the callback */
14169 struct ast_str *device_name;
14170 char *dash;
14171 const char *monitor_type;
14172 char dialstring[AST_CHANNEL_NAME];
14173 char full_device_name[AST_CHANNEL_NAME];
14174
14177 break;
14181#if defined(HAVE_PRI)
14183 /*
14184 * ISDN is in a trunk busy condition so we need to monitor
14185 * the span congestion device state.
14186 */
14187 snprintf(full_device_name, sizeof(full_device_name),
14188 "DAHDI/I%d/congestion", p->pri->span);
14189 } else
14190#endif /* defined(HAVE_PRI) */
14191 {
14192#if defined(HAVE_PRI)
14193 device_name = create_channel_name(p, 1, "");
14194#else
14195 device_name = create_channel_name(p);
14196#endif /* defined(HAVE_PRI) */
14197 snprintf(full_device_name, sizeof(full_device_name), "DAHDI/%s",
14198 device_name ? ast_str_buffer(device_name) : "");
14199 ast_free(device_name);
14200 /*
14201 * The portion after the '-' in the channel name is either a random
14202 * number, a sequence number, or a subchannel number. None are
14203 * necessary so strip them off.
14204 */
14205 dash = strrchr(full_device_name, '-');
14206 if (dash) {
14207 *dash = '\0';
14208 }
14209 }
14210 snprintf(dialstring, sizeof(dialstring), "DAHDI/%s", dest);
14211
14212 /*
14213 * Analog can only do generic monitoring.
14214 * ISDN is in a trunk busy condition and any "device" is going
14215 * to be busy until a B channel becomes available. The generic
14216 * monitor can do this task.
14217 */
14218 monitor_type = AST_CC_GENERIC_MONITOR_TYPE;
14219 callback(inbound,
14220#if defined(HAVE_PRI)
14221 p->pri ? p->pri->cc_params : p->cc_params,
14222#else
14223 p->cc_params,
14224#endif /* defined(HAVE_PRI) */
14225 monitor_type, full_device_name, dialstring, NULL);
14226 break;
14227 }
14228 }
14229 p = start.backwards ? p->prev : p->next;
14230 if (!p) {
14231 p = start.backwards ? ifend : iflist;
14232 }
14233 if (p == exitpvt) {
14234 break;
14235 }
14236 }
14238 return 0;
14239}
#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:13444
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:13747
#define AST_CHANNEL_NAME
Definition: channel.h:173
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:19961
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 15769 of file chan_dahdi.c.

15770{
15771 int start;
15772 int end;
15773 int ret;
15774
15775 switch (cmd) {
15776 case CLI_INIT:
15777 e->command = "dahdi create channels";
15778 e->usage = "Usage: dahdi create channels <from> [<to>] - a range of channels\n"
15779 " dahdi create channels new - add channels not yet created\n"
15780 "For ISDN and SS7 the range should include complete spans.\n";
15781 return NULL;
15782 case CLI_GENERATE:
15783 return NULL;
15784 }
15785 if ((a->argc < 4) || a->argc > 5) {
15786 return CLI_SHOWUSAGE;
15787 }
15788 if (a->argc == 4 && !strcmp(a->argv[3], "new")) {
15789 ret = dahdi_create_channel_range(0, 0);
15790 return (RESULT_SUCCESS == ret) ? CLI_SUCCESS : CLI_FAILURE;
15791 }
15792 start = atoi(a->argv[3]);
15793 if (start <= 0) {
15794 ast_cli(a->fd, "Invalid starting channel number '%s'.\n",
15795 a->argv[3]);
15796 return CLI_FAILURE;
15797 }
15798 if (a->argc == 5) {
15799 end = atoi(a->argv[4]);
15800 if (end <= 0) {
15801 ast_cli(a->fd, "Invalid ending channel number '%s'.\n",
15802 a->argv[4]);
15803 return CLI_FAILURE;
15804 }
15805 } else {
15806 end = start;
15807 }
15808 if (end < start) {
15809 ast_cli(a->fd,
15810 "range end (%d) is smaller than range start (%d)\n",
15811 end, start);
15812 return CLI_FAILURE;
15813 }
15814 ret = dahdi_create_channel_range(start, end);
15815 return (RESULT_SUCCESS == ret) ? CLI_SUCCESS : CLI_FAILURE;
15816}
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 15725 of file chan_dahdi.c.

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

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

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

16745{
16746 if (p) {
16747 switch (mode) {
16748 case TRANSFER:
16749 p->fake_event = DAHDI_EVENT_WINKFLASH;
16750 break;
16751 case HANGUP:
16752 p->fake_event = DAHDI_EVENT_ONHOOK;
16753 break;
16754 default:
16755 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));
16756 }
16757 }
16758 return 0;
16759}

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:4132
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:2970
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1185
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1210
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
@ AST_SOFTHANGUP_EXPLICIT
Definition: channel.h:1168
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:422
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:435
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:429
struct ast_party_name name
Subscriber name.
Definition: channel.h:342
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:281
char * str
Subscriber name (Malloced)
Definition: channel.h:266
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:12173
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:7444
#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:7788
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7798
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:1299
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:10473
@ AST_ADSI_UNAVAILABLE
Definition: channel.h:891
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:2445
@ AST_FLAG_DISABLE_DEVSTATE_CACHE
Definition: channel.h:1049
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:388
char * tag
User-set "tag".
Definition: channel.h:356
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:279
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:297
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:295
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:529
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:1158

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:2917
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
Definition: channel.c:2864
@ AST_FLAG_BLOCKING
Definition: channel.h:1005
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 13908 of file chan_dahdi.c.

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

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

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

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

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

16601{
16602 int channel;
16603 int on;
16604 struct dahdi_pvt *dahdi_chan = NULL;
16605
16606 switch (cmd) {
16607 case CLI_INIT:
16608 e->command = "dahdi set dnd";
16609 e->usage =
16610 "Usage: dahdi set dnd <chan#> <on|off>\n"
16611 " Sets/resets DND (Do Not Disturb) mode on a channel.\n"
16612 " Changes take effect immediately.\n"
16613 " <chan num> is the channel number\n"
16614 " <on|off> Enable or disable DND mode?\n"
16615 ;
16616 return NULL;
16617 case CLI_GENERATE:
16618 return NULL;
16619 }
16620
16621 if (a->argc != 5)
16622 return CLI_SHOWUSAGE;
16623
16624 if ((channel = atoi(a->argv[3])) <= 0) {
16625 ast_cli(a->fd, "Expected channel number, got '%s'\n", a->argv[3]);
16626 return CLI_SHOWUSAGE;
16627 }
16628
16629 if (ast_true(a->argv[4]))
16630 on = 1;
16631 else if (ast_false(a->argv[4]))
16632 on = 0;
16633 else {
16634 ast_cli(a->fd, "Expected 'on' or 'off', got '%s'\n", a->argv[4]);
16635 return CLI_SHOWUSAGE;
16636 }
16637
16639 for (dahdi_chan = iflist; dahdi_chan; dahdi_chan = dahdi_chan->next) {
16640 if (dahdi_chan->channel != channel)
16641 continue;
16642
16643 /* Found the channel. Actually set it */
16644 dahdi_dnd(dahdi_chan, on);
16645 break;
16646 }
16648
16649 if (!dahdi_chan) {
16650 ast_cli(a->fd, "Unable to find given channel %d\n", channel);
16651 return CLI_FAILURE;
16652 }
16653
16654 return CLI_SUCCESS;
16655}
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 16443 of file chan_dahdi.c.

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

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

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

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

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

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

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

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

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

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

15819{
15820 struct dahdi_pvt *p;
15821retry:
15823 for (p = iflist; p; p = p->next) {
15824 ast_mutex_lock(&p->lock);
15825 if (p->owner && !p->restartpending) {
15826 if (ast_channel_trylock(p->owner)) {
15827 if (DEBUG_ATLEAST(3))
15828 ast_verbose("Avoiding deadlock\n");
15829 /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */
15832 goto retry;
15833 }
15834 if (DEBUG_ATLEAST(3))
15835 ast_verbose("Softhanging up on %s\n", ast_channel_name(p->owner));
15837 p->restartpending = 1;
15840 }
15842 }
15844}
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2477
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:10128
#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 19939 of file chan_dahdi.c.

19940{
19941 struct ast_cc_config_params *cc_params;
19942
19943 cc_params = dest->chan.cc_params;
19944 *dest = *src;
19945 dest->chan.cc_params = cc_params;
19947}

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:478
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:7754
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:4109
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 13747 of file chan_dahdi.c.

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

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 /* In some cases, all of the above checks will pass even if the line is really off-hook.
11988 * This last check will give the right answer 100% of the time, but is relatively
11989 * "expensive" (it requires an ioctl), so it is last to avoid unnecessary system calls. */
11990 && !my_is_off_hook(last)) {
11991 res = has_voicemail(last);
11992 if (analog_p->msgstate != res) {
11993 /* Set driver resources for signalling VMWI */
11994 res2 = ioctl(last->subs[SUB_REAL].dfd, DAHDI_VMWI, &res);
11995 if (res2) {
11996 /* TODO: This message will ALWAYS be generated on some cards; any way to restrict it to those cards where it is interesting? */
11997 ast_debug(3, "Unable to control message waiting led on channel %d: %s\n", last->channel, strerror(errno));
11998 }
11999 /* If enabled for FSK spill then initiate it */
12000 ast_debug(5, "Initiating MWI FSK spill on channel %d\n", last->channel);
12001 if (mwi_send_init(last)) {
12002 ast_log(LOG_WARNING, "Unable to initiate mwi send sequence on channel %d\n", last->channel);
12003 }
12004 analog_p->msgstate = res;
12005 found ++;
12006 }
12007 }
12008 last = last->next;
12009 }
12010 }
12011 }
12012 if ((i->subs[SUB_REAL].dfd > -1) && i->sig) {
12013 if (i->radio && !i->owner)
12014 {
12015 res = dahdi_get_event(i->subs[SUB_REAL].dfd);
12016 if (res)
12017 {
12018 ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
12019 /* Don't hold iflock while handling init events */
12021 if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode))
12023 else
12024 doomed = handle_init_event(i, res);
12026 }
12027 continue;
12028 }
12029 pollres = ast_fdisset(pfds, i->subs[SUB_REAL].dfd, count, &spoint);
12030 if (pollres & POLLIN) {
12031 if (i->owner || i->subs[SUB_REAL].owner) {
12032#ifdef HAVE_PRI
12033 if (!i->pri)
12034#endif
12035 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd);
12036 continue;
12037 }
12039 ast_log(LOG_WARNING, "Whoa.... I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd);
12040 continue;
12041 }
12042 res = read(i->subs[SUB_REAL].dfd, buf, sizeof(buf));
12043 if (res > 0) {
12044 if (i->mwimonitor_fsk) {
12045 if (calc_energy((unsigned char *) buf, res, AST_LAW(i)) > mwilevel) {
12046 pthread_attr_t attr;
12047 pthread_t threadid;
12048 struct mwi_thread_data *mtd;
12049
12050 pthread_attr_init(&attr);
12051 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
12052
12053 ast_debug(1, "Maybe some MWI on port %d!\n", i->channel);
12054 if ((mtd = ast_calloc(1, sizeof(*mtd)))) {
12055 mtd->pvt = i;
12056 memcpy(mtd->buf, buf, res);
12057 mtd->len = res;
12058 i->mwimonitoractive = 1;
12059 if (ast_pthread_create_background(&threadid, &attr, mwi_thread, mtd)) {
12060 ast_log(LOG_WARNING, "Unable to start mwi thread on channel %d\n", i->channel);
12061 i->mwimonitoractive = 0;
12062 ast_free(mtd);
12063 }
12064 }
12065 }
12066 /* If configured to check for a DTMF CID spill that comes without alert (e.g no polarity reversal) */
12067 } else if (i->cid_start == CID_START_DTMF_NOALERT) {
12068 int energy;
12069 struct timeval now;
12070 /* State machine dtmfcid_holdoff_state allows for the line to settle
12071 * before checking agin for dtmf energy. Presently waits for 500 mS before checking again
12072 */
12073 if (1 == i->dtmfcid_holdoff_state) {
12074 gettimeofday(&i->dtmfcid_delay, NULL);
12075 i->dtmfcid_holdoff_state = 2;
12076 } else if (2 == i->dtmfcid_holdoff_state) {
12077 gettimeofday(&now, NULL);
12078 if ((int)(now.tv_sec - i->dtmfcid_delay.tv_sec) * 1000000 + (int)now.tv_usec - (int)i->dtmfcid_delay.tv_usec > 500000) {
12079 i->dtmfcid_holdoff_state = 0;
12080 }
12081 } else {
12082 energy = calc_energy((unsigned char *) buf, res, AST_LAW(i));
12083 if (!i->mwisendactive && energy > dtmfcid_level) {
12084 pthread_t threadid;
12085 struct ast_channel *chan;
12087 if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
12088 /* just in case this event changes or somehow destroys a channel, set doomed here too */
12090 i->dtmfcid_holdoff_state = 1;
12091 } else {
12092 ast_callid callid = 0;
12093 int callid_created = ast_callid_threadstorage_auto(&callid);
12094 chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
12095 if (!chan) {
12096 ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
12097 } else {
12098 res = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan);
12099 if (res) {
12100 ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
12101 ast_hangup(chan);
12102 } else {
12103 i->dtmfcid_holdoff_state = 1;
12104 }
12105 }
12107 }
12109 }
12110 }
12111 }
12112 if (i->mwisendactive) {
12114 }
12115 } else {
12116 ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
12117 }
12118 }
12119 if (pollres & POLLPRI) {
12120 if (i->owner || i->subs[SUB_REAL].owner) {
12121#ifdef HAVE_PRI
12122 if (!i->pri)
12123#endif
12124 ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].dfd);
12125 continue;
12126 }
12127 res = dahdi_get_event(i->subs[SUB_REAL].dfd);
12128 ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
12129 /* Don't hold iflock while handling init events */
12131 if (0 == i->mwisendactive || 0 == mwi_send_process_event(i, res)) {
12132 if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode))
12134 else
12135 doomed = handle_init_event(i, res);
12136 }
12137 if (i->doreoriginate && res == DAHDI_EVENT_HOOKCOMPLETE) {
12138 /* Actually automatically reoriginate this FXS line, if directed to.
12139 * We should get a DAHDI_EVENT_HOOKCOMPLETE from the loop disconnect
12140 * doing its thing (one reason why this is for FXOKS only: FXOLS
12141 * hangups don't give us any DAHDI events to piggyback off of)*/
12142 i->doreoriginate = 0;
12143 /* Double check the channel is still off-hook. There's only about a millisecond
12144 * between when doreoriginate is set high and we see that here, but just to be safe. */
12145 if (!my_is_off_hook(i)) {
12146 ast_debug(1, "Woah! Went back on hook before reoriginate could happen on channel %d\n", i->channel);
12147 } else {
12148 ast_verb(3, "Automatic reorigination on channel %d\n", i->channel);
12149 res = DAHDI_EVENT_RINGOFFHOOK; /* Pretend that the physical channel just went off hook */
12150 if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
12152 } else {
12153 doomed = handle_init_event(i, res);
12154 }
12155 }
12156 }
12158 }
12159 }
12160 }
12163#ifdef HAVE_OPENR2
12164 dahdi_r2_destroy_nodev();
12165#endif
12166 }
12167 /* Never reached */
12168 pthread_cleanup_pop(1);
12169 return NULL;
12170
12171}
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:2873
void * analog_handle_init_event(struct analog_pvt *i, int event)
Definition: sig_analog.c:3798
@ 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 13683 of file chan_dahdi.c.

13684{
13685 struct dahdi_pvt *p;
13686 struct dahdi_bufferinfo bi;
13687 int res;
13688
13689 p = ast_malloc(sizeof(*p));
13690 if (!p) {
13691 return NULL;
13692 }
13693 *p = *src;
13694
13695 /* Must deep copy the cc_params. */
13697 if (!p->cc_params) {
13698 ast_free(p);
13699 return NULL;
13700 }
13702
13704 p->next = NULL;
13705 p->prev = NULL;
13706 ast_mutex_init(&p->lock);
13707 p->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo");
13708 if (p->subs[SUB_REAL].dfd < 0) {
13709 ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno));
13711 return NULL;
13712 }
13713 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
13714 if (!res) {
13715 bi.txbufpolicy = src->buf_policy;
13716 bi.rxbufpolicy = src->buf_policy;
13717 bi.numbufs = src->buf_no;
13718 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
13719 if (res < 0) {
13720 ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel: %s\n", strerror(errno));
13721 }
13722 } else
13723 ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel: %s\n", strerror(errno));
13724 p->destroy = 1;
13726 return p;
13727}
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 16760 of file chan_dahdi.c.

16761{
16762 struct dahdi_pvt *p;
16763
16765 for (p = iflist; p; p = p->next) {
16766 if (p->channel == channel) {
16767 break;
16768 }
16769 }
16771 return p;
16772}

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

16784{
16785 int chan_num;
16786
16787 if (sscanf(channel, "%30d", &chan_num) != 1) {
16788 /* Not numeric string. */
16789 return NULL;
16790 }
16791
16792 return find_channel(chan_num);
16793}
static struct dahdi_pvt * find_channel(int channel)
Definition: chan_dahdi.c:16760

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

16279{
16280 int i, j;
16281 switch (cmd) {
16282 case CLI_INIT:
16283 e->command = "dahdi show cadences";
16284 e->usage =
16285 "Usage: dahdi show cadences\n"
16286 " Shows all cadences currently defined\n";
16287 return NULL;
16288 case CLI_GENERATE:
16289 return NULL;
16290 }
16291 for (i = 0; i < num_cadence; i++) {
16292 char output[1024];
16293 char tmp[16], tmp2[64];
16294 snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
16295 term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
16296
16297 for (j = 0; j < 16; j++) {
16298 if (cadences[i].ringcadence[j] == 0)
16299 break;
16300 snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
16301 if (cidrings[i] * 2 - 1 == j)
16302 term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
16303 else
16304 term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
16305 if (j != 0)
16306 strncat(output, ",", sizeof(output) - strlen(output) - 1);
16307 strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
16308 }
16309 ast_cli(a->fd,"%s\n",output);
16310 }
16311 return CLI_SUCCESS;
16312}
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 13444 of file chan_dahdi.c.

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

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

20285{
20286 int res;
20287#if defined(HAVE_PRI) || defined(HAVE_SS7)
20288 int y;
20289#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
20290
20291 if (STASIS_MESSAGE_TYPE_INIT(dahdichannel_type)) {
20293 }
20294
20297 }
20301
20305 }
20306
20307#ifdef HAVE_PRI
20308 memset(pris, 0, sizeof(pris));
20309 for (y = 0; y < NUM_SPANS; y++) {
20310 sig_pri_init_pri(&pris[y].pri);
20311 }
20312 pri_set_error(dahdi_pri_error);
20313 pri_set_message(dahdi_pri_message);
20314 ast_register_application_xml(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec);
20315#ifdef HAVE_PRI_PROG_W_CAUSE
20316 ast_register_application_xml(dahdi_send_callrerouting_facility_app, dahdi_send_callrerouting_facility_exec);
20317#endif
20318#if defined(HAVE_PRI_CCSS)
20319 if (ast_cc_agent_register(&dahdi_pri_cc_agent_callbacks)
20320 || ast_cc_monitor_register(&dahdi_pri_cc_monitor_callbacks)) {
20323 }
20324#endif /* defined(HAVE_PRI_CCSS) */
20325 if (sig_pri_load(
20326#if defined(HAVE_PRI_CCSS)
20327 dahdi_pri_cc_type
20328#else
20329 NULL
20330#endif /* defined(HAVE_PRI_CCSS) */
20331 )) {
20334 }
20335#endif
20336#if defined(HAVE_SS7)
20337 memset(linksets, 0, sizeof(linksets));
20338 for (y = 0; y < NUM_SPANS; y++) {
20339 sig_ss7_init_linkset(&linksets[y].ss7);
20340 }
20341 ss7_set_error(dahdi_ss7_error);
20342 ss7_set_message(dahdi_ss7_message);
20343 ss7_set_hangup(sig_ss7_cb_hangup);
20344 ss7_set_notinservice(sig_ss7_cb_notinservice);
20345 ss7_set_call_null(sig_ss7_cb_call_null);
20346#endif /* defined(HAVE_SS7) */
20347 res = setup_dahdi(0);
20348 /* Make sure we can register our DAHDI channel type */
20349 if (res) {
20352 }
20354 ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n");
20357 }
20358#ifdef HAVE_PRI
20359 ast_cli_register_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
20360#endif
20361#if defined(HAVE_SS7)
20362 ast_cli_register_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli));
20363#endif /* defined(HAVE_SS7) */
20364#ifdef HAVE_OPENR2
20365 ast_cli_register_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli));
20366 ast_register_application_xml(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec);
20367#endif
20368
20370
20372 memset(round_robin, 0, sizeof(round_robin));
20373 ast_manager_register_xml("DAHDITransfer", 0, action_transfer);
20375 ast_manager_register_xml("DAHDIDialOffhook", 0, action_dahdidialoffhook);
20378 ast_manager_register_xml("DAHDIShowChannels", 0, action_dahdishowchannels);
20379 ast_manager_register_xml("DAHDIShowStatus", 0, action_dahdishowstatus);
20381#if defined(HAVE_PRI)
20382 ast_manager_register_xml("PRIShowSpans", 0, action_prishowspans);
20383 ast_manager_register_xml("PRIDebugSet", 0, action_pri_debug_set);
20384 ast_manager_register_xml("PRIDebugFileSet", EVENT_FLAG_SYSTEM, action_pri_debug_file_set);
20385 ast_manager_register_xml("PRIDebugFileUnset", 0, action_pri_debug_file_unset);
20386#endif /* defined(HAVE_PRI) */
20387
20389
20390 return res;
20391}
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:18113
static int action_transfer(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16833
static int action_dahdidndon(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16795
static int action_dahdishowchannels(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16911
static int action_dahdirestart(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:15984
static int action_dahdidndoff(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16814
static int action_dahdidialoffhook(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16879
static int action_transferhangup(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16856
static int action_dahdishowstatus(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16999
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 12498 of file chan_dahdi.c.

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

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

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

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

20515{
20516 int res = 0;
20517
20518 res = setup_dahdi(1);
20519 if (res) {
20520 ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n");
20521 return -1;
20522 }
20523 return 0;
20524}

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

12174{
12175 /* If we're supposed to be stopped -- stay stopped */
12177 return 0;
12179 if (monitor_thread == pthread_self()) {
12181 ast_log(LOG_WARNING, "Cannot kill myself\n");
12182 return -1;
12183 }
12185 /* Wake up the thread */
12186 pthread_kill(monitor_thread, SIGURG);
12187 } else {
12188 /* Start a new monitor */
12191 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
12192 return -1;
12193 }
12194 }
12196 return 0;
12197}
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 20255 of file chan_dahdi.c.

20256{
20257 int res;
20258 struct dahdi_chan_conf default_conf = dahdi_chan_conf_default();
20259 struct dahdi_chan_conf base_conf = dahdi_chan_conf_default();
20261
20262 if (default_conf.chan.cc_params && base_conf.chan.cc_params && conf.chan.cc_params) {
20263 res = setup_dahdi_int(reload, &default_conf, &base_conf, &conf);
20264 } else {
20265 res = -1;
20266 }
20269 ast_cc_config_params_destroy(conf.chan.cc_params);
20270
20271 return res;
20272}

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

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

12480{
12481 return sigtype;
12482}
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 18227 of file chan_dahdi.c.

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

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