Asterisk - The Open Source Telephony Project  18.5.0
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 %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n"
 
#define FORMAT   "%-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n"
 
#define FORMAT2   "%7s %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n"
 
#define FORMAT2   "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n"
 
#define 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_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 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_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)
 
 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 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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 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 [32]
 
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

Referenced by dahdi_sendtext().

◆ AST_LAW

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

◆ CALLPROGRESS_FAX

#define CALLPROGRESS_FAX   (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)

Definition at line 561 of file chan_dahdi.c.

Referenced by dahdi_handle_dtmf(), my_handle_dtmf(), and process_dahdi().

◆ CALLPROGRESS_FAX_INCOMING

#define CALLPROGRESS_FAX_INCOMING   4

Definition at line 560 of file chan_dahdi.c.

Referenced by dahdi_new(), and process_dahdi().

◆ CALLPROGRESS_FAX_OUTGOING

#define CALLPROGRESS_FAX_OUTGOING   2

Definition at line 559 of file chan_dahdi.c.

Referenced by dahdi_new(), and process_dahdi().

◆ CALLPROGRESS_PROGRESS

#define CALLPROGRESS_PROGRESS   1

Definition at line 558 of file chan_dahdi.c.

Referenced by dahdi_handle_event(), dahdi_new(), my_have_progressdetect(), and process_dahdi().

◆ CALLWAITING_REPEAT_SAMPLES

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

10,000 ms

Definition at line 679 of file chan_dahdi.c.

Referenced by dahdi_callwait(), and my_callwait().

◆ CALLWAITING_SILENT_SAMPLES

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

300 ms

Definition at line 678 of file chan_dahdi.c.

◆ CALLWAITING_SUPPRESS_SAMPLES

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

100 ms

Definition at line 680 of file chan_dahdi.c.

Referenced by send_callerid().

◆ CANBUSYDETECT

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

Definition at line 593 of file chan_dahdi.c.

Referenced by dahdi_new().

◆ CANPROGRESSDETECT

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

◆ CHAN_PSEUDO

#define CHAN_PSEUDO   -2

◆ CIDCW_EXPIRE_SAMPLES

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

500 ms

Definition at line 681 of file chan_dahdi.c.

Referenced by send_callerid().

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

Referenced by dahdi_chan_conf_default().

◆ DEFAULT_DIALTONE_DETECT_TIMEOUT

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

10,000 ms

Definition at line 684 of file chan_dahdi.c.

Referenced by process_dahdi().

◆ DEFAULT_RINGT

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

8,000 ms

Definition at line 683 of file chan_dahdi.c.

◆ END_SILENCE_LEN

#define END_SILENCE_LEN   400

Referenced by dahdi_sendtext().

◆ FORMAT [1/2]

#define FORMAT   "%7s %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n"

◆ FORMAT [2/2]

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

◆ FORMAT2 [1/2]

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

◆ FORMAT2 [2/2]

#define FORMAT2   "%-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 3342 of file chan_dahdi.c.

◆ GET_CHANNEL

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

Definition at line 1053 of file chan_dahdi.c.

Referenced by dahdi_conf_update(), and my_complete_conference_update().

◆ HANGUP

#define HANGUP   1

Definition at line 16235 of file chan_dahdi.c.

Referenced by action_transferhangup(), and dahdi_fake_event().

◆ HEADER_LEN

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

◆ HEADER_MS

#define HEADER_MS   50

Referenced by dahdi_sendtext().

◆ ISTRUNK

#define ISTRUNK (   p)
Value:
((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
(p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
#define SIG_PRI
Definition: chan_dahdi.h:745
#define SIG_FXSGS
Definition: chan_dahdi.h:732
#define SIG_FXSKS
Definition: chan_dahdi.h:733
#define SIG_FXSLS
Definition: chan_dahdi.h:731

Definition at line 590 of file chan_dahdi.c.

Referenced by analog_ss_thread(), and dahdi_indicate().

◆ MASK_AVAIL

#define MASK_AVAIL   (1 << 0)

Channel available for PRI use

Definition at line 675 of file chan_dahdi.c.

◆ MASK_INUSE

#define MASK_INUSE   (1 << 1)

Channel currently in use

Definition at line 676 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 17726 of file chan_dahdi.c.

◆ MIN_MS_SINCE_FLASH

#define MIN_MS_SINCE_FLASH   ((2000) )

2000 ms

Definition at line 682 of file chan_dahdi.c.

Referenced by dahdi_handle_event().

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

Referenced by analog_ss_thread(), and dahdi_new().

◆ NUM_CADENCE_MAX

#define NUM_CADENCE_MAX   25

Definition at line 563 of file chan_dahdi.c.

Referenced by process_dahdi().

◆ NUM_SPANS

#define NUM_SPANS   32

◆ POLARITY_IDLE

#define POLARITY_IDLE   0

Definition at line 792 of file chan_dahdi.c.

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

◆ POLARITY_REV

#define POLARITY_REV   1

Definition at line 793 of file chan_dahdi.c.

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

◆ PROC_DAHDI_OPT_NOCHAN

#define PROC_DAHDI_OPT_NOCHAN   (1 << 0)

process_dahdi() - ignore keyword 'channel' and similar

Definition at line 17861 of file chan_dahdi.c.

Referenced by process_dahdi(), and setup_dahdi_int().

◆ PROC_DAHDI_OPT_NOWARN

#define PROC_DAHDI_OPT_NOWARN   (1 << 1)

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

Definition at line 17863 of file chan_dahdi.c.

Referenced by process_dahdi(), and setup_dahdi_int().

◆ READ_SIZE

#define READ_SIZE   160

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

Definition at line 673 of file chan_dahdi.c.

Referenced by dahdi_callwait(), dahdi_open(), dahdi_read(), dahdi_sendtext(), dahdi_setoption(), my_callwait(), my_dahdi_write(), my_send_callerid(), process_dahdi(), and send_cwcidspill().

◆ REPORT_CHANNEL_ALARMS

#define REPORT_CHANNEL_ALARMS   1

Definition at line 615 of file chan_dahdi.c.

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

◆ REPORT_SPAN_ALARMS

#define REPORT_SPAN_ALARMS   2

Definition at line 616 of file chan_dahdi.c.

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

◆ sig2str

#define sig2str   dahdi_sig2str

◆ SMDI_MD_WAIT_TIMEOUT

#define SMDI_MD_WAIT_TIMEOUT   1500 /* 1.5 seconds */

Definition at line 482 of file chan_dahdi.c.

Referenced by analog_ss_thread().

◆ TRAILER_MS

#define TRAILER_MS   5

Referenced by dahdi_sendtext().

◆ TRANSFER

#define TRANSFER   0

Definition at line 16234 of file chan_dahdi.c.

Referenced by action_transfer(), and dahdi_fake_event().

Function Documentation

◆ __dahdi_exception()

static struct ast_frame* __dahdi_exception ( struct ast_channel ast)
static

Definition at line 8281 of file chan_dahdi.c.

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

8282 {
8283  int res;
8284  int idx;
8285  struct ast_frame *f;
8286  int usedindex = -1;
8287  struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
8288 
8289  if ((idx = dahdi_get_index(ast, p, 0)) < 0) {
8290  idx = SUB_REAL;
8291  }
8292 
8293  p->subs[idx].f.frametype = AST_FRAME_NULL;
8294  p->subs[idx].f.datalen = 0;
8295  p->subs[idx].f.samples = 0;
8296  p->subs[idx].f.mallocd = 0;
8297  p->subs[idx].f.offset = 0;
8298  p->subs[idx].f.subclass.integer = 0;
8299  p->subs[idx].f.delivery = ast_tv(0,0);
8300  p->subs[idx].f.src = "dahdi_exception";
8301  p->subs[idx].f.data.ptr = NULL;
8302 
8303 
8304  if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
8305  /* If nobody owns us, absorb the event appropriately, otherwise
8306  we loop indefinitely. This occurs when, during call waiting, the
8307  other end hangs up our channel so that it no longer exists, but we
8308  have neither FLASH'd nor ONHOOK'd to signify our desire to
8309  change to the other channel. */
8310  if (p->fake_event) {
8311  res = p->fake_event;
8312  p->fake_event = 0;
8313  } else
8314  res = dahdi_get_event(p->subs[SUB_REAL].dfd);
8315  /* Switch to real if there is one and this isn't something really silly... */
8316  if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) &&
8317  (res != DAHDI_EVENT_HOOKCOMPLETE)) {
8318  ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
8319  p->owner = p->subs[SUB_REAL].owner;
8320  if (p->owner) {
8321  ast_queue_unhold(p->owner);
8322  }
8323  p->subs[SUB_REAL].needunhold = 1;
8324  }
8325  switch (res) {
8326  case DAHDI_EVENT_ONHOOK:
8327  dahdi_ec_disable(p);
8328  if (p->owner) {
8329  ast_verb(3, "Channel %s still has call, ringing phone\n", ast_channel_name(p->owner));
8330  dahdi_ring_phone(p);
8331  p->callwaitingrepeat = 0;
8332  p->cidcwexpire = 0;
8333  p->cid_suppress_expire = 0;
8334  } else
8335  ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
8336  dahdi_conf_update(p);
8337  break;
8338  case DAHDI_EVENT_RINGOFFHOOK:
8339  dahdi_ec_enable(p);
8340  dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
8341  if (p->owner && (ast_channel_state(p->owner) == AST_STATE_RINGING)) {
8342  p->subs[SUB_REAL].needanswer = 1;
8343  p->dialing = 0;
8344  }
8345  break;
8346  case DAHDI_EVENT_HOOKCOMPLETE:
8347  case DAHDI_EVENT_RINGERON:
8348  case DAHDI_EVENT_RINGEROFF:
8349  /* Do nothing */
8350  break;
8351  case DAHDI_EVENT_WINKFLASH:
8352  p->flashtime = ast_tvnow();
8353  if (p->owner) {
8354  ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, ast_channel_name(p->owner));
8355  if (ast_channel_state(p->owner) != AST_STATE_UP) {
8356  /* Answer if necessary */
8357  usedindex = dahdi_get_index(p->owner, p, 0);
8358  if (usedindex > -1) {
8359  p->subs[usedindex].needanswer = 1;
8360  }
8362  }
8363  p->callwaitingrepeat = 0;
8364  p->cidcwexpire = 0;
8365  p->cid_suppress_expire = 0;
8366  ast_queue_unhold(p->owner);
8367  p->subs[SUB_REAL].needunhold = 1;
8368  } else
8369  ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
8370  dahdi_conf_update(p);
8371  break;
8372  default:
8373  ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
8374  }
8375  f = &p->subs[idx].f;
8376  return f;
8377  }
8378  if (!(p->radio || (p->oprmode < 0)))
8379  ast_debug(1, "Exception on %d, channel %d\n", ast_channel_fd(ast, 0), p->channel);
8380  /* If it's not us, return NULL immediately */
8381  if (ast != p->owner) {
8382  if (p->owner) {
8383  ast_log(LOG_WARNING, "We're %s, not %s\n", ast_channel_name(ast), ast_channel_name(p->owner));
8384  }
8385  f = &p->subs[idx].f;
8386  return f;
8387  }
8388 
8389  f = dahdi_handle_event(ast);
8390  if (!f) {
8391  const char *name = ast_strdupa(ast_channel_name(ast));
8392 
8393  /* Tell the CDR this DAHDI device hung up */
8394  ast_mutex_unlock(&p->lock);
8395  ast_channel_unlock(ast);
8396  ast_set_hangupsource(ast, name, 0);
8397  ast_channel_lock(ast);
8398  ast_mutex_lock(&p->lock);
8399  }
8400  return f;
8401 }
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
static struct ast_frame * dahdi_handle_event(struct ast_channel *ast)
Definition: chan_dahdi.c:7386
#define ast_channel_lock(chan)
Definition: channel.h:2945
unsigned int dialing
TRUE if in the process of dialing digits or sending something.
Definition: chan_dahdi.h:234
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void dahdi_ec_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4638
unsigned int needanswer
Definition: chan_dahdi.h:86
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
#define LOG_WARNING
Definition: logger.h:274
char * name
Definition: chan_dahdi.c:4361
struct ast_channel * owner
Definition: chan_dahdi.h:127
ast_channel_state
ast_channel states
Definition: channelstate.h:35
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
void dahdi_ec_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4710
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
int callwaitingrepeat
Definition: chan_dahdi.h:546
void dahdi_conf_update(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4583
struct ast_frame f
Definition: chan_dahdi.h:82
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_frame_subclass subclass
int oprmode
Definition: chan_dahdi.h:150
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int dahdi_ring_phone(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7101
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it&#39;s bridge.
Definition: channel.c:2504
const char * src
unsigned int needunhold
Definition: chan_dahdi.h:89
struct timeval flashtime
Definition: chan_dahdi.h:637
ast_mutex_t lock
Definition: chan_dahdi.h:125
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ast_channel * owner
Definition: chan_dahdi.h:79
#define SUB_REAL
Definition: chan_dahdi.h:57
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922
static int dahdi_get_event(int fd)
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition: chan_dahdi.c:652
static const char * event2str(int event)
Definition: chan_dahdi.c:4382
struct timeval delivery
int fake_event
Holding place for event injected from outside normal operation.
Definition: chan_dahdi.h:667
int ast_channel_fd(const struct ast_channel *chan, int which)
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
const char * ast_channel_name(const struct ast_channel *chan)
int cidcwexpire
Definition: chan_dahdi.h:547
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
int cid_suppress_expire
Definition: chan_dahdi.h:548
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 19922 of file chan_dahdi.c.

◆ __unload_module()

static int __unload_module ( void  )
static

Definition at line 17540 of file chan_dahdi.c.

References ao2_cleanup, ARRAY_LEN, ast_cc_agent_unregister(), ast_cc_monitor_unregister(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_destroy, ast_manager_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_unregister_application(), ast_channel_tech::capabilities, dahdi_native_unload(), destroy_all_channels(), iflock, sig_pri_span::master, monitor_thread, monlock, dahdi_pvt::next, NULL, NUM_SPANS, dahdi_pvt::owner, SIG_PRI_NUM_DCHANS, sig_pri_stop_pri(), sig_pri_unload(), SIG_SS7_NUM_DCHANS, ss_thread_complete, and STASIS_MESSAGE_TYPE_CLEANUP.

Referenced by load_module(), and unload_module().

17541 {
17542  struct dahdi_pvt *p;
17543 #if defined(HAVE_PRI) || defined(HAVE_SS7)
17544  int i, j;
17545 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
17546 
17547 #ifdef HAVE_PRI
17548  for (i = 0; i < NUM_SPANS; i++) {
17549  if (pris[i].pri.master != AST_PTHREADT_NULL) {
17550  pthread_cancel(pris[i].pri.master);
17551  pthread_kill(pris[i].pri.master, SIGURG);
17552  }
17553  }
17554  ast_cli_unregister_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
17555  ast_unregister_application(dahdi_send_keypad_facility_app);
17556 #ifdef HAVE_PRI_PROG_W_CAUSE
17557  ast_unregister_application(dahdi_send_callrerouting_facility_app);
17558 #endif
17559 #endif
17560 #if defined(HAVE_SS7)
17561  for (i = 0; i < NUM_SPANS; i++) {
17562  if (linksets[i].ss7.master != AST_PTHREADT_NULL) {
17563  pthread_cancel(linksets[i].ss7.master);
17564  pthread_kill(linksets[i].ss7.master, SIGURG);
17565  }
17566  }
17567  ast_cli_unregister_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli));
17568 #endif /* defined(HAVE_SS7) */
17569 #if defined(HAVE_OPENR2)
17570  dahdi_r2_destroy_links();
17571  ast_cli_unregister_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli));
17572  ast_unregister_application(dahdi_accept_r2_call_app);
17573 #endif
17574 
17576  ast_manager_unregister("DAHDIDialOffhook");
17577  ast_manager_unregister("DAHDIHangup");
17578  ast_manager_unregister("DAHDITransfer");
17579  ast_manager_unregister("DAHDIDNDoff");
17580  ast_manager_unregister("DAHDIDNDon");
17581  ast_manager_unregister("DAHDIShowChannels");
17582  ast_manager_unregister("DAHDIRestart");
17583 #if defined(HAVE_PRI)
17584  ast_manager_unregister("PRIShowSpans");
17585  ast_manager_unregister("PRIDebugSet");
17586  ast_manager_unregister("PRIDebugFileSet");
17587  ast_manager_unregister("PRIDebugFileUnset");
17588 #endif /* defined(HAVE_PRI) */
17590 
17591  /* Hangup all interfaces if they have an owner */
17593  for (p = iflist; p; p = p->next) {
17594  if (p->owner)
17596  }
17598 
17601  pthread_cancel(monitor_thread);
17602  pthread_kill(monitor_thread, SIGURG);
17603  pthread_join(monitor_thread, NULL);
17604  }
17607 
17609 
17610 #if defined(HAVE_PRI)
17611  for (i = 0; i < NUM_SPANS; i++) {
17612  if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) {
17613  pthread_join(pris[i].pri.master, NULL);
17614  }
17615  for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) {
17616  dahdi_close_pri_fd(&(pris[i]), j);
17617  }
17618  sig_pri_stop_pri(&pris[i].pri);
17619  }
17620 #if defined(HAVE_PRI_CCSS)
17621  ast_cc_agent_unregister(&dahdi_pri_cc_agent_callbacks);
17622  ast_cc_monitor_unregister(&dahdi_pri_cc_monitor_callbacks);
17623 #endif /* defined(HAVE_PRI_CCSS) */
17624  sig_pri_unload();
17625 #endif
17626 
17627 #if defined(HAVE_SS7)
17628  for (i = 0; i < NUM_SPANS; i++) {
17629  if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) {
17630  pthread_join(linksets[i].ss7.master, NULL);
17631  }
17632  for (j = 0; j < SIG_SS7_NUM_DCHANS; j++) {
17633  dahdi_close_ss7_fd(&(linksets[i]), j);
17634  }
17635  if (linksets[i].ss7.ss7) {
17636  ss7_destroy(linksets[i].ss7.ss7);
17637  linksets[i].ss7.ss7 = NULL;
17638  }
17639  }
17640 #endif /* defined(HAVE_SS7) */
17642 
17644 
17647  STASIS_MESSAGE_TYPE_CLEANUP(dahdichannel_type);
17648  return 0;
17649 }
void sig_pri_unload(void)
void ast_cc_agent_unregister(const struct ast_cc_agent_callbacks *callbacks)
Unregister a set of agent callbacks with the core.
Definition: ccss.c:1254
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_cli_entry dahdi_cli[]
Definition: chan_dahdi.c:16220
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
static struct ast_channel_tech dahdi_tech
Definition: chan_dahdi.c:1030
struct ast_channel * owner
Definition: chan_dahdi.h:127
static ast_cond_t ss_thread_complete
Definition: chan_dahdi.c:641
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static void destroy_all_channels(void)
Definition: chan_dahdi.c:5667
static ast_mutex_t monlock
Protect the monitoring thread, so only one process can kill or start it, and not when it&#39;s doing some...
Definition: chan_dahdi.c:636
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:640
#define AST_PTHREADT_NULL
Definition: lock.h:66
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
#define SIG_SS7_NUM_DCHANS
Definition: sig_ss7.h:56
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:241
#define ast_cond_destroy(cond)
Definition: lock.h:200
struct ast_format_cap * capabilities
Definition: channel.h:633
void dahdi_native_unload(void)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void sig_pri_stop_pri(struct sig_pri_span *pri)
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
#define AST_PTHREADT_STOP
Definition: lock.h:67
void ast_cc_monitor_unregister(const struct ast_cc_monitor_callbacks *callbacks)
Unregister a set of monitor callbacks with the core.
Definition: ccss.c:1217
#define NUM_SPANS
Definition: chan_dahdi.c:553
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 19922 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 3431 of file chan_dahdi.c.

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

3432 {
3433  int res;
3434  if (p->subs[SUB_REAL].owner == ast)
3435  res = 0;
3436  else if (p->subs[SUB_CALLWAIT].owner == ast)
3437  res = 1;
3438  else if (p->subs[SUB_THREEWAY].owner == ast)
3439  res = 2;
3440  else {
3441  res = -1;
3442  if (!nullok)
3444  "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
3445  ast ? ast_channel_name(ast) : "", p->channel, fname, line);
3446  }
3447  return res;
3448 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define SUB_THREEWAY
Definition: chan_dahdi.h:59
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
struct ast_channel * owner
Definition: chan_dahdi.h:79
#define SUB_REAL
Definition: chan_dahdi.h:57
const char * ast_channel_name(const struct ast_channel *chan)
int channel
Definition: chan_dahdi.h:538
#define SUB_CALLWAIT
Definition: chan_dahdi.h:58

◆ action_dahdidialoffhook()

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

Definition at line 16372 of file chan_dahdi.c.

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

Referenced by load_module().

16373 {
16374  struct dahdi_pvt *p;
16375  const char *channel = astman_get_header(m, "DAHDIChannel");
16376  const char *number = astman_get_header(m, "Number");
16377  int i;
16378 
16379  if (ast_strlen_zero(channel)) {
16380  astman_send_error(s, m, "No channel specified");
16381  return 0;
16382  }
16383  if (ast_strlen_zero(number)) {
16384  astman_send_error(s, m, "No number specified");
16385  return 0;
16386  }
16387  p = find_channel_from_str(channel);
16388  if (!p) {
16389  astman_send_error(s, m, "No such channel");
16390  return 0;
16391  }
16392  if (!p->owner) {
16393  astman_send_error(s, m, "Channel does not have it's owner");
16394  return 0;
16395  }
16396  for (i = 0; i < strlen(number); i++) {
16397  struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = number[i] };
16398  dahdi_queue_frame(p, &f);
16399  }
16400  astman_send_ack(s, m, "DAHDIDialOffhook");
16401  return 0;
16402 }
struct ast_channel * owner
Definition: chan_dahdi.h:127
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
Definition: muted.c:95
static struct dahdi_pvt * find_channel_from_str(const char *channel)
Definition: chan_dahdi.c:16276
#define AST_FRAME_DTMF
static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
Definition: chan_dahdi.c:3490
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
Data structure associated with a single frame of data.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ action_dahdidndoff()

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

Definition at line 16307 of file chan_dahdi.c.

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

Referenced by load_module().

16308 {
16309  struct dahdi_pvt *p;
16310  const char *channel = astman_get_header(m, "DAHDIChannel");
16311 
16312  if (ast_strlen_zero(channel)) {
16313  astman_send_error(s, m, "No channel specified");
16314  return 0;
16315  }
16316  p = find_channel_from_str(channel);
16317  if (!p) {
16318  astman_send_error(s, m, "No such channel");
16319  return 0;
16320  }
16321  dahdi_dnd(p, 0);
16322  astman_send_ack(s, m, "DND Disabled");
16323  return 0;
16324 }
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
Definition: muted.c:95
static struct dahdi_pvt * find_channel_from_str(const char *channel)
Definition: chan_dahdi.c:16276
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:9466
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ action_dahdidndon()

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

Definition at line 16288 of file chan_dahdi.c.

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

Referenced by load_module().

16289 {
16290  struct dahdi_pvt *p;
16291  const char *channel = astman_get_header(m, "DAHDIChannel");
16292 
16293  if (ast_strlen_zero(channel)) {
16294  astman_send_error(s, m, "No channel specified");
16295  return 0;
16296  }
16297  p = find_channel_from_str(channel);
16298  if (!p) {
16299  astman_send_error(s, m, "No such channel");
16300  return 0;
16301  }
16302  dahdi_dnd(p, 1);
16303  astman_send_ack(s, m, "DND Enabled");
16304  return 0;
16305 }
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
Definition: muted.c:95
static struct dahdi_pvt * find_channel_from_str(const char *channel)
Definition: chan_dahdi.c:16276
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:9466
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ action_dahdirestart()

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

Definition at line 15562 of file chan_dahdi.c.

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

Referenced by load_module().

15563 {
15564  if (dahdi_restart() != 0) {
15565  astman_send_error(s, m, "Failed rereading DAHDI configuration");
15566  return 1;
15567  }
15568  astman_send_ack(s, m, "DAHDIRestart: Success");
15569  return 0;
15570 }
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
static int dahdi_restart(void)
Definition: chan_dahdi.c:15424
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ action_dahdishowchannels()

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

Definition at line 16404 of file chan_dahdi.c.

References alarm2str(), ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_assert, ast_channel_accountcode(), ast_channel_name(), ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_uniqueid(), ast_cli(), AST_CLI_DEFINE, ast_log, ast_module_ref, ast_module_unref, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, ast_strlen_zero, astman_append(), astman_get_header(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), sig_ss7_linkset::called_nai, sig_ss7_linkset::calling_nai, sig_ss7_chan::chan_pvt, sig_ss7_chan::channel, dahdi_pvt::channel, sig_ss7_chan::cic, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_pvt::context, dahdi_dnd(), dahdi_sig_pri_lib_handles(), dahdi_pvt::description, sig_ss7_chan::dpc, errno, ast_cli_args::fd, sig_ss7_linkset::flags, FORMAT, FORMAT2, get_alarms(), iflock, dahdi_pvt::inservice, sig_ss7_linkset::internationalprefix, sig_ss7_linkset::LINKSET_STATE_UP, dahdi_pvt::locallyblocked, LOG_ERROR, sig_ss7_linkset::nationalprefix, sig_ss7_linkset::networkroutedprefix, dahdi_pvt::next, NULL, NUM_SPANS, sig_ss7_linkset::numchans, dahdi_pvt::owner, sig_ss7_chan::owner, sig_ss7_linkset::pvts, dahdi_pvt::remotelyblocked, ast_module_info::self, dahdi_pvt::sig, sig2str, sig_pri_ami_show_spans(), sig_pri_cc_agent_callee_available(), sig_pri_cc_agent_destructor(), sig_pri_cc_agent_init(), sig_pri_cc_agent_party_b_free(), sig_pri_cc_agent_req_rsp(), sig_pri_cc_agent_start_monitoring(), sig_pri_cc_agent_start_offer_timer(), sig_pri_cc_agent_status_req(), sig_pri_cc_agent_stop_offer_timer(), sig_pri_cc_agent_stop_ringing(), sig_pri_cc_monitor_cancel_available_timer(), sig_pri_cc_monitor_destructor(), sig_pri_cc_monitor_req_cc(), sig_pri_cc_monitor_status_rsp(), sig_pri_cc_monitor_suspend(), sig_pri_cc_monitor_unsuspend(), dahdi_pvt::sig_pvt, sig_ss7_add_sigchan(), sig_ss7_cic_blocking(), sig_ss7_cli_show_channels(), sig_ss7_cli_show_channels_header(), SIG_SS7_DEBUG, sig_ss7_find_cic(), sig_ss7_find_cic_range(), sig_ss7_group_blocking(), SIG_SS7_NUM_DCHANS, sig_ss7_reset_cic(), sig_ss7_reset_group(), sig_ss7_linkset::ss7, SS7_BLOCKED_HARDWARE, SS7_BLOCKED_MAINTENANCE, sig_ss7_chan::ss7call, sig_ss7_linkset::state, state, sig_ss7_linkset::subscriberprefix, tmp(), type, ast_cc_monitor_callbacks::type, ast_cc_agent_callbacks::type, sig_ss7_linkset::unknownprefix, and ast_cli_entry::usage.

Referenced by load_module().

16405 {
16406  struct dahdi_pvt *tmp = NULL;
16407  const char *id = astman_get_header(m, "ActionID");
16408  const char *dahdichannel = astman_get_header(m, "DAHDIChannel");
16409  char idText[256];
16410  int channels = 0;
16411  int dahdichanquery;
16412 
16413  if (!dahdichannel || sscanf(dahdichannel, "%30d", &dahdichanquery) != 1) {
16414  /* Not numeric string. */
16415  dahdichanquery = -1;
16416  }
16417 
16418  idText[0] = '\0';
16419  if (!ast_strlen_zero(id)) {
16420  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
16421  }
16422 
16423  astman_send_listack(s, m, "DAHDI channel status will follow", "start");
16424 
16426 
16427  for (tmp = iflist; tmp; tmp = tmp->next) {
16428  if (tmp->channel > 0) {
16429  int alm;
16430 
16431  /* If a specific channel is queried for, only deliver status for that channel */
16432  if (dahdichanquery > 0 && tmp->channel != dahdichanquery)
16433  continue;
16434 
16435  alm = get_alarms(tmp);
16436  channels++;
16437  if (tmp->owner) {
16438  /* Add data if we have a current call */
16439  astman_append(s,
16440  "Event: DAHDIShowChannels\r\n"
16441  "DAHDIChannel: %d\r\n"
16442  "Channel: %s\r\n"
16443  "Uniqueid: %s\r\n"
16444  "AccountCode: %s\r\n"
16445  "Signalling: %s\r\n"
16446  "SignallingCode: %d\r\n"
16447  "Context: %s\r\n"
16448  "DND: %s\r\n"
16449  "Alarm: %s\r\n"
16450  "Description: %s\r\n"
16451  "%s"
16452  "\r\n",
16453  tmp->channel,
16454  ast_channel_name(tmp->owner),
16457  sig2str(tmp->sig),
16458  tmp->sig,
16459  tmp->context,
16460  dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled",
16461  alarm2str(alm),
16462  tmp->description, idText);
16463  } else {
16464  astman_append(s,
16465  "Event: DAHDIShowChannels\r\n"
16466  "DAHDIChannel: %d\r\n"
16467  "Signalling: %s\r\n"
16468  "SignallingCode: %d\r\n"
16469  "Context: %s\r\n"
16470  "DND: %s\r\n"
16471  "Alarm: %s\r\n"
16472  "Description: %s\r\n"
16473  "%s"
16474  "\r\n",
16475  tmp->channel, sig2str(tmp->sig), tmp->sig,
16476  tmp->context,
16477  dahdi_dnd(tmp, -1) ? "Enabled" : "Disabled",
16478  alarm2str(alm),
16479  tmp->description, idText);
16480  }
16481  }
16482  }
16483 
16485 
16486  astman_send_list_complete_start(s, m, "DAHDIShowChannelsComplete", channels);
16487  astman_append(s, "Items: %d\r\n", channels);
16489  return 0;
16490 }
char description[32]
A description for the channel configuration.
Definition: chan_dahdi.h:449
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
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:3237
struct ast_channel * owner
Definition: chan_dahdi.h:127
static int tmp()
Definition: bt_open.c:389
static char * alarm2str(int alm)
Definition: chan_dahdi.c:4372
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:9466
const char * ast_channel_accountcode(const struct ast_channel *chan)
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
static struct channel_usage channels
const char * ast_channel_uniqueid(const struct ast_channel *chan)
static int get_alarms(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7204
char context[AST_MAX_CONTEXT]
The configured context for incoming calls.
Definition: chan_dahdi.h:444
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
const char * ast_channel_name(const struct ast_channel *chan)
#define sig2str
Definition: chan_dahdi.c:4455
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188
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:3201

◆ action_transfer()

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

Definition at line 16326 of file chan_dahdi.c.

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

Referenced by load_module().

16327 {
16328  struct dahdi_pvt *p;
16329  const char *channel = astman_get_header(m, "DAHDIChannel");
16330 
16331  if (ast_strlen_zero(channel)) {
16332  astman_send_error(s, m, "No channel specified");
16333  return 0;
16334  }
16335  p = find_channel_from_str(channel);
16336  if (!p) {
16337  astman_send_error(s, m, "No such channel");
16338  return 0;
16339  }
16340  if (!dahdi_analog_lib_handles(p->sig, 0, 0)) {
16341  astman_send_error(s, m, "Channel signaling is not analog");
16342  return 0;
16343  }
16345  astman_send_ack(s, m, "DAHDITransfer");
16346  return 0;
16347 }
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
Definition: muted.c:95
static struct dahdi_pvt * find_channel_from_str(const char *channel)
Definition: chan_dahdi.c:16276
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define TRANSFER
Definition: chan_dahdi.c:16234
static int dahdi_fake_event(struct dahdi_pvt *p, int mode)
Definition: chan_dahdi.c:16237
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ action_transferhangup()

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

Definition at line 16349 of file chan_dahdi.c.

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

Referenced by load_module().

16350 {
16351  struct dahdi_pvt *p;
16352  const char *channel = astman_get_header(m, "DAHDIChannel");
16353 
16354  if (ast_strlen_zero(channel)) {
16355  astman_send_error(s, m, "No channel specified");
16356  return 0;
16357  }
16358  p = find_channel_from_str(channel);
16359  if (!p) {
16360  astman_send_error(s, m, "No such channel");
16361  return 0;
16362  }
16363  if (!dahdi_analog_lib_handles(p->sig, 0, 0)) {
16364  astman_send_error(s, m, "Channel signaling is not analog");
16365  return 0;
16366  }
16368  astman_send_ack(s, m, "DAHDIHangup");
16369  return 0;
16370 }
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
Definition: muted.c:95
static struct dahdi_pvt * find_channel_from_str(const char *channel)
Definition: chan_dahdi.c:16276
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int dahdi_fake_event(struct dahdi_pvt *p, int mode)
Definition: chan_dahdi.c:16237
#define HANGUP
Definition: chan_dahdi.c:16235
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ alarm2str()

static char* alarm2str ( int  alm)
static

Definition at line 4372 of file chan_dahdi.c.

References alarm, alarms, and ARRAY_LEN.

Referenced by action_dahdishowchannels(), and handle_alarms().

4373 {
4374  int x;
4375  for (x = 0; x < ARRAY_LEN(alarms); x++) {
4376  if (alarms[x].alarm & alm)
4377  return alarms[x].name;
4378  }
4379  return alm ? "Unknown Alarm" : "No Alarm";
4380 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct @109 alarms[]
int alarm
Definition: chan_dahdi.c:4360

◆ alloc_sub()

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

Definition at line 4167 of file chan_dahdi.c.

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

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

4168 {
4169  struct dahdi_bufferinfo bi;
4170  int res;
4171  if (p->subs[x].dfd >= 0) {
4172  ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
4173  return -1;
4174  }
4175 
4176  p->subs[x].dfd = dahdi_open("/dev/dahdi/pseudo");
4177  if (p->subs[x].dfd <= -1) {
4178  ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
4179  return -1;
4180  }
4181 
4182  res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi);
4183  if (!res) {
4184  bi.txbufpolicy = p->buf_policy;
4185  bi.rxbufpolicy = p->buf_policy;
4186  bi.numbufs = p->buf_no;
4187  res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi);
4188  if (res < 0) {
4189  ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno));
4190  }
4191  } else
4192  ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno));
4193 
4194  if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) {
4195  ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno));
4196  dahdi_close_sub(p, x);
4197  p->subs[x].dfd = -1;
4198  return -1;
4199  }
4200  ast_debug(1, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan);
4201  return 0;
4202 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
int buf_no
Definition: chan_dahdi.h:139
static void dahdi_close_sub(struct dahdi_pvt *chan_pvt, int sub_num)
Definition: chan_dahdi.c:4139
const char *const subnames[]
Definition: chan_dahdi.c:795
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int dahdi_open(char *fn)
Definition: chan_dahdi.c:4086
int errno
int buf_policy
Definition: chan_dahdi.h:140
int channel
Definition: chan_dahdi.h:538

◆ analog_ss_thread()

static void * analog_ss_thread ( void *  data)
static

Definition at line 9512 of file chan_dahdi.c.

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, 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_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(), exten, dahdi_pvt::firstdigit_timeout, 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, 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(), timeout, 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(), dahdi_ring_phone(), do_monitor(), handle_init_event(), and mwi_thread().

9513 {
9514  struct ast_channel *chan = data;
9515  struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
9516  char exten[AST_MAX_EXTENSION] = "";
9517  char exten2[AST_MAX_EXTENSION] = "";
9518  unsigned char buf[256];
9519  char dtmfcid[300];
9520  char dtmfbuf[300];
9521  struct callerid_state *cs = NULL;
9522  char *name = NULL, *number = NULL;
9523  int distMatches;
9524  int curRingData[3];
9525  int receivedRingT;
9526  int counter1;
9527  int counter;
9528  int samples = 0;
9529  struct ast_smdi_md_message *smdi_msg = NULL;
9530  int flags = 0;
9531  int i;
9532  int timeout;
9533  int getforward = 0;
9534  char *s1, *s2;
9535  int len = 0;
9536  int res;
9537  int idx;
9538  RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
9539  const char *pickupexten;
9540 
9542  ss_thread_count++;
9544  /* in the bizarre case where the channel has become a zombie before we
9545  even get started here, abort safely
9546  */
9547  if (!p) {
9548  ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", ast_channel_name(chan));
9549  ast_hangup(chan);
9550  goto quit;
9551  }
9552  ast_verb(3, "Starting simple switch on '%s'\n", ast_channel_name(chan));
9553  idx = dahdi_get_index(chan, p, 1);
9554  if (idx < 0) {
9555  ast_log(LOG_WARNING, "Huh?\n");
9556  ast_hangup(chan);
9557  goto quit;
9558  }
9559 
9560  ast_channel_lock(chan);
9561  pickup_cfg = ast_get_chan_features_pickup_config(chan);
9562  if (!pickup_cfg) {
9563  ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
9564  pickupexten = "";
9565  } else {
9566  pickupexten = ast_strdupa(pickup_cfg->pickupexten);
9567  }
9568  ast_channel_unlock(chan);
9569 
9570  if (p->dsp)
9571  ast_dsp_digitreset(p->dsp);
9572  switch (p->sig) {
9573  case SIG_FEATD:
9574  case SIG_FEATDMF:
9575  case SIG_FEATDMF_TA:
9576  case SIG_E911:
9577  case SIG_FGC_CAMAMF:
9578  case SIG_FEATB:
9579  case SIG_EMWINK:
9580  case SIG_SF_FEATD:
9581  case SIG_SF_FEATDMF:
9582  case SIG_SF_FEATB:
9583  case SIG_SFWINK:
9584  if (dahdi_wink(p, idx))
9585  goto quit;
9586  /* Fall through */
9587  case SIG_EM:
9588  case SIG_EM_E1:
9589  case SIG_SF:
9590  case SIG_FGC_CAMA:
9591  res = tone_zone_play_tone(p->subs[idx].dfd, -1);
9592  if (p->dsp)
9593  ast_dsp_digitreset(p->dsp);
9594  /* set digit mode appropriately */
9595  if (p->dsp) {
9596  if (NEED_MFDETECT(p))
9598  else
9600  }
9601  memset(dtmfbuf, 0, sizeof(dtmfbuf));
9602  /* Wait for the first digit only if immediate=no */
9603  if (!p->immediate)
9604  /* Wait for the first digit (up to 5 seconds). */
9605  res = ast_waitfordigit(chan, 5000);
9606  else
9607  res = 0;
9608  if (res > 0) {
9609  /* save first char */
9610  dtmfbuf[0] = res;
9611  switch (p->sig) {
9612  case SIG_FEATD:
9613  case SIG_SF_FEATD:
9614  res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
9615  if (res > 0)
9616  res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
9617  if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
9618  break;
9619  case SIG_FEATDMF_TA:
9620  res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
9621  if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
9622  if (dahdi_wink(p, idx)) goto quit;
9623  dtmfbuf[0] = 0;
9624  /* Wait for the first digit (up to 5 seconds). */
9625  res = ast_waitfordigit(chan, 5000);
9626  if (res <= 0) break;
9627  dtmfbuf[0] = res;
9628  /* fall through intentionally */
9629  case SIG_FEATDMF:
9630  case SIG_E911:
9631  case SIG_FGC_CAMAMF:
9632  case SIG_SF_FEATDMF:
9633  res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
9634  /* if international caca, do it again to get real ANO */
9635  if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
9636  {
9637  if (dahdi_wink(p, idx)) goto quit;
9638  dtmfbuf[0] = 0;
9639  /* Wait for the first digit (up to 5 seconds). */
9640  res = ast_waitfordigit(chan, 5000);
9641  if (res <= 0) break;
9642  dtmfbuf[0] = res;
9643  res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
9644  }
9645  if (res > 0) {
9646  /* if E911, take off hook */
9647  if (p->sig == SIG_E911)
9648  dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
9649  res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
9650  }
9651  if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
9652  break;
9653  case SIG_FEATB:
9654  case SIG_SF_FEATB:
9655  res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
9656  if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
9657  break;
9658  case SIG_EMWINK:
9659  /* if we received a '*', we are actually receiving Feature Group D
9660  dial syntax, so use that mode; otherwise, fall through to normal
9661  mode
9662  */
9663  if (res == '*') {
9664  res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
9665  if (res > 0)
9666  res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
9667  if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
9668  break;
9669  }
9670  default:
9671  /* If we got the first digit, get the rest */
9672  len = 1;
9673  dtmfbuf[len] = '\0';
9674  while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
9675  if (ast_exists_extension(chan, ast_channel_context(chan), dtmfbuf, 1, p->cid_num)) {
9676  timeout = p->matchdigit_timeout;
9677  } else {
9678  timeout = p->interdigit_timeout;
9679  }
9680  res = ast_waitfordigit(chan, timeout);
9681  if (res < 0) {
9682  ast_debug(1, "waitfordigit returned < 0...\n");
9683  ast_hangup(chan);
9684  goto quit;
9685  } else if (res) {
9686  dtmfbuf[len++] = res;
9687  dtmfbuf[len] = '\0';
9688  } else {
9689  break;
9690  }
9691  }
9692  break;
9693  }
9694  }
9695  if (res == -1) {
9696  ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
9697  ast_hangup(chan);
9698  goto quit;
9699  } else if (res < 0) {
9700  ast_debug(1, "Got hung up before digits finished\n");
9701  ast_hangup(chan);
9702  goto quit;
9703  }
9704 
9705  if (p->sig == SIG_FGC_CAMA) {
9706  char anibuf[100];
9707 
9708  if (ast_safe_sleep(chan,1000) == -1) {
9709  ast_hangup(chan);
9710  goto quit;
9711  }
9712  dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
9714  res = my_getsigstr(chan, anibuf, "#", 10000);
9715  if ((res > 0) && (strlen(anibuf) > 2)) {
9716  if (anibuf[strlen(anibuf) - 1] == '#')
9717  anibuf[strlen(anibuf) - 1] = 0;
9718  ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
9719  }
9721  }
9722 
9723  ast_copy_string(exten, dtmfbuf, sizeof(exten));
9724  if (ast_strlen_zero(exten))
9725  ast_copy_string(exten, "s", sizeof(exten));
9726  if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
9727  /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
9728  if (exten[0] == '*') {
9729  char *stringp=NULL;
9730  ast_copy_string(exten2, exten, sizeof(exten2));
9731  /* Parse out extension and callerid */
9732  stringp=exten2 +1;
9733  s1 = strsep(&stringp, "*");
9734  s2 = strsep(&stringp, "*");
9735  if (s2) {
9736  if (!ast_strlen_zero(p->cid_num))
9737  ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
9738  else
9739  ast_set_callerid(chan, s1, NULL, s1);
9740  ast_copy_string(exten, s2, sizeof(exten));
9741  } else
9742  ast_copy_string(exten, s1, sizeof(exten));
9743  } else if (p->sig == SIG_FEATD)
9744  ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel);
9745  }
9746  if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
9747  if (exten[0] == '*') {
9748  char *stringp=NULL;
9749  ast_copy_string(exten2, exten, sizeof(exten2));
9750  /* Parse out extension and callerid */
9751  stringp=exten2 +1;
9752  s1 = strsep(&stringp, "#");
9753  s2 = strsep(&stringp, "#");
9754  if (s2) {
9755  if (!ast_strlen_zero(p->cid_num))
9756  ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
9757  else
9758  if (*(s1 + 2))
9759  ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
9760  ast_copy_string(exten, s2 + 1, sizeof(exten));
9761  } else
9762  ast_copy_string(exten, s1 + 2, sizeof(exten));
9763  } else
9764  ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel);
9765  }
9766  if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
9767  if (exten[0] == '*') {
9768  char *stringp=NULL;
9769  ast_copy_string(exten2, exten, sizeof(exten2));
9770  /* Parse out extension and callerid */
9771  stringp=exten2 +1;
9772  s1 = strsep(&stringp, "#");
9773  s2 = strsep(&stringp, "#");
9774  if (s2 && (*(s2 + 1) == '0')) {
9775  if (*(s2 + 2))
9776  ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
9777  }
9778  if (s1) ast_copy_string(exten, s1, sizeof(exten));
9779  else ast_copy_string(exten, "911", sizeof(exten));
9780  } else
9781  ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel);
9782  }
9783  if (p->sig == SIG_FEATB) {
9784  if (exten[0] == '*') {
9785  char *stringp=NULL;
9786  ast_copy_string(exten2, exten, sizeof(exten2));
9787  /* Parse out extension and callerid */
9788  stringp=exten2 +1;
9789  s1 = strsep(&stringp, "#");
9790  ast_copy_string(exten, exten2 + 1, sizeof(exten));
9791  } else
9792  ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel);
9793  }
9794  if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
9795  dahdi_wink(p, idx);
9796  /* some switches require a minimum guard time between
9797  the last FGD wink and something that answers
9798  immediately. This ensures it */
9799  if (ast_safe_sleep(chan, 100)) {
9800  ast_hangup(chan);
9801  goto quit;
9802  }
9803  }
9804  dahdi_ec_enable(p);
9805  if (NEED_MFDETECT(p)) {
9806  if (p->dsp) {
9807  if (!p->hardwaredtmf)
9809  else {
9810  ast_dsp_free(p->dsp);
9811  p->dsp = NULL;
9812  }
9813  }
9814  }
9815 
9816  if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1,
9817  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
9818  ast_channel_exten_set(chan, exten);
9819  if (p->dsp) ast_dsp_digitreset(p->dsp);
9820  res = ast_pbx_run(chan);
9821  if (res) {
9822  ast_log(LOG_WARNING, "PBX exited non-zero\n");
9823  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
9824  }
9825  goto quit;
9826  } else {
9827  ast_verb(2, "Unknown extension '%s' in context '%s' requested\n", exten, ast_channel_context(chan));
9828  sleep(2);
9829  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_INFO);
9830  if (res < 0)
9831  ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
9832  else
9833  sleep(1);
9834  res = ast_streamfile(chan, "ss-noservice", ast_channel_language(chan));
9835  if (res >= 0)
9836  ast_waitstream(chan, "");
9837  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
9838  ast_hangup(chan);
9839  goto quit;
9840  }
9841  break;
9842  case SIG_FXOLS:
9843  case SIG_FXOGS:
9844  case SIG_FXOKS:
9845  /* Read the first digit */
9846  timeout = p->firstdigit_timeout;
9847  /* If starting a threeway call, never timeout on the first digit so someone
9848  can use flash-hook as a "hold" feature */
9849  if (p->subs[SUB_THREEWAY].owner)
9850  timeout = INT_MAX;
9851  while (len < AST_MAX_EXTENSION-1) {
9852  int is_exten_parking = 0;
9853 
9854  /* Read digit unless it's supposed to be immediate, in which case the
9855  only answer is 's' */
9856  if (p->immediate)
9857  res = 's';
9858  else
9859  res = ast_waitfordigit(chan, timeout);
9860  timeout = 0;
9861  if (res < 0) {
9862  ast_debug(1, "waitfordigit returned < 0...\n");
9863  res = tone_zone_play_tone(p->subs[idx].dfd, -1);
9864  ast_hangup(chan);
9865  goto quit;
9866  } else if (res) {
9867  ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
9868  exten[len++]=res;
9869  exten[len] = '\0';
9870  }
9871  if (!ast_ignore_pattern(ast_channel_context(chan), exten)) {
9872  tone_zone_play_tone(p->subs[idx].dfd, -1);
9873  } else {
9874  tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE);
9875  }
9877  is_exten_parking = ast_parking_is_exten_park(ast_channel_context(chan), exten);
9878  }
9879  if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num) && !is_exten_parking) {
9880  if (!res || !ast_matchmore_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) {
9881  if (getforward) {
9882  /* Record this as the forwarding extension */
9883  ast_copy_string(p->call_forward, exten, sizeof(p->call_forward));
9884  ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
9885  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
9886  if (res)
9887  break;
9888  usleep(500000);
9889  res = tone_zone_play_tone(p->subs[idx].dfd, -1);
9890  sleep(1);
9891  memset(exten, 0, sizeof(exten));
9892  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE);
9893  len = 0;
9894  getforward = 0;
9895  } else {
9896  res = tone_zone_play_tone(p->subs[idx].dfd, -1);
9897  ast_channel_lock(chan);
9898  ast_channel_exten_set(chan, exten);
9899  if (!ast_strlen_zero(p->cid_num)) {
9900  if (!p->hidecallerid)
9901  ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
9902  else
9903  ast_set_callerid(chan, NULL, NULL, p->cid_num);
9904  }
9905  if (!ast_strlen_zero(p->cid_name)) {
9906  if (!p->hidecallerid)
9907  ast_set_callerid(chan, NULL, p->cid_name, NULL);
9908  }
9910  ast_channel_unlock(chan);
9911  dahdi_ec_enable(p);
9912  res = ast_pbx_run(chan);
9913  if (res) {
9914  ast_log(LOG_WARNING, "PBX exited non-zero\n");
9915  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
9916  }
9917  goto quit;
9918  }
9919  } else {
9920  /* It's a match, but they just typed a digit, and there is an ambiguous match,
9921  so just set the timeout to matchdigit_timeout and wait some more */
9922  timeout = p->matchdigit_timeout;
9923  }
9924  } else if (res == 0) {
9925  ast_debug(1, "not enough digits (and no ambiguous match)...\n");
9926  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
9927  dahdi_wait_event(p->subs[idx].dfd);
9928  ast_hangup(chan);
9929  goto quit;
9930  } else if (p->callwaiting && !strcmp(exten, "*70")) {
9931  ast_verb(3, "Disabling call waiting on %s\n", ast_channel_name(chan));
9932  /* Disable call waiting if enabled */
9933  p->callwaiting = 0;
9934  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
9935  if (res) {
9936  ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
9937  ast_channel_name(chan), strerror(errno));
9938  }
9939  len = 0;
9940  ioctl(p->subs[idx].dfd,DAHDI_CONFDIAG,&len);
9941  memset(exten, 0, sizeof(exten));
9942  timeout = p->firstdigit_timeout;
9943 
9944  } else if (!strcmp(exten, pickupexten)) {
9945  /* Scan all channels and see if there are any
9946  * ringing channels that have call groups
9947  * that equal this channels pickup group
9948  */
9949  if (idx == SUB_REAL) {
9950  /* Switch us from Third call to Call Wait */
9951  if (p->subs[SUB_THREEWAY].owner) {
9952  /* If you make a threeway call and the *8# a call, it should actually
9953  look like a callwait */
9954  alloc_sub(p, SUB_CALLWAIT);
9957  }
9958  dahdi_ec_enable(p);
9959  if (ast_pickup_call(chan)) {
9960  ast_debug(1, "No call pickup possible...\n");
9961  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
9962  dahdi_wait_event(p->subs[idx].dfd);
9963  }
9964  ast_hangup(chan);
9965  goto quit;
9966  } else {
9967  ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n");
9968  ast_hangup(chan);
9969  goto quit;
9970  }
9971 
9972  } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
9973  ast_verb(3, "Disabling Caller*ID on %s\n", ast_channel_name(chan));
9974  /* Disable Caller*ID if enabled */
9975  p->hidecallerid = 1;
9976  ast_party_number_free(&ast_channel_caller(chan)->id.number);
9977  ast_party_number_init(&ast_channel_caller(chan)->id.number);
9978  ast_party_name_free(&ast_channel_caller(chan)->id.name);
9979  ast_party_name_init(&ast_channel_caller(chan)->id.name);
9980  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
9981  if (res) {
9982  ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
9983  ast_channel_name(chan), strerror(errno));
9984  }
9985  len = 0;
9986  memset(exten, 0, sizeof(exten));
9987  timeout = p->firstdigit_timeout;
9988  } else if (p->callreturn && !strcmp(exten, "*69")) {
9989  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
9990  break;
9991  } else if (!strcmp(exten, "*78")) {
9992  dahdi_dnd(p, 1);
9993  /* Do not disturb */
9994  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
9995  getforward = 0;
9996  memset(exten, 0, sizeof(exten));
9997  len = 0;
9998  } else if (!strcmp(exten, "*79")) {
9999  dahdi_dnd(p, 0);
10000  /* Do not disturb */
10001  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10002  getforward = 0;
10003  memset(exten, 0, sizeof(exten));
10004  len = 0;
10005  } else if (p->cancallforward && !strcmp(exten, "*72")) {
10006  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10007  getforward = 1;
10008  memset(exten, 0, sizeof(exten));
10009  len = 0;
10010  } else if (p->cancallforward && !strcmp(exten, "*73")) {
10011  ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel);
10012  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10013  memset(p->call_forward, 0, sizeof(p->call_forward));
10014  getforward = 0;
10015  memset(exten, 0, sizeof(exten));
10016  len = 0;
10017  } else if ((p->transfer || p->canpark) && is_exten_parking
10018  && p->subs[SUB_THREEWAY].owner) {
10019  struct ast_bridge_channel *bridge_channel;
10020 
10021  /*
10022  * This is a three way call, the main call being a real channel,
10023  * and we're parking the first call.
10024  */
10026  bridge_channel = ast_channel_get_bridge_channel(p->subs[SUB_THREEWAY].owner);
10028  if (bridge_channel) {
10029  if (!ast_parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), exten, NULL, NULL)) {
10030  /*
10031  * Swap things around between the three-way and real call so we
10032  * can hear where the channel got parked.
10033  */
10034  ast_mutex_lock(&p->lock);
10035  p->owner = p->subs[SUB_THREEWAY].owner;
10037  ast_mutex_unlock(&p->lock);
10038 
10039  ast_verb(3, "%s: Parked call\n", ast_channel_name(chan));
10040  ast_hangup(chan);
10041  ao2_ref(bridge_channel, -1);
10042  goto quit;
10043  }
10044  ao2_ref(bridge_channel, -1);
10045  }
10046  break;
10047  } else if (p->hidecallerid && !strcmp(exten, "*82")) {
10048  ast_verb(3, "Enabling Caller*ID on %s\n", ast_channel_name(chan));
10049  /* Enable Caller*ID if enabled */
10050  p->hidecallerid = 0;
10051  ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
10052  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
10053  if (res) {
10054  ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
10055  ast_channel_name(chan), strerror(errno));
10056  }
10057  len = 0;
10058  memset(exten, 0, sizeof(exten));
10059  timeout = p->firstdigit_timeout;
10060  } else if (!strcmp(exten, "*0")) {
10061  struct ast_channel *nbridge =
10062  p->subs[SUB_THREEWAY].owner;
10063  struct dahdi_pvt *pbridge = NULL;
10064  RAII_VAR(struct ast_channel *, bridged, nbridge ? ast_channel_bridge_peer(nbridge) : NULL, ast_channel_cleanup);
10065 
10066  /* set up the private struct of the bridged one, if any */
10067  if (nbridge && bridged) {
10068  pbridge = ast_channel_tech_pvt(bridged);
10069  }
10070  if (nbridge && pbridge &&
10071  (ast_channel_tech(nbridge) == &dahdi_tech) &&
10072  (ast_channel_tech(bridged) == &dahdi_tech) &&
10073  ISTRUNK(pbridge)) {
10074  int func = DAHDI_FLASH;
10075  /* Clear out the dial buffer */
10076  p->dop.dialstr[0] = '\0';
10077  /* flash hookswitch */
10078  if ((ioctl(pbridge->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
10079  ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
10080  ast_channel_name(nbridge), strerror(errno));
10081  }
10084  p->owner = p->subs[SUB_REAL].owner;
10086  ast_hangup(chan);
10087  goto quit;
10088  } else {
10089  tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
10090  dahdi_wait_event(p->subs[idx].dfd);
10091  tone_zone_play_tone(p->subs[idx].dfd, -1);
10094  p->owner = p->subs[SUB_REAL].owner;
10095  ast_hangup(chan);
10096  goto quit;
10097  }
10098  } else if (!ast_canmatch_extension(chan, ast_channel_context(chan), exten, 1,
10099  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
10100  && !canmatch_featurecode(pickupexten, exten)) {
10101  ast_debug(1, "Can't match %s from '%s' in context %s\n", exten,
10102  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<Unknown Caller>"),
10103  ast_channel_context(chan));
10104  break;
10105  }
10106  if (!timeout)
10107  timeout = p->interdigit_timeout;
10108  if (len && !ast_ignore_pattern(ast_channel_context(chan), exten))
10109  tone_zone_play_tone(p->subs[idx].dfd, -1);
10110  }
10111  break;
10112  case SIG_FXSLS:
10113  case SIG_FXSGS:
10114  case SIG_FXSKS:
10115  /* check for SMDI messages */
10116  if (p->use_smdi && p->smdi_iface) {
10118 
10119  if (smdi_msg != NULL) {
10120  ast_channel_exten_set(chan, smdi_msg->fwd_st);
10121 
10122  if (smdi_msg->type == 'B')
10123  pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
10124  else if (smdi_msg->type == 'N')
10125  pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
10126 
10127  ast_debug(1, "Received SMDI message on %s\n", ast_channel_name(chan));
10128  } else {
10129  ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
10130  }
10131  }
10132 
10133  if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
10134  number = smdi_msg->calling_st;
10135 
10136  /* If we want caller id, we're in a prering state due to a polarity reversal
10137  * and we're set to use a polarity reversal to trigger the start of caller id,
10138  * grab the caller id and wait for ringing to start... */
10139  } else if (p->use_callerid && (ast_channel_state(chan) == AST_STATE_PRERING &&
10141  /* If set to use DTMF CID signalling, listen for DTMF */
10142  if (p->cid_signalling == CID_SIG_DTMF) {
10143  int k = 0;
10144  int off_ms;
10145  struct timeval start = ast_tvnow();
10146  int ms;
10147  cs = NULL;
10148  ast_debug(1, "Receiving DTMF cid on channel %s\n", ast_channel_name(chan));
10149  dahdi_setlinear(p->subs[idx].dfd, 0);
10150  /*
10151  * We are the only party interested in the Rx stream since
10152  * we have not answered yet. We don't need or even want DTMF
10153  * emulation. The DTMF digits can come so fast that emulation
10154  * can drop some of them.
10155  */
10156  ast_channel_lock(chan);
10158  ast_channel_unlock(chan);
10159  off_ms = 4000;/* This is a typical OFF time between rings. */
10160  for (;;) {
10161  struct ast_frame *f;
10162 
10163  ms = ast_remaining_ms(start, off_ms);
10164  res = ast_waitfor(chan, ms);
10165  if (res <= 0) {
10166  /*
10167  * We do not need to restore the dahdi_setlinear()
10168  * or AST_FLAG_END_DTMF_ONLY flag settings since we
10169  * are hanging up the channel.
10170  */
10171  ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
10172  "Exiting simple switch\n");
10173  ast_hangup(chan);
10174  goto quit;
10175  }
10176  f = ast_read(chan);
10177  if (!f)
10178  break;
10179  if (f->frametype == AST_FRAME_DTMF) {
10180  if (k < ARRAY_LEN(dtmfbuf) - 1) {
10181  dtmfbuf[k++] = f->subclass.integer;
10182  }
10183  ast_debug(1, "CID got digit '%c'\n", f->subclass.integer);
10184  start = ast_tvnow();
10185  }
10186  ast_frfree(f);
10187  if (ast_channel_state(chan) == AST_STATE_RING ||
10189  break; /* Got ring */
10190  }
10191  ast_channel_lock(chan);
10193  ast_channel_unlock(chan);
10194  dtmfbuf[k] = '\0';
10195  dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
10196  /* Got cid and ring. */
10197  ast_debug(1, "CID got string '%s'\n", dtmfbuf);
10198  callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
10199  ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags);
10200  /* If first byte is NULL, we have no cid */
10201  if (!ast_strlen_zero(dtmfcid))
10202  number = dtmfcid;
10203  else
10204  number = NULL;
10205  /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
10206  } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
10207  cs = callerid_new(p->cid_signalling);
10208  if (cs) {
10209  int off_ms;
10210  struct timeval start;
10211  int ms;
10212  samples = 0;
10213 #if 1
10214  bump_gains(p);
10215 #endif
10216  /* Take out of linear mode for Caller*ID processing */
10217  dahdi_setlinear(p->subs[idx].dfd, 0);
10218 
10219  /* First we wait and listen for the Caller*ID */
10220  for (;;) {
10221  i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10222  if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
10223  ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
10224  callerid_free(cs);
10225  ast_hangup(chan);
10226  goto quit;
10227  }
10228  if (i & DAHDI_IOMUX_SIGEVENT) {
10229  res = dahdi_get_event(p->subs[idx].dfd);
10230  ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
10231  if (res == DAHDI_EVENT_NOALARM) {
10232  p->inalarm = 0;
10233  }
10234 
10235  if (p->cid_signalling == CID_SIG_V23_JP) {
10236  if (res == DAHDI_EVENT_RINGBEGIN) {
10237  res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
10238  usleep(1);
10239  }
10240  } else {
10241  res = 0;
10242  break;
10243  }
10244  } else if (i & DAHDI_IOMUX_READ) {
10245  res = read(p->subs[idx].dfd, buf, sizeof(buf));
10246  if (res < 0) {
10247  if (errno != ELAST) {
10248  ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
10249  callerid_free(cs);
10250  ast_hangup(chan);
10251  goto quit;
10252  }
10253  break;
10254  }
10255  samples += res;
10256 
10257  if (p->cid_signalling == CID_SIG_V23_JP) {
10258  res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
10259  } else {
10260  res = callerid_feed(cs, buf, res, AST_LAW(p));
10261  }
10262  if (res < 0) {
10263  /*
10264  * The previous diagnostic message output likely
10265  * explains why it failed.
10266  */
10268  "Failed to decode CallerID on channel '%s'\n",
10269  ast_channel_name(chan));
10270  break;
10271  } else if (res)
10272  break;
10273  else if (samples > (8000 * 10))
10274  break;
10275  }
10276  }
10277  if (res == 1) {
10278  callerid_get(cs, &name, &number, &flags);
10279  ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
10280  }
10281 
10282  if (p->cid_signalling == CID_SIG_V23_JP) {
10283  res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
10284  usleep(1);
10285  }
10286 
10287  /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
10288  start = ast_tvnow();
10289  off_ms = 4000;/* This is a typical OFF time between rings. */
10290  for (;;) {
10291  struct ast_frame *f;
10292 
10293  ms = ast_remaining_ms(start, off_ms);
10294  res = ast_waitfor(chan, ms);
10295  if (res <= 0) {
10296  ast_log(LOG_WARNING, "CID timed out waiting for ring. "
10297  "Exiting simple switch\n");
10298  ast_hangup(chan);
10299  goto quit;
10300  }
10301  if (!(f = ast_read(chan))) {
10302  ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n");
10303  ast_hangup(chan);
10304  goto quit;
10305  }
10306  ast_frfree(f);
10307  if (ast_channel_state(chan) == AST_STATE_RING ||
10309  break; /* Got ring */
10310  }
10311 
10312  /* We must have a ring by now, so, if configured, lets try to listen for
10313  * distinctive ringing */
10314  if (p->usedistinctiveringdetection) {
10315  len = 0;
10316  distMatches = 0;
10317  /* Clear the current ring data array so we don't have old data in it. */
10318  for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++)
10319  curRingData[receivedRingT] = 0;
10320  receivedRingT = 0;
10321  counter = 0;
10322  counter1 = 0;
10323  /* Check to see if context is what it should be, if not set to be. */
10324  if (strcmp(p->context,p->defcontext) != 0) {
10325  ast_copy_string(p->context, p->defcontext, sizeof(p->context));
10327  }
10328 
10329  for (;;) {
10330  i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10331  if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
10332  ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
10333  callerid_free(cs);
10334  ast_hangup(chan);
10335  goto quit;
10336  }
10337  if (i & DAHDI_IOMUX_SIGEVENT) {
10338  res = dahdi_get_event(p->subs[idx].dfd);
10339  ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
10340  if (res == DAHDI_EVENT_NOALARM) {
10341  p->inalarm = 0;
10342  }
10343  res = 0;
10344  /* Let us detect distinctive ring */
10345 
10346  curRingData[receivedRingT] = p->ringt;
10347 
10348  if (p->ringt < p->ringt_base/2)
10349  break;
10350  /* Increment the ringT counter so we can match it against
10351  values in chan_dahdi.conf for distinctive ring */
10352  if (++receivedRingT == ARRAY_LEN(curRingData))
10353  break;
10354  } else if (i & DAHDI_IOMUX_READ) {
10355  res = read(p->subs[idx].dfd, buf, sizeof(buf));
10356  if (res < 0) {
10357  if (errno != ELAST) {
10358  ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
10359  callerid_free(cs);
10360  ast_hangup(chan);
10361  goto quit;
10362  }
10363  break;
10364  }
10365  if (p->ringt > 0) {
10366  if (!(--p->ringt)) {
10367  res = -1;
10368  break;
10369  }
10370  }
10371  }
10372  }
10373  /* this only shows up if you have n of the dring patterns filled in */
10374  ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
10375  for (counter = 0; counter < 3; counter++) {
10376  /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
10377  channel */
10378  distMatches = 0;
10379  for (counter1 = 0; counter1 < 3; counter1++) {
10380  ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
10381  if (p->drings.ringnum[counter].ring[counter1] == -1) {
10382  ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
10383  curRingData[counter1]);
10384  distMatches++;
10385  } else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
10386  curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
10387  ast_verb(3, "Ring pattern matched in range: %d to %d\n",
10388  (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
10389  (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
10390  distMatches++;
10391  }
10392  }
10393 
10394  if (distMatches == 3) {
10395  /* The ring matches, set the context to whatever is for distinctive ring.. */
10396  ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context));
10398  ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
10399  break;
10400  }
10401  }
10402  }
10403  /* Restore linear mode (if appropriate) for Caller*ID processing */
10404  dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
10405 #if 1
10406  restore_gains(p);
10407 #endif
10408  } else
10409  ast_log(LOG_WARNING, "Unable to get caller ID space\n");
10410  } else {
10411  ast_log(LOG_WARNING, "Channel %s in prering "
10412  "state, but I have nothing to do. "
10413  "Terminating simple switch, should be "
10414  "restarted by the actual ring.\n",
10415  ast_channel_name(chan));
10416  ast_hangup(chan);
10417  goto quit;
10418  }
10419  } else if (p->use_callerid && p->cid_start == CID_START_RING) {
10420  if (p->cid_signalling == CID_SIG_DTMF) {
10421  int k = 0;
10422  int off_ms;
10423  struct timeval start;
10424  int ms;
10425  cs = NULL;
10426  dahdi_setlinear(p->subs[idx].dfd, 0);
10427  off_ms = 2000;
10428  start = ast_tvnow();
10429  for (;;) {
10430  struct ast_frame *f;
10431 
10432  ms = ast_remaining_ms(start, off_ms);
10433  res = ast_waitfor(chan, ms);
10434  if (res <= 0) {
10435  ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
10436  "Exiting simple switch\n");
10437  ast_hangup(chan);
10438  goto quit;
10439  }
10440  f = ast_read(chan);
10441  if (!f) {
10442  /* Hangup received waiting for DTMFCID. Exiting simple switch. */
10443  ast_hangup(chan);
10444  goto quit;
10445  }
10446  if (f->frametype == AST_FRAME_DTMF) {
10447  dtmfbuf[k++] = f->subclass.integer;
10448  ast_debug(1, "CID got digit '%c'\n", f->subclass.integer);
10449  start = ast_tvnow();
10450  }
10451  ast_frfree(f);
10452 
10453  if (p->ringt_base == p->ringt)
10454  break;
10455  }
10456  dtmfbuf[k] = '\0';
10457  dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
10458  /* Got cid and ring. */
10459  callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
10460  ast_debug(1, "CID is '%s', flags %d\n",
10461  dtmfcid, flags);
10462  /* If first byte is NULL, we have no cid */
10463  if (!ast_strlen_zero(dtmfcid))
10464  number = dtmfcid;
10465  else
10466  number = NULL;
10467  /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
10468  } else {
10469  /* FSK Bell202 callerID */
10470  cs = callerid_new(p->cid_signalling);
10471  if (cs) {
10472 #if 1
10473  bump_gains(p);
10474 #endif
10475  samples = 0;
10476  len = 0;
10477  distMatches = 0;
10478  /* Clear the current ring data array so we don't have old data in it. */
10479  for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++)
10480  curRingData[receivedRingT] = 0;
10481  receivedRingT = 0;
10482  counter = 0;
10483  counter1 = 0;
10484  /* Check to see if context is what it should be, if not set to be. */
10485  if (strcmp(p->context,p->defcontext) != 0) {
10486  ast_copy_string(p->context, p->defcontext, sizeof(p->context));
10488  }
10489 
10490  /* Take out of linear mode for Caller*ID processing */
10491  dahdi_setlinear(p->subs[idx].dfd, 0);
10492  for (;;) {
10493  i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10494  if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
10495  ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
10496  callerid_free(cs);
10497  ast_hangup(chan);
10498  goto quit;
10499  }
10500  if (i & DAHDI_IOMUX_SIGEVENT) {
10501  res = dahdi_get_event(p->subs[idx].dfd);
10502  ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
10503  if (res == DAHDI_EVENT_NOALARM) {
10504  p->inalarm = 0;
10505  }
10506  /* If we get a PR event, they hung up while processing calerid */
10507  if ( res == DAHDI_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
10508  ast_debug(1, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
10509  p->polarity = POLARITY_IDLE;
10510  callerid_free(cs);
10511  ast_hangup(chan);
10512  goto quit;
10513  }
10514  res = 0;
10515  /* Let us detect callerid when the telco uses distinctive ring */
10516 
10517  curRingData[receivedRingT] = p->ringt;
10518 
10519  if (p->ringt < p->ringt_base/2)
10520  break;
10521  /* Increment the ringT counter so we can match it against
10522  values in chan_dahdi.conf for distinctive ring */
10523  if (++receivedRingT == ARRAY_LEN(curRingData))
10524  break;
10525  } else if (i & DAHDI_IOMUX_READ) {
10526  res = read(p->subs[idx].dfd, buf, sizeof(buf));
10527  if (res < 0) {
10528  if (errno != ELAST) {
10529  ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
10530  callerid_free(cs);
10531  ast_hangup(chan);
10532  goto quit;
10533  }
10534  break;
10535  }
10536  if (p->ringt > 0) {
10537  if (!(--p->ringt)) {
10538  res = -1;
10539  break;
10540  }
10541  }
10542  samples += res;
10543  res = callerid_feed(cs, buf, res, AST_LAW(p));
10544  if (res < 0) {
10545  /*
10546  * The previous diagnostic message output likely
10547  * explains why it failed.
10548  */
10550  "Failed to decode CallerID on channel '%s'\n",
10551  ast_channel_name(chan));
10552  break;
10553  } else if (res)
10554  break;
10555  else if (samples > (8000 * 10))
10556  break;
10557  }
10558  }
10559  if (res == 1) {
10560  callerid_get(cs, &name, &number, &flags);
10561  ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
10562  }
10563  if (distinctiveringaftercid == 1) {
10564  /* Clear the current ring data array so we don't have old data in it. */
10565  for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
10566  curRingData[receivedRingT] = 0;
10567  }
10568  receivedRingT = 0;
10569  ast_verb(3, "Detecting post-CID distinctive ring\n");
10570  for (;;) {
10571  i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10572  if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
10573  ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
10574  callerid_free(cs);
10575  ast_hangup(chan);
10576  goto quit;
10577  }
10578  if (i & DAHDI_IOMUX_SIGEVENT) {
10579  res = dahdi_get_event(p->subs[idx].dfd);
10580  ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
10581  if (res == DAHDI_EVENT_NOALARM) {
10582  p->inalarm = 0;
10583  }
10584  res = 0;
10585  /* Let us detect callerid when the telco uses distinctive ring */
10586 
10587  curRingData[receivedRingT] = p->ringt;
10588 
10589  if (p->ringt < p->ringt_base/2)
10590  break;
10591  /* Increment the ringT counter so we can match it against
10592  values in chan_dahdi.conf for distinctive ring */
10593  if (++receivedRingT == ARRAY_LEN(curRingData))
10594  break;
10595  } else if (i & DAHDI_IOMUX_READ) {
10596  res = read(p->subs[idx].dfd, buf, sizeof(buf));
10597  if (res < 0) {
10598  if (errno != ELAST) {
10599  ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
10600  callerid_free(cs);
10601  ast_hangup(chan);
10602  goto quit;
10603  }
10604  break;
10605  }
10606  if (p->ringt > 0) {
10607  if (!(--p->ringt)) {
10608  res = -1;
10609  break;
10610  }
10611  }
10612  }
10613  }
10614  }
10615  if (p->usedistinctiveringdetection) {
10616  /* this only shows up if you have n of the dring patterns filled in */
10617  ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
10618 
10619  for (counter = 0; counter < 3; counter++) {
10620  /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
10621  channel */
10622  /* this only shows up if you have n of the dring patterns filled in */
10623  ast_verb(3, "Checking %d,%d,%d\n",
10624  p->drings.ringnum[counter].ring[0],
10625  p->drings.ringnum[counter].ring[1],
10626  p->drings.ringnum[counter].ring[2]);
10627  distMatches = 0;
10628  for (counter1 = 0; counter1 < 3; counter1++) {
10629  ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
10630  if (p->drings.ringnum[counter].ring[counter1] == -1) {
10631  ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
10632  curRingData[counter1]);
10633  distMatches++;
10634  }
10635  else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
10636  curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
10637  ast_verb(3, "Ring pattern matched in range: %d to %d\n",
10638  (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
10639  (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
10640  distMatches++;
10641  }
10642  }
10643  if (distMatches == 3) {
10644  /* The ring matches, set the context to whatever is for distinctive ring.. */
10645  ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context));
10647  ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
10648  break;
10649  }
10650  }
10651  }
10652  /* Restore linear mode (if appropriate) for Caller*ID processing */
10653  dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
10654 #if 1
10655  restore_gains(p);
10656 #endif
10657  if (res < 0) {
10658  ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", ast_channel_name(chan));
10659  }
10660  } else
10661  ast_log(LOG_WARNING, "Unable to get caller ID space\n");
10662  }
10663  } else
10664  cs = NULL;
10665 
10666  if (number)
10667  ast_shrink_phone_number(number);
10668  ast_set_callerid(chan, number, name, number);
10669 
10670  ao2_cleanup(smdi_msg);
10671 
10672  if (cs)
10673  callerid_free(cs);
10674 
10675  my_handle_notify_message(chan, p, flags, -1);
10676 
10677  ast_channel_lock(chan);
10679  ast_channel_rings_set(chan, 1);
10680  ast_channel_unlock(chan);
10681  p->ringt = p->ringt_base;
10682  res = ast_pbx_run(chan);
10683  if (res) {
10684  ast_hangup(chan);
10685  ast_log(LOG_WARNING, "PBX exited non-zero\n");
10686  }
10687  goto quit;
10688  default:
10689  ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
10690  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
10691  if (res < 0)
10692  ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
10693  }
10694  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
10695  if (res < 0)
10696  ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
10697  ast_hangup(chan);
10698 quit:
10700  ss_thread_count--;
10703  return NULL;
10704 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
char defcontext[AST_MAX_CONTEXT]
Default distinctive ring context.
Definition: chan_dahdi.h:453
static void swap_subs(struct dahdi_pvt *p, int a, int b)
Definition: chan_dahdi.c:4058
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
struct ringContextData ringContext[3]
Definition: chan_dahdi.h:71
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
int matchdigit_timeout
Time (ms) to wait, in case of ambiguous match (in an analog phone)
Definition: chan_dahdi.h:635
int dtmfrelax
Definition: chan_dahdi.h:665
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:7434
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:4199
#define ast_channel_lock(chan)
Definition: channel.h:2945
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
struct dahdi_dialoperation dop
DAHDI dial operation command struct for ioctl() call.
Definition: chan_dahdi.h:641
char fwd_st[SMDI_MAX_STATION_NUM_LEN+1]
Definition: smdi.h:69
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
unsigned int cancallforward
TRUE if support for call forwarding enabled. Dial *72 to enable call forwarding. Dial *73 to disable ...
Definition: chan_dahdi.h:214
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:202
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
#define POLARITY_IDLE
Definition: chan_dahdi.c:792
int firstdigit_timeout
Time (ms) to detect first digit (in an analog phone)
Definition: chan_dahdi.h:625
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define SIG_FXOGS
Definition: chan_dahdi.h:735
#define SIG_SF_FEATDMF
Definition: chan_dahdi.h:740
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static ast_mutex_t ss_thread_lock
Definition: chan_dahdi.c:642
int cid_signalling
Definition: chan_dahdi.h:541
unsigned int hardwaredtmf
TRUE if DTMF detection needs to be done by hardware.
Definition: chan_dahdi.h:263
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
int interdigit_timeout
Time (ms) to detect following digits (in an analog phone)
Definition: chan_dahdi.h:630
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void dahdi_ec_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4638
int cid_start
Definition: chan_dahdi.h:542
static struct ast_channel_tech dahdi_tech
Definition: chan_dahdi.c:1030
#define CID_SIG_SMDI
Definition: callerid.h:63
int ringt
Ring timeout timer??
Definition: chan_dahdi.h:556
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
#define DSP_DIGITMODE_MF
Definition: dsp.h:32
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define SUB_THREEWAY
Definition: chan_dahdi.h:59
char calling_st[SMDI_MAX_STATION_NUM_LEN+1]
Definition: smdi.h:70
#define LOG_WARNING
Definition: logger.h:274
char * name
Definition: chan_dahdi.c:4361
#define SIG_EM
Definition: chan_dahdi.h:722
struct ast_channel * owner
Definition: chan_dahdi.h:127
static int timeout
Definition: cdr_mysql.c:86
static ast_cond_t ss_thread_complete
Definition: chan_dahdi.c:641
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4302
void ast_dsp_digitreset(struct ast_dsp *dsp)
Reset DTMF detector.
Definition: dsp.c:1797
#define CID_START_POLARITY
Definition: callerid.h:66
unsigned int immediate
TRUE if the channel should be answered immediately without attempting to gather any digits...
Definition: chan_dahdi.h:284
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition: pbx.c:6921
#define SIG_FXOKS
Definition: chan_dahdi.h:736
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define SIG_FEATB
Definition: chan_dahdi.h:726
static int dahdi_wink(struct dahdi_pvt *p, int index)
Definition: chan_dahdi.c:9419
static int unalloc_sub(struct dahdi_pvt *p, int x)
Definition: chan_dahdi.c:4204
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
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define SIG_FEATDMF_TA
Definition: chan_dahdi.h:728
#define ast_mutex_lock(a)
Definition: lock.h:187
static int alloc_sub(struct dahdi_pvt *p, int x)
Definition: chan_dahdi.c:4167
#define CID_START_POLARITY_IN
Definition: callerid.h:67
#define NULL
Definition: resample.c:96
const char * data
#define AST_FRAME_DTMF
int ringt_base
Ring timeout base.
Definition: chan_dahdi.h:561
#define ast_cond_signal(cond)
Definition: lock.h:201
#define ast_verb(level,...)
Definition: logger.h:463
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
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:4194
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:188
struct ast_frame_subclass subclass
#define SIG_SF
Definition: chan_dahdi.h:737
#define ast_strlen_zero(foo)
Definition: strings.h:52
char cid_name[AST_MAX_EXTENSION]
Caller ID name from an incoming call.
Definition: chan_dahdi.h:488
Number structure.
Definition: app_followme.c:154
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:306
#define SIG_EMWINK
Definition: chan_dahdi.h:723
static int dahdi_wait_event(int fd)
Avoid the silly dahdi_waitevent which ignores a bunch of events.
Definition: chan_dahdi.c:661
#define NEED_MFDETECT(p)
Signaling types that need to use MF detection should be placed in this macro.
Definition: chan_dahdi.c:525
#define SIG_FGC_CAMAMF
Definition: chan_dahdi.h:730
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int polarity
Current line interface polarity. POLARITY_IDLE, POLARITY_REV.
Definition: chan_dahdi.h:681
unsigned int hanguponpolarityswitch
TRUE if the call will be considered "hung up" on a polarity reversal.
Definition: chan_dahdi.h:261
unsigned int callreturn
TRUE if call return is enabled. (*69, if your dialplan doesn&#39;t catch this first)
Definition: chan_dahdi.h:195
#define ISTRUNK(p)
Definition: chan_dahdi.c:590
unsigned int transfer
TRUE if call transfer is enabled.
Definition: chan_dahdi.h:339
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:9466
void ast_channel_rings_set(struct ast_channel *chan, int value)
#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:911
static int ss_thread_count
Definition: chan_dahdi.c:644
#define SIG_FEATD
Definition: chan_dahdi.h:724
#define AST_MAX_EXTENSION
Definition: channel.h:135
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
Definition: channel.c:1644
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ao2_ref(o, delta)
Definition: astobj2.h:464
ast_mutex_t lock
Definition: chan_dahdi.h:125
#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:85
char contextData[AST_MAX_CONTEXT]
Definition: chan_dahdi.h:67
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ring[3]
Definition: chan_dahdi.h:63
struct ast_channel * owner
Definition: chan_dahdi.h:79
#define AST_LAW(p)
Definition: chan_dahdi.c:521
static int restore_gains(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4909
unsigned int linear
Definition: chan_dahdi.h:90
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:4179
#define SMDI_MD_WAIT_TIMEOUT
Definition: chan_dahdi.c:482
An SMDI message desk message.
Definition: smdi.h:65
void ast_party_number_free(struct ast_party_number *doomed)
Destroy the party number contents.
Definition: channel.c:1691
static int bump_gains(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4895
unsigned int use_smdi
TRUE if SMDI (Simplified Message Desk Interface) is enabled.
Definition: chan_dahdi.h:432
#define SIG_E911
Definition: chan_dahdi.h:727
#define CID_SIG_V23_JP
Definition: callerid.h:62
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
#define LOG_ERROR
Definition: logger.h:285
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition: pickup.c:200
char cid_num[AST_MAX_EXTENSION]
Caller ID number from an incoming call.
Definition: chan_dahdi.h:479
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_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: main/utils.c:2033
#define POLARITY_REV
Definition: chan_dahdi.c:793
void ast_party_name_init(struct ast_party_name *init)
Initialize the given name structure.
Definition: channel.c:1591
unsigned int use_callerid
TRUE if caller ID is used on this channel.
Definition: chan_dahdi.h:347
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define CID_SIG_DTMF
Definition: callerid.h:61
static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent)
Definition: chan_dahdi.c:3307
void ast_party_name_free(struct ast_party_name *doomed)
Destroy the party name contents.
Definition: channel.c:1638
#define SIG_FXSGS
Definition: chan_dahdi.h:732
#define LOG_NOTICE
Definition: logger.h:263
int ast_parking_provider_registered(void)
Check whether a parking provider is registered.
Definition: parking.c:241
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define SIG_SF_FEATD
Definition: chan_dahdi.h:739
unsigned int usedistinctiveringdetection
TRUE if distinctive rings are to be detected.
Definition: chan_dahdi.h:360
char call_forward[AST_MAX_EXTENSION]
Accumulated call forwarding number.
Definition: chan_dahdi.h:649
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922
static int dahdi_get_event(int fd)
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition: chan_dahdi.c:652
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
char context[AST_MAX_CONTEXT]
The configured context for incoming calls.
Definition: chan_dahdi.h:444
static const char * event2str(int event)
Definition: chan_dahdi.c:4382
#define SIG_SFWINK
Definition: chan_dahdi.h:738
struct ast_smdi_interface * smdi_iface
The SMDI interface to get SMDI messages from.
Definition: chan_dahdi.h:435
#define SIG_FGC_CAMA
Definition: chan_dahdi.h:729
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define SIG_SF_FEATB
Definition: chan_dahdi.h:741
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel&#39;s bridge pointer.
Definition: channel.c:10783
#define SIG_FXSKS
Definition: chan_dahdi.h:733
#define CID_START_RING
Definition: callerid.h:65
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
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...
static int dahdi_setlinear(int dfd, int linear)
Definition: chan_dahdi.c:4161
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3184
void callerid_free(struct callerid_state *cid)
This function frees callerid_state cid.
Definition: callerid.c:734
static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
Definition: chan_dahdi.c:9400
Structure that contains information regarding a channel in a bridge.
char * strsep(char **str, const char *delims)
static int distinctiveringaftercid
Definition: chan_dahdi.c:608
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3171
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_channel_context_set(struct ast_channel *chan, const char *value)
struct dahdi_distRings drings
Distinctive Ring data.
Definition: chan_dahdi.h:438
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: channel.c:10765
const char * ast_channel_name(const struct ast_channel *chan)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
#define ast_frfree(fr)
#define SIG_FXSLS
Definition: chan_dahdi.h:731
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:4759
Data structure associated with a single frame of data.
const char * ast_channel_language(const struct ast_channel *chan)
unsigned int hidecallerid
TRUE if the outgoing caller ID is blocked/hidden.
Definition: chan_dahdi.h:270
const char * ast_channel_context(const struct ast_channel *chan)
enum ast_frame_type frametype
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
#define SIG_FXOLS
Definition: chan_dahdi.h:734
#define sig2str
Definition: chan_dahdi.c:4455
void callerid_get_dtmf(char *cidstring, char *number, int *flags)
Get and parse DTMF-based callerid.
Definition: callerid.c:201
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:947
struct callerid_state * callerid_new(int cid_signalling)
Create a callerID state machine.
Definition: callerid.c:129
#define CID_START_DTMF_NOALERT
Definition: callerid.h:68
#define SIG_FEATDMF
Definition: chan_dahdi.h:725
static int canmatch_featurecode(const char *pickupexten, const char *exten)
Definition: chan_dahdi.c:9485
unsigned int inalarm
TRUE if in an alarm condition.
Definition: chan_dahdi.h:286
int channel
Definition: chan_dahdi.h:538
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
unsigned int canpark
TRUE if support for call parking is enabled.
Definition: chan_dahdi.h:219
#define SIG_EM_E1
Definition: chan_dahdi.h:742
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1844
struct distRingData ringnum[3]
Definition: chan_dahdi.h:70
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:545
#define ast_mutex_unlock(a)
Definition: lock.h:188
Configuration relating to call pickup.
#define CID_SIG_V23
Definition: callerid.h:60
#define SUB_CALLWAIT
Definition: chan_dahdi.h:58

◆ analog_tone_to_dahditone()

static int analog_tone_to_dahditone ( enum analog_tone  tone)
static

Definition at line 1106 of file chan_dahdi.c.

References ANALOG_TONE_CONGESTION, ANALOG_TONE_DIALRECALL, ANALOG_TONE_DIALTONE, ANALOG_TONE_INFO, ANALOG_TONE_RINGTONE, and ANALOG_TONE_STUTTER.

Referenced by my_play_tone().

1107 {
1108  switch (tone) {
1109  case ANALOG_TONE_RINGTONE:
1110  return DAHDI_TONE_RINGTONE;
1111  case ANALOG_TONE_STUTTER:
1112  return DAHDI_TONE_STUTTER;
1114  return DAHDI_TONE_CONGESTION;
1115  case ANALOG_TONE_DIALTONE:
1116  return DAHDI_TONE_DIALTONE;
1118  return DAHDI_TONE_DIALRECALL;
1119  case ANALOG_TONE_INFO:
1120  return DAHDI_TONE_INFO;
1121  default:
1122  return -1;
1123  }
1124 }

◆ analogsub_to_dahdisub()

static int analogsub_to_dahdisub ( enum analog_sub  analogsub)
static

Definition at line 1126 of file chan_dahdi.c.

References ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY, ast_log, LOG_ERROR, SUB_CALLWAIT, SUB_REAL, and SUB_THREEWAY.

Referenced by my_allocate_sub(), my_conf_add(), my_conf_del(), my_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().

1127 {
1128  int index;
1129 
1130  switch (analogsub) {
1131  case ANALOG_SUB_REAL:
1132  index = SUB_REAL;
1133  break;
1134  case ANALOG_SUB_CALLWAIT:
1135  index = SUB_CALLWAIT;
1136  break;
1137  case ANALOG_SUB_THREEWAY:
1138  index = SUB_THREEWAY;
1139  break;
1140  default:
1141  ast_log(LOG_ERROR, "Unidentified sub!\n");
1142  index = SUB_REAL;
1143  }
1144 
1145  return index;
1146 }
#define SUB_THREEWAY
Definition: chan_dahdi.h:59
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SUB_CALLWAIT
Definition: chan_dahdi.h:58

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 19922 of file chan_dahdi.c.

◆ attempt_transfer()

static int attempt_transfer ( struct dahdi_pvt p)
static

Definition at line 7145 of file chan_dahdi.c.

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

7146 {
7147  struct ast_channel *owner_real;
7148  struct ast_channel *owner_3way;
7149  enum ast_transfer_result xfer_res;
7150  int res = 0;
7151 
7152  owner_real = ast_channel_ref(p->subs[SUB_REAL].owner);
7153  owner_3way = ast_channel_ref(p->subs[SUB_THREEWAY].owner);
7154 
7155  ast_verb(3, "TRANSFERRING %s to %s\n",
7156  ast_channel_name(owner_3way), ast_channel_name(owner_real));
7157 
7158  ast_channel_unlock(owner_real);
7159  ast_channel_unlock(owner_3way);
7160  ast_mutex_unlock(&p->lock);
7161 
7162  xfer_res = ast_bridge_transfer_attended(owner_3way, owner_real);
7163  if (xfer_res != AST_BRIDGE_TRANSFER_SUCCESS) {
7164  ast_softhangup(owner_3way, AST_SOFTHANGUP_DEV);
7165  res = -1;
7166  }
7167 
7168  /* Must leave with these locked. */
7169  ast_channel_lock(owner_real);
7170  ast_mutex_lock(&p->lock);
7171 
7172  ast_channel_unref(owner_real);
7173  ast_channel_unref(owner_3way);
7174 
7175  return res;
7176 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
Definition: bridge.c:4729
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define SUB_THREEWAY
Definition: chan_dahdi.h:59
#define ast_mutex_lock(a)
Definition: lock.h:187
ast_transfer_result
Definition: bridge.h:1115
#define ast_verb(level,...)
Definition: logger.h:463
ast_mutex_t lock
Definition: chan_dahdi.h:125
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
struct ast_channel * owner
Definition: chan_dahdi.h:79
#define SUB_REAL
Definition: chan_dahdi.h:57
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ available()

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

Definition at line 13058 of file chan_dahdi.c.

References analog_available(), ARRAY_LEN, ast_calloc, ast_cc_config_params_init, ast_copy_string(), ast_free, ast_log, ast_mutex_init, dahdi_pvt::buf_no, dahdi_pvt::buf_policy, dahdi_pvt::bufsize, dahdi_pvt::cc_params, CHAN_PSEUDO, sig_pri_chan::chan_pvt, sig_pri_chan::channel, dahdi_pvt::channel, dahdi_pvt::context, dahdi_analog_lib_handles(), dahdi_open(), destroy_dahdi_pvt(), dahdi_subchannel::dfd, errno, dahdi_pvt::faxbuf_no, dahdi_pvt::faxbuf_policy, dahdi_pvt::hidecallerid, dahdi_pvt::hidecalleridname, dahdi_pvt::immediate, dahdi_pvt::inalarm, dahdi_pvt::law_default, dahdi_pvt::locallyblocked, dahdi_pvt::lock, LOG_ERROR, LOG_WARNING, dahdi_pvt::mohinterpret, sig_pri_chan::no_b_channel, NULL, sig_pri_span::numchans, dahdi_pvt::oprmode, dahdi_pvt::outsigmod, dahdi_pvt::owner, dahdi_pvt::priexclusive, dahdi_pvt::priindication_oob, sig_pri_span::pvts, dahdi_pvt::radio, dahdi_pvt::remotelyblocked, dahdi_pvt::sig, sig_pri_span::sig, sig_pri_available(), sig_pri_chan_new(), SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, sig_ss7_available(), dahdi_pvt::span, sig_pri_span::span, dahdi_pvt::stripmsd, SUB_REAL, dahdi_pvt::subs, dahdi_pvt::use_callerid, and dahdi_pvt::use_callingpres.

Referenced by __ast_string_field_ptr_build_va(), ast_logger_register_level(), dahdi_request(), is_member_available(), and logger_register_level().

13059 {
13060  struct dahdi_pvt *p = *pvt;
13061 
13062  if (p->inalarm)
13063  return 0;
13064 
13065  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode))
13066  return analog_available(p->sig_pvt);
13067 
13068  switch (p->sig) {
13069 #if defined(HAVE_PRI)
13071  {
13072  struct sig_pri_chan *pvt_chan;
13073  int res;
13074 
13075  pvt_chan = p->sig_pvt;
13076  res = sig_pri_available(&pvt_chan, is_specific_channel);
13077  *pvt = pvt_chan->chan_pvt;
13078  return res;
13079  }
13080 #endif /* defined(HAVE_PRI) */
13081 #if defined(HAVE_SS7)
13082  case SIG_SS7:
13083  return sig_ss7_available(p->sig_pvt);
13084 #endif /* defined(HAVE_SS7) */
13085  default:
13086  break;
13087  }
13088 
13089  if (p->locallyblocked || p->remotelyblocked) {
13090  return 0;
13091  }
13092 
13093  /* If no owner definitely available */
13094  if (!p->owner) {
13095 #ifdef HAVE_OPENR2
13096  /* Trust MFC/R2 */
13097  if (p->mfcr2) {
13098  if (p->mfcr2call) {
13099  return 0;
13100  } else {
13101  return 1;
13102  }
13103  }
13104 #endif
13105  return 1;
13106  }
13107 
13108  return 0;
13109 }
int sig_pri_available(struct sig_pri_chan **pvt, int is_specific_channel)
int sig_ss7_available(struct sig_ss7_chan *p)
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
unsigned int locallyblocked
Bitmask for the channel being locally blocked.
Definition: chan_dahdi.h:404
struct ast_channel * owner
Definition: chan_dahdi.h:127
void * sig_pvt
Definition: chan_dahdi.h:709
void * chan_pvt
Definition: sig_pri.h:376
int oprmode
Definition: chan_dahdi.h:150
int analog_available(struct analog_pvt *p)
Definition: sig_analog.c:795
#define SIG_SS7
Definition: chan_dahdi.h:750
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
unsigned int remotelyblocked
Bitmask for the channel being remotely blocked. 1 maintenance, 2 blocked in hardware.
Definition: chan_dahdi.h:413
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
unsigned int inalarm
TRUE if in an alarm condition.
Definition: chan_dahdi.h:286

◆ build_channels()

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

Definition at line 17667 of file chan_dahdi.c.

References ast_log, ast_strdupa, ast_verb, c, dahdi_chan_conf::chan, CHAN_PSEUDO, has_pseudo, dahdi_chan_conf::is_sig_auto, LOG_ERROR, LOG_WARNING, mkintf(), dahdi_pvt::sig, sig2str, strsep(), tmp(), dahdi_chan_conf::wanted_channels_end, and dahdi_chan_conf::wanted_channels_start.

Referenced by process_dahdi().

17668 {
17669  char *c, *chan;
17670  int x, start, finish;
17671  struct dahdi_pvt *tmp;
17672 
17673  if ((reload == 0) && (conf->chan.sig < 0) && !conf->is_sig_auto) {
17674  ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
17675  return -1;
17676  }
17677 
17678  c = ast_strdupa(value);
17679 
17680  while ((chan = strsep(&c, ","))) {
17681  if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
17682  /* Range */
17683  } else if (sscanf(chan, "%30d", &start)) {
17684  /* Just one */
17685  finish = start;
17686  } else if (!strcasecmp(chan, "pseudo")) {
17687  finish = start = CHAN_PSEUDO;
17688  } else {
17689  ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
17690  return -1;
17691  }
17692  if (finish < start) {
17693  ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
17694  x = finish;
17695  finish = start;
17696  start = x;
17697  }
17698 
17699  for (x = start; x <= finish; x++) {
17700  if (conf->wanted_channels_start &&
17701  (x < conf->wanted_channels_start ||
17702  x > conf->wanted_channels_end)
17703  ) {
17704  continue;
17705  }
17706  tmp = mkintf(x, conf, reload);
17707 
17708  if (tmp) {
17709  ast_verb(3, "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
17710  } else {
17711  ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
17712  (reload == 1) ? "reconfigure" : "register", value);
17713  return -1;
17714  }
17715  if (x == CHAN_PSEUDO) {
17716  has_pseudo = 1;
17717  }
17718  }
17719  }
17720 
17721  return 0;
17722 }
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
#define CHAN_PSEUDO
Definition: chan_dahdi.c:556
static struct test_val c
int value
Definition: syslog.c:37
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static int reload(void)
Definition: chan_dahdi.c:19898
#define LOG_ERROR
Definition: logger.h:285
static int has_pseudo
Definition: chan_dahdi.c:567
int wanted_channels_start
Don&#39;t create channels below this number.
Definition: chan_dahdi.c:859
int wanted_channels_end
Don&#39;t create channels above this number (infinity by default)
Definition: chan_dahdi.c:865
char * strsep(char **str, const char *delims)
struct dahdi_pvt chan
Definition: chan_dahdi.c:832
static struct dahdi_pvt * mkintf(int channel, const struct dahdi_chan_conf *conf, int reloading)
Definition: chan_dahdi.c:12095
#define sig2str
Definition: chan_dahdi.c:4455

◆ bump_gains()

static int bump_gains ( struct dahdi_pvt p)
static

Definition at line 4895 of file chan_dahdi.c.

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

Referenced by analog_ss_thread(), dahdi_dial_str(), mwi_thread(), and my_start_cid_detect().

4896 {
4897  int res;
4898 
4899  /* Bump receive gain by value stored in cid_rxgain */
4900  res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain + p->cid_rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
4901  if (res) {
4902  ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
4903  return -1;
4904  }
4905 
4906  return 0;
4907 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
float txdrc
Definition: chan_dahdi.h:163
float cid_rxgain
Amount of gain to increase during caller id.
Definition: chan_dahdi.h:157
int law
Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:509
float txgain
Software Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:161
#define ast_log
Definition: astobj2.c:42
float rxdrc
Definition: chan_dahdi.h:164
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law)
Definition: chan_dahdi.c:4890
float rxgain
Software Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:159

◆ calc_energy()

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

Definition at line 10712 of file chan_dahdi.c.

References abs, AST_ALAW, ast_format_ulaw, AST_MULAW, and len().

Referenced by do_monitor(), and mwi_thread().

10713 {
10714  int x;
10715  int sum = 0;
10716 
10717  if (!len)
10718  return 0;
10719 
10720  for (x = 0; x < len; x++)
10721  sum += abs(law == ast_format_ulaw ? AST_MULAW(buf[x]) : AST_ALAW(buf[x]));
10722 
10723  return sum / len;
10724 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
#define AST_ALAW(a)
Definition: alaw.h:84
#define AST_MULAW(a)
Definition: ulaw.h:85
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define abs(x)
Definition: f2c.h:195

◆ canmatch_featurecode()

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

Definition at line 9485 of file chan_dahdi.c.

Referenced by analog_ss_thread().

9486 {
9487  int extlen = strlen(exten);
9488 
9489  if (!extlen) {
9490  return 1;
9491  }
9492 
9493  if (extlen < strlen(pickupexten) && !strncmp(pickupexten, exten, extlen)) {
9494  return 1;
9495  }
9496  /* hardcoded features are *60, *67, *69, *70, *72, *73, *78, *79, *82, *0 */
9497  if (exten[0] == '*' && extlen < 3) {
9498  if (extlen == 1) {
9499  return 1;
9500  }
9501  /* "*0" should be processed before it gets here */
9502  switch (exten[1]) {
9503  case '6':
9504  case '7':
9505  case '8':
9506  return 1;
9507  }
9508  }
9509  return 0;
9510 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118

◆ check_for_conference()

static int check_for_conference ( struct dahdi_pvt p)
static

Definition at line 7178 of file chan_dahdi.c.

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

Referenced by dahdi_handle_event(), my_check_for_conference(), and my_complete_conference_update().

7179 {
7180  struct dahdi_confinfo ci;
7181  /* Fine if we already have a master, etc */
7182  if (p->master || (p->confno > -1))
7183  return 0;
7184  memset(&ci, 0, sizeof(ci));
7185  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
7186  ast_log(LOG_WARNING, "Failed to get conference info on channel %d: %s\n", p->channel, strerror(errno));
7187  return 0;
7188  }
7189  /* If we have no master and don't have a confno, then
7190  if we're in a conference, it's probably a MeetMe room or
7191  some such, so don't let us 3-way out! */
7192  if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
7193  ast_verb(3, "Avoiding 3-way call when in an external conference\n");
7194  return 1;
7195  }
7196  return 0;
7197 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct dahdi_pvt * master
Definition: chan_dahdi.h:135
#define LOG_WARNING
Definition: logger.h:274
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
int confno
Definition: chan_dahdi.h:510
int channel
Definition: chan_dahdi.h:538
struct dahdi_confinfo curconf
Definition: chan_dahdi.h:92

◆ conf_add()

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

Definition at line 4457 of file chan_dahdi.c.

References ast_debug, ast_log, dahdi_pvt::confno, dahdi_subchannel::curconf, dahdi_subchannel::dfd, errno, and LOG_WARNING.

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

4458 {
4459  /* If the conference already exists, and we're already in it
4460  don't bother doing anything */
4461  struct dahdi_confinfo zi;
4462 
4463  memset(&zi, 0, sizeof(zi));
4464  zi.chan = 0;
4465 
4466  if (slavechannel > 0) {
4467  /* If we have only one slave, do a digital mon */
4468  zi.confmode = DAHDI_CONF_DIGITALMON;
4469  zi.confno = slavechannel;
4470  } else {
4471  if (!idx) {
4472  /* Real-side and pseudo-side both participate in conference */
4473  zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |
4474  DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;
4475  } else
4476  zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
4477  zi.confno = p->confno;
4478  }
4479  if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
4480  return 0;
4481  if (c->dfd < 0)
4482  return 0;
4483  if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
4484  ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno));
4485  return -1;
4486  }
4487  if (slavechannel < 1) {
4488  p->confno = zi.confno;
4489  }
4490  c->curconf = zi;
4491  ast_debug(1, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
4492  return 0;
4493 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int errno
int confno
Definition: chan_dahdi.h:510
struct dahdi_confinfo curconf
Definition: chan_dahdi.h:92

◆ conf_del()

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

Definition at line 4506 of file chan_dahdi.c.

References ast_debug, ast_log, dahdi_subchannel::curconf, dahdi_subchannel::dfd, errno, isourconf(), and LOG_WARNING.

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

4507 {
4508  struct dahdi_confinfo zi;
4509  if (/* Can't delete if there's no dfd */
4510  (c->dfd < 0) ||
4511  /* Don't delete from the conference if it's not our conference */
4512  !isourconf(p, c)
4513  /* Don't delete if we don't think it's conferenced at all (implied) */
4514  ) return 0;
4515  memset(&zi, 0, sizeof(zi));
4516  if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
4517  ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno));
4518  return -1;
4519  }
4520  ast_debug(1, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
4521  memcpy(&c->curconf, &zi, sizeof(c->curconf));
4522  return 0;
4523 }
#define LOG_WARNING
Definition: logger.h:274
static int isourconf(struct dahdi_pvt *p, struct dahdi_subchannel *c)
Definition: chan_dahdi.c:4495
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int errno
struct dahdi_confinfo curconf
Definition: chan_dahdi.h:92

◆ create_channel_name()

static struct ast_str* create_channel_name ( struct dahdi_pvt i)
static

Definition at line 9099 of file chan_dahdi.c.

References ast_channel_name(), ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_strlen_zero, CHAN_PSEUDO, dahdi_pvt::channel, dahdi_pvt::cid_num, dahdi_pvt::cid_subaddr, dahdi_pvt::lock, NULL, dahdi_subchannel::owner, dahdi_pvt::span, and dahdi_pvt::subs.

Referenced by dahdi_cc_callback(), dahdi_indicate(), and dahdi_new().

9101 {
9102  struct ast_str *chan_name;
9103  int x, y;
9104 
9105  /* Create the new channel name tail. */
9106  if (!(chan_name = ast_str_create(32))) {
9107  return NULL;
9108  }
9109  if (i->channel == CHAN_PSEUDO) {
9110  ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random());
9111 #if defined(HAVE_PRI)
9112  } else if (i->pri) {
9113  ast_mutex_lock(&i->pri->lock);
9114  y = ++i->pri->new_chan_seq;
9115  if (is_outgoing) {
9116  ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, address, (unsigned)y);
9117  address[0] = '\0';
9118  } else if (ast_strlen_zero(i->cid_subaddr)) {
9119  /* Put in caller-id number only since there is no subaddress. */
9120  ast_str_set(&chan_name, 0, "i%d/%s-%x", i->pri->span, i->cid_num, (unsigned)y);
9121  } else {
9122  /* Put in caller-id number and subaddress. */
9123  ast_str_set(&chan_name, 0, "i%d/%s:%s-%x", i->pri->span, i->cid_num,
9124  i->cid_subaddr, (unsigned)y);
9125  }
9126  ast_mutex_unlock(&i->pri->lock);
9127 #endif /* defined(HAVE_PRI) */
9128  } else {
9129  y = 1;
9130  do {
9131  ast_str_set(&chan_name, 0, "%d-%d", i->channel, y);
9132  for (x = 0; x < 3; ++x) {
9133  if (i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name),
9134  ast_channel_name(i->subs[x].owner) + 6)) {
9135  break;
9136  }
9137  }
9138  ++y;
9139  } while (x < 3);
9140  }
9141  return chan_name;
9142 }
char cid_subaddr[AST_MAX_EXTENSION]
Caller ID subaddress from an incoming call.
Definition: chan_dahdi.h:490
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
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:714
#define CHAN_PSEUDO
Definition: chan_dahdi.c:556
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:1065
ast_mutex_t lock
Definition: chan_dahdi.h:125
long int ast_random(void)
Definition: main/utils.c:2064
struct ast_channel * owner
Definition: chan_dahdi.h:79
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
char cid_num[AST_MAX_EXTENSION]
Caller ID number from an incoming call.
Definition: chan_dahdi.h:479
const char * ast_channel_name(const struct ast_channel *chan)
int channel
Definition: chan_dahdi.h:538
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_ami_channel_event()

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

Definition at line 1801 of file chan_dahdi.c.

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

Referenced by dahdi_new().

1802 {
1803  char ch_name[23];
1804 
1805  if (p->channel < CHAN_PSEUDO) {
1806  /* No B channel */
1807  snprintf(ch_name, sizeof(ch_name), "no-media (%d)", p->channel);
1808  } else if (p->channel == CHAN_PSEUDO) {
1809  /* Pseudo channel */
1810  strcpy(ch_name, "pseudo");
1811  } else {
1812  /* Real channel */
1813  snprintf(ch_name, sizeof(ch_name), "%d", p->channel);
1814  }
1815  publish_dahdichannel(chan, p->group, p->span, ch_name);
1816 }
#define CHAN_PSEUDO
Definition: chan_dahdi.c:556
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:1772
ast_group_t group
Bitmapped groups this belongs to.
Definition: chan_dahdi.h:505
int channel
Definition: chan_dahdi.h:538

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

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.

Referenced by dahdi_chan_conf_default().

6410 {
6411  struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
6412  int res = 0;
6413  int idx;
6414  ast_setstate(ast, AST_STATE_UP);/*! \todo XXX this is redundantly set by the analog and PRI submodules! */
6415  ast_mutex_lock(&p->lock);
6416  idx = dahdi_get_index(ast, p, 0);
6417  if (idx < 0)
6418  idx = SUB_REAL;
6419  /* nothing to do if a radio channel */
6420  if ((p->radio || (p->oprmode < 0))) {
6421  ast_mutex_unlock(&p->lock);
6422  return 0;
6423  }
6424 
6425  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
6426  res = analog_answer(p->sig_pvt, ast);
6427  ast_mutex_unlock(&p->lock);
6428  return res;
6429  }
6430 
6431  switch (p->sig) {
6432 #if defined(HAVE_PRI)
6434  res = sig_pri_answer(p->sig_pvt, ast);
6435  break;
6436 #endif /* defined(HAVE_PRI) */
6437 #if defined(HAVE_SS7)
6438  case SIG_SS7:
6439  res = sig_ss7_answer(p->sig_pvt, ast);
6440  break;
6441 #endif /* defined(HAVE_SS7) */
6442 #ifdef HAVE_OPENR2
6443  case SIG_MFCR2:
6444  if (!p->mfcr2_call_accepted) {
6445  /* The call was not accepted on offer nor the user, so it must be accepted now before answering,
6446  openr2_chan_answer_call will be called when the callback on_call_accepted is executed */
6447  p->mfcr2_answer_pending = 1;
6448  if (p->mfcr2_charge_calls) {
6449  ast_debug(1, "Accepting MFC/R2 call with charge before answering on chan %d\n", p->channel);
6450  openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE);
6451  } else {
6452  ast_debug(1, "Accepting MFC/R2 call with no charge before answering on chan %d\n", p->channel);
6453  openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE);
6454  }
6455  } else {
6456  ast_debug(1, "Answering MFC/R2 call on chan %d\n", p->channel);
6457  dahdi_r2_answer(p);
6458  }
6459  break;
6460 #endif
6461  case 0:
6462  ast_mutex_unlock(&p->lock);
6463  return 0;
6464  default:
6465  ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
6466  res = -1;
6467  break;
6468  }
6469  ast_mutex_unlock(&p->lock);
6470  return res;
6471 }
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
#define LOG_WARNING
Definition: logger.h:274
void * sig_pvt
Definition: chan_dahdi.h:709
#define ast_mutex_lock(a)
Definition: lock.h:187
int oprmode
Definition: chan_dahdi.h:150
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
ast_mutex_t lock
Definition: chan_dahdi.h:125
#define SIG_SS7
Definition: chan_dahdi.h:750
int analog_answer(struct analog_pvt *p, struct ast_channel *ast)
Definition: sig_analog.c:1461
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
#define SIG_MFCR2
Definition: chan_dahdi.h:753
int sig_pri_answer(struct sig_pri_chan *p, struct ast_channel *ast)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
int sig_ss7_answer(struct sig_ss7_chan *p, struct ast_channel *ast)
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_call()

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

Definition at line 5121 of file chan_dahdi.c.

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.

Referenced by dahdi_chan_conf_default().

5122 {
5123  struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
5124  int x, res, mysig;
5125  char *dest;
5127  AST_APP_ARG(group); /* channel/group token */
5128  AST_APP_ARG(ext); /* extension token */
5129  //AST_APP_ARG(opts); /* options token */
5130  AST_APP_ARG(other); /* Any remining unused arguments */
5131  );
5132 
5133  ast_mutex_lock(&p->lock);
5134  ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
5135 
5136  /* Split the dialstring */
5137  dest = ast_strdupa(rdest);
5138  AST_NONSTANDARD_APP_ARGS(args, dest, '/');
5139  if (!args.ext) {
5140  args.ext = "";
5141  }
5142 
5143 #if defined(HAVE_PRI)
5144  if (dahdi_sig_pri_lib_handles(p->sig)) {
5145  char *subaddr;
5146 
5147  sig_pri_extract_called_num_subaddr(p->sig_pvt, rdest, p->exten, sizeof(p->exten));
5148 
5149  /* Remove any subaddress for uniformity with incoming calls. */
5150  subaddr = strchr(p->exten, ':');
5151  if (subaddr) {
5152  *subaddr = '\0';
5153  }
5154  } else
5155 #endif /* defined(HAVE_PRI) */
5156  {
5157  ast_copy_string(p->exten, args.ext, sizeof(p->exten));
5158  }
5159 
5160  if ((ast_channel_state(ast) == AST_STATE_BUSY)) {
5161  p->subs[SUB_REAL].needbusy = 1;
5162  ast_mutex_unlock(&p->lock);
5163  return 0;
5164  }
5166  ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
5167  ast_mutex_unlock(&p->lock);
5168  return -1;
5169  }
5170  p->waitingfordt.tv_sec = 0;
5171  p->dialednone = 0;
5172  if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */
5173  {
5174  /* Special pseudo -- automatically up */
5175  ast_setstate(ast, AST_STATE_UP);
5176  ast_mutex_unlock(&p->lock);
5177  return 0;
5178  }
5179  x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;
5180  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
5181  if (res)
5182  ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno));
5183  p->outgoing = 1;
5184 
5186  set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, p->rxdrc, p->txdrc, p->law);
5187  } else {
5188  set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
5189  }
5190 
5191 #ifdef HAVE_PRI
5192  if (dahdi_sig_pri_lib_handles(p->sig)) {
5193  res = sig_pri_call(p->sig_pvt, ast, rdest, timeout,
5194  (p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW);
5195  ast_mutex_unlock(&p->lock);
5196  return res;
5197  }
5198 #endif
5199 
5200 #if defined(HAVE_SS7)
5201  if (p->sig == SIG_SS7) {
5202  res = sig_ss7_call(p->sig_pvt, ast, rdest);
5203  ast_mutex_unlock(&p->lock);
5204  return res;
5205  }
5206 #endif /* defined(HAVE_SS7) */
5207 
5208  /* If this is analog signalling we can exit here */
5209  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
5210  p->callwaitrings = 0;
5211  res = analog_call(p->sig_pvt, ast, rdest, timeout);
5212  ast_mutex_unlock(&p->lock);
5213  return res;
5214  }
5215 
5216  mysig = p->outsigmod > -1 ? p->outsigmod : p->sig;
5217  switch (mysig) {
5218  case 0:
5219  /* Special pseudo -- automatically up*/
5220  ast_setstate(ast, AST_STATE_UP);
5221  break;
5222  case SIG_MFCR2:
5223  break;
5224  default:
5225  ast_debug(1, "not yet implemented\n");
5226  ast_mutex_unlock(&p->lock);
5227  return -1;
5228  }
5229 
5230 #ifdef HAVE_OPENR2
5231  if (p->mfcr2) {
5232  openr2_calling_party_category_t chancat;
5233  int callres = 0;
5234  char *c, *l;
5235 
5236  /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
5237  p->dialdest[0] = '\0';
5238 
5239  c = args.ext;
5240  if (!p->hidecallerid) {
5242  } else {
5243  l = NULL;
5244  }
5245  if (strlen(c) < p->stripmsd) {
5246  ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
5247  ast_mutex_unlock(&p->lock);
5248  return -1;
5249  }
5250  p->dialing = 1;
5251  chancat = dahdi_r2_get_channel_category(ast);
5252  callres = openr2_chan_make_call(p->r2chan, l, (c + p->stripmsd), chancat);
5253  if (-1 == callres) {
5254  ast_mutex_unlock(&p->lock);
5255  ast_log(LOG_ERROR, "unable to make new MFC/R2 call!\n");
5256  return -1;
5257  }
5258  p->mfcr2_call_accepted = 0;
5259  p->mfcr2_progress_sent = 0;
5261  }
5262 #endif /* HAVE_OPENR2 */
5263  ast_mutex_unlock(&p->lock);
5264  return 0;
5265 }
unsigned int outgoing
TRUE if we originated the call leg.
Definition: chan_dahdi.h:290
int outsigmod
Definition: chan_dahdi.h:149
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
#define IS_DIGITAL(cap)
Definition: transcap.h:43
unsigned int dialing
TRUE if in the process of dialing digits or sending something.
Definition: chan_dahdi.h:234
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
int callwaitrings
Number of call waiting rings.
Definition: chan_dahdi.h:577
struct ast_party_id id
Connected party ID.
Definition: channel.h:459
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
#define LOG_WARNING
Definition: logger.h:274
float txdrc
Definition: chan_dahdi.h:163
static int timeout
Definition: cdr_mysql.c:86
ast_channel_state
ast_channel states
Definition: channelstate.h:35
void * sig_pvt
Definition: chan_dahdi.h:709
#define ast_mutex_lock(a)
Definition: lock.h:187
static struct test_val c
const char * args
int law
Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:509
#define NULL
Definition: resample.c:96
const char * ext
Definition: http.c:147
float txgain
Software Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:161
void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size)
int oprmode
Definition: chan_dahdi.h:150
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
ast_mutex_t lock
Definition: chan_dahdi.h:125
float rxdrc
Definition: chan_dahdi.h:164
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define SIG_SS7
Definition: chan_dahdi.h:750
struct timeval waitingfordt
Definition: chan_dahdi.h:636
#define LOG_ERROR
Definition: logger.h:285
int sig_ss7_call(struct sig_ss7_chan *p, struct ast_channel *ast, const char *rdest)
int analog_call(struct analog_pvt *p, struct ast_channel *ast, const char *rdest, int timeout)
Definition: sig_analog.c:987
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
char exten[AST_MAX_EXTENSION]
Extension to use in the dialplan.
Definition: chan_dahdi.h:455
int stripmsd
Number of most significant digits/characters to strip from the dialed number.
Definition: chan_dahdi.h:568
#define SIG_MFCR2
Definition: chan_dahdi.h:753
int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, const char *rdest, int timeout, int layer1)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
unsigned int needbusy
Definition: chan_dahdi.h:84
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
unsigned int dialednone
TRUE if analog type line dialed no digits in Dial()
Definition: chan_dahdi.h:229
static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law)
Definition: chan_dahdi.c:4890
unsigned int hidecallerid
TRUE if the outgoing caller ID is blocked/hidden.
Definition: chan_dahdi.h:270
float rxgain
Software Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:159
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
int channel
Definition: chan_dahdi.h:538
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
char dialdest[256]
Delayed dialing for E911. Overlap digits for ISDN.
Definition: chan_dahdi.h:658
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define AST_APP_ARG(name)
Define an application argument.
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ dahdi_callwait()

static int dahdi_callwait ( struct ast_channel ast)
static

Definition at line 5087 of file chan_dahdi.c.

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

5088 {
5089  struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
5090 
5092  if (p->cidspill) {
5093  ast_log(LOG_WARNING, "Spill already exists?!?\n");
5094  ast_free(p->cidspill);
5095  }
5096 
5097  /*
5098  * SAS: Subscriber Alert Signal, 440Hz for 300ms
5099  * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
5100  */
5101  if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
5102  return -1;
5103  save_conference(p);
5104  /* Silence */
5105  memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
5106  if (!p->callwaitrings && p->callwaitingcallerid) {
5107  ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
5108  p->callwaitcas = 1;
5109  p->cidlen = 2400 + 680 + READ_SIZE * 4;
5110  } else {
5111  ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
5112  p->callwaitcas = 0;
5113  p->cidlen = 2400 + READ_SIZE * 4;
5114  }
5115  p->cidpos = 0;
5116  send_callerid(p);
5117 
5118  return 0;
5119 }
int cidpos
Position in the cidspill buffer to send out next.
Definition: chan_dahdi.h:552
int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: chan_dahdi.h:575
int callwaitrings
Number of call waiting rings.
Definition: chan_dahdi.h:577
void * ast_channel_tech_pvt(const struct ast_channel *chan)
unsigned int callwaitingcallerid
TRUE if send caller ID for Call Waiting.
Definition: chan_dahdi.h:207
#define LOG_WARNING
Definition: logger.h:274
int callwaitingrepeat
Definition: chan_dahdi.h:546
#define ast_log
Definition: astobj2.c:42
int cidlen
Length of the cidspill buffer containing samples.
Definition: chan_dahdi.h:554
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
#define AST_LAW(p)
Definition: chan_dahdi.c:521
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define READ_SIZE
Definition: chan_dahdi.c:673
#define ast_free(a)
Definition: astmm.h:182
static int send_callerid(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5051
#define CALLWAITING_REPEAT_SAMPLES
Definition: chan_dahdi.c:679
static int save_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4976
int ast_gen_cas(unsigned char *outbuf, int sas, int len, struct ast_format *codec)
Generate a CAS (CPE Alert Signal) tone for &#39;n&#39; samples.
Definition: callerid.c:261

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

References a, ast_cli_args::argc, ast_cli_args::argv, ast_asprintf, 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_cli(), AST_CLI_DEFINE, ast_copy_string(), ast_db_del(), ast_db_put(), ast_debug, AST_FILE_MODE, ast_free, ast_get_cc_monitor_policy(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_MOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log, ast_log_callid(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, ast_str_buffer(), ast_strdupa, ast_strlen_zero, ast_true(), ast_verbose_callid, astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), dahdi_starting_point::backwards, dahdi_pvt::cc_params, sig_pri_chan::channel, dahdi_pvt::channel, dahdi_starting_point::channelmatch, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, container_of, dahdi_pvt::context, create_channel_name(), dahdi_destroy_channel_range(), dahdi_sig_pri_lib_handles(), sig_pri_span::dchans, debug, determine_starting_point(), dahdi_subchannel::dfd, errno, ast_cli_args::fd, FORMAT, dahdi_pvt::group, dahdi_starting_point::groupmatch, ifend, iflist, iflock, is_group_or_channel_match(), len(), ast_cli_args::line, dahdi_pvt::locallyblocked, dahdi_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sig_pri_span::master, ast_cli_args::n, dahdi_pvt::next, NULL, NUM_SPANS, sig_pri_span::numchans, dahdi_pvt::owner, ast_cli_args::pos, dahdi_pvt::prev, sig_pri_span::pri, pri_event_alarm(), pri_event_noalarm(), sig_pri_span::pvts, dahdi_pvt::sig, SIG_MFCR2, sig_pri_cli_show_channels(), sig_pri_cli_show_channels_header(), sig_pri_cli_show_span(), sig_pri_cli_show_spans(), SIG_PRI_DEBUG_NORMAL, sig_pri_init_pri(), SIG_PRI_NUM_DCHANS, dahdi_pvt::sig_pvt, dahdi_pvt::span, sig_pri_span::span, dahdi_starting_point::span, SUB_REAL, dahdi_pvt::subs, tmp(), ast_cli_entry::usage, and ast_cli_args::word.

Referenced by dahdi_chan_conf_default().

13730 {
13731  struct dahdi_pvt *p;
13732  struct dahdi_pvt *exitpvt;
13733  struct dahdi_starting_point start;
13734  int groupmatched = 0;
13735  int channelmatched = 0;
13736 
13738  p = determine_starting_point(dest, &start);
13739  if (!p) {
13741  return -1;
13742  }
13743  exitpvt = p;
13744  for (;;) {
13745  if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)) {
13746  /* We found a potential match. call the callback */
13747  struct ast_str *device_name;
13748  char *dash;
13749  const char *monitor_type;
13750  char dialstring[AST_CHANNEL_NAME];
13751  char full_device_name[AST_CHANNEL_NAME];
13752 
13753  switch (ast_get_cc_monitor_policy(p->cc_params)) {
13754  case AST_CC_MONITOR_NEVER:
13755  break;
13756  case AST_CC_MONITOR_NATIVE:
13757  case AST_CC_MONITOR_ALWAYS:
13759 #if defined(HAVE_PRI)
13760  if (dahdi_sig_pri_lib_handles(p->sig)) {
13761  /*
13762  * ISDN is in a trunk busy condition so we need to monitor
13763  * the span congestion device state.
13764  */
13765  snprintf(full_device_name, sizeof(full_device_name),
13766  "DAHDI/I%d/congestion", p->pri->span);
13767  } else
13768 #endif /* defined(HAVE_PRI) */
13769  {
13770 #if defined(HAVE_PRI)
13771  device_name = create_channel_name(p, 1, "");
13772 #else
13773  device_name = create_channel_name(p);
13774 #endif /* defined(HAVE_PRI) */
13775  snprintf(full_device_name, sizeof(full_device_name), "DAHDI/%s",
13776  device_name ? ast_str_buffer(device_name) : "");
13777  ast_free(device_name);
13778  /*
13779  * The portion after the '-' in the channel name is either a random
13780  * number, a sequence number, or a subchannel number. None are
13781  * necessary so strip them off.
13782  */
13783  dash = strrchr(full_device_name, '-');
13784  if (dash) {
13785  *dash = '\0';
13786  }
13787  }
13788  snprintf(dialstring, sizeof(dialstring), "DAHDI/%s", dest);
13789 
13790  /*
13791  * Analog can only do generic monitoring.
13792  * ISDN is in a trunk busy condition and any "device" is going
13793  * to be busy until a B channel becomes available. The generic
13794  * monitor can do this task.
13795  */
13796  monitor_type = AST_CC_GENERIC_MONITOR_TYPE;
13797  callback(inbound,
13798 #if defined(HAVE_PRI)
13799  p->pri ? p->pri->cc_params : p->cc_params,
13800 #else
13801  p->cc_params,
13802 #endif /* defined(HAVE_PRI) */
13803  monitor_type, full_device_name, dialstring, NULL);
13804  break;
13805  }
13806  }
13807  p = start.backwards ? p->prev : p->next;
13808  if (!p) {
13809  p = start.backwards ? ifend : iflist;
13810  }
13811  if (p == exitpvt) {
13812  break;
13813  }
13814  }
13816  return 0;
13817 }
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
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:13025
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static struct dahdi_pvt * determine_starting_point(const char *data, struct dahdi_starting_point *param)
Definition: chan_dahdi.c:13330
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct dahdi_pvt * ifend
Definition: chan_dahdi.c:802
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
Definition: ccss.c:883
struct ast_cc_config_params * cc_params
Definition: chan_dahdi.h:710
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
#define AST_CC_GENERIC_MONITOR_TYPE
Definition: ccss.h:489
struct dahdi_pvt * prev
Definition: chan_dahdi.h:169
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
#define AST_CHANNEL_NAME
Definition: channel.h:172
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
static struct ast_str * create_channel_name(struct dahdi_pvt *i)
Definition: chan_dahdi.c:9099
#define ast_mutex_unlock(a)
Definition: lock.h:188

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

References ANALOG_FIRST_DIGIT_TIMEOUT, ANALOG_INTER_DIGIT_TIMEOUT, ANALOG_MATCH_DIGIT_TIMEOUT, ast_cc_config_params_init, buf, c, CID_SIG_BELL, CID_START_RING, dahdi_answer(), dahdi_call(), dahdi_cc_callback(), DAHDI_CHAN_MAPPING_PHYSICAL, dahdi_devicestate(), dahdi_digit_begin(), dahdi_digit_end(), dahdi_exception(), dahdi_fixup(), dahdi_func_read(), dahdi_func_write(), dahdi_hangup(), dahdi_indicate(), dahdi_queryoption(), dahdi_read(), dahdi_request(), dahdi_sendtext(), dahdi_setoption(), dahdi_write(), ast_channel::data, ast_frame::data, ast_frame::datalen, DEFAULT_CIDRINGS, digit, len(), numbufs, SIG_PRI_COLP_UPDATE, text, timeout, type, and value.

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

870 {
871  /* recall that if a field is not included here it is initialized
872  * to 0 or equivalent
873  */
874  struct dahdi_chan_conf conf = {
875 #ifdef HAVE_PRI
876  .pri.pri = {
877  .nsf = PRI_NSF_NONE,
878  .switchtype = PRI_SWITCH_NI2,
879  .dialplan = PRI_UNKNOWN + 1,
880  .localdialplan = PRI_NATIONAL_ISDN + 1,
881  .nodetype = PRI_CPE,
882  .qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL,
883 
884 #if defined(HAVE_PRI_CCSS)
885  .cc_ptmp_recall_mode = 1,/* specificRecall */
886  .cc_qsig_signaling_link_req = 1,/* retain */
887  .cc_qsig_signaling_link_rsp = 1,/* retain */
888 #endif /* defined(HAVE_PRI_CCSS) */
889 
890  .minunused = 2,
891  .idleext = "",
892  .idledial = "",
893  .internationalprefix = "",
894  .nationalprefix = "",
895  .localprefix = "",
896  .privateprefix = "",
897  .unknownprefix = "",
898  .colp_send = SIG_PRI_COLP_UPDATE,
899  .resetinterval = -1,
900  },
901 #endif
902 #if defined(HAVE_SS7)
903  .ss7.ss7 = {
904  .called_nai = SS7_NAI_NATIONAL,
905  .calling_nai = SS7_NAI_NATIONAL,
906  .internationalprefix = "",
907  .nationalprefix = "",
908  .subscriberprefix = "",
909  .unknownprefix = "",
910  .networkroutedprefix = ""
911  },
912 #endif /* defined(HAVE_SS7) */
913 #ifdef HAVE_OPENR2
914  .mfcr2 = {
915  .variant = OR2_VAR_ITU,
916  .mfback_timeout = -1,
917  .metering_pulse_timeout = -1,
918  .max_ani = 10,
919  .max_dnis = 4,
920  .get_ani_first = -1,
921 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
922  .skip_category_request = -1,
923 #endif
924  .call_files = 0,
925  .allow_collect_calls = 0,
926  .charge_calls = 1,
927  .accept_on_offer = 1,
928  .forced_release = 0,
929  .double_answer = 0,
930  .immediate_accept = -1,
931 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
932  .dtmf_dialing = -1,
933  .dtmf_detection = -1,
934  .dtmf_time_on = OR2_DEFAULT_DTMF_ON,
935  .dtmf_time_off = OR2_DEFAULT_DTMF_OFF,
936 #endif
937 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
938  .dtmf_end_timeout = -1,
939 #endif
940  .logdir = "",
941  .r2proto_file = "",
942  .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
943  .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
944  },
945 #endif
946  .chan = {
947  .context = "default",
948  .cid_num = "",
949  .cid_name = "",
950  .cid_tag = "",
951  .mohinterpret = "default",
952  .mohsuggest = "",
953  .parkinglot = "",
954  .transfertobusy = 1,
955 
956  .cid_signalling = CID_SIG_BELL,
957  .cid_start = CID_START_RING,
958  .dahditrcallerid = 0,
959  .use_callerid = 1,
960  .sig = -1,
961  .outsigmod = -1,
962 
963  .cid_rxgain = +5.0,
964 
965  .tonezone = -1,
966 
967  .echocancel.head.tap_length = 1,
968 
969  .busycount = 3,
970 
971  .accountcode = "",
972 
973  .mailbox = "",
974 
975 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
976  .mwisend_fsk = 1,
977 #endif
978  .polarityonanswerdelay = 600,
979 
980  .sendcalleridafter = DEFAULT_CIDRINGS,
981 
982  .buf_policy = DAHDI_POLICY_IMMEDIATE,
983  .buf_no = numbufs,
984  .usefaxbuffers = 0,
985  .cc_params = ast_cc_config_params_init(),
986  .firstdigit_timeout = ANALOG_FIRST_DIGIT_TIMEOUT,
987  .interdigit_timeout = ANALOG_INTER_DIGIT_TIMEOUT,
988  .matchdigit_timeout = ANALOG_MATCH_DIGIT_TIMEOUT,
989  },
990  .timing = {
991  .prewinktime = -1,
992  .preflashtime = -1,
993  .winktime = -1,
994  .flashtime = -1,
995  .starttime = -1,
996  .rxwinktime = -1,
997  .rxflashtime = -1,
998  .debouncetime = -1
999  },
1000  .is_sig_auto = 1,
1001  .ignore_failed_channels = 1,
1002  .smdi_port = "/dev/ttyS0",
1003  };
1004 
1005  return conf;
1006 }
#define ANALOG_MATCH_DIGIT_TIMEOUT
Default time (ms) to wait, in case of ambiguous match.
Definition: sig_analog.h:42
#define CID_SIG_BELL
Definition: callerid.h:59
#define ast_cc_config_params_init()
Allocate and initialize an ast_cc_config_params structure.
Definition: ccss.h:135
All configuration options for statsd client.
Definition: res_statsd.c:95
#define DAHDI_CHAN_MAPPING_PHYSICAL
Definition: sig_pri.h:249
static int numbufs
Definition: chan_dahdi.c:610
#define DEFAULT_CIDRINGS
Typically, how many rings before we should send Caller*ID.
Definition: chan_dahdi.c:519
Channel configuration from chan_dahdi.conf . This struct is used for parsing the [channels] section o...
Definition: chan_dahdi.c:831
#define CID_START_RING
Definition: callerid.h:65
#define ANALOG_FIRST_DIGIT_TIMEOUT
Default time (ms) to detect first digit.
Definition: sig_analog.h:38
#define ANALOG_INTER_DIGIT_TIMEOUT
Default time (ms) to detect following digits.
Definition: sig_analog.h:40

◆ dahdi_close()

static void dahdi_close ( int  fd)
static

Definition at line 4133 of file chan_dahdi.c.

Referenced by dahdi_close_sub().

4134 {
4135  if (fd > 0)
4136  close(fd);
4137 }

◆ dahdi_close_sub()

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

Definition at line 4139 of file chan_dahdi.c.

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

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

4140 {
4141  dahdi_close(chan_pvt->subs[sub_num].dfd);
4142  chan_pvt->subs[sub_num].dfd = -1;
4143 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static void dahdi_close(int fd)
Definition: chan_dahdi.c:4133

◆ dahdi_conf_update()

void dahdi_conf_update ( struct dahdi_pvt p)

Definition at line 4583 of file chan_dahdi.c.

References ast_debug, dahdi_pvt::channel, conf_add(), conf_del(), dahdi_pvt::confno, dahdi_subchannel::dfd, GET_CHANNEL, dahdi_pvt::inconference, dahdi_subchannel::inthreeway, isslavenative(), dahdi_pvt::master, MAX_SLAVES, 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().

4584 {
4585  int needconf = 0;
4586  int x;
4587  int useslavenative;
4588  struct dahdi_pvt *slave = NULL;
4589 
4590  useslavenative = isslavenative(p, &slave);
4591  /* Start with the obvious, general stuff */
4592  for (x = 0; x < 3; x++) {
4593  /* Look for three way calls */
4594  if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) {
4595  conf_add(p, &p->subs[x], x, 0);
4596  needconf++;
4597  } else {
4598  conf_del(p, &p->subs[x], x);
4599  }
4600  }
4601  /* If we have a slave, add him to our conference now. or DAX
4602  if this is slave native */
4603  for (x = 0; x < MAX_SLAVES; x++) {
4604  if (p->slaves[x]) {
4605  if (useslavenative)
4606  conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
4607  else {
4608  conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
4609  needconf++;
4610  }
4611  }
4612  }
4613  /* If we're supposed to be in there, do so now */
4614  if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
4615  if (useslavenative)
4616  conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
4617  else {
4618  conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
4619  needconf++;
4620  }
4621  }
4622  /* If we have a master, add ourselves to his conference */
4623  if (p->master) {
4624  if (isslavenative(p->master, NULL)) {
4626  } else {
4627  conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
4628  }
4629  }
4630  if (!needconf) {
4631  /* Nobody is left (or should be left) in our conference.
4632  Kill it. */
4633  p->confno = -1;
4634  }
4635  ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
4636 }
static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index)
Definition: chan_dahdi.c:4506
#define MAX_SLAVES
Definition: chan_dahdi.h:95
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct dahdi_pvt * master
Definition: chan_dahdi.h:135
static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel)
Definition: chan_dahdi.c:4457
#define NULL
Definition: resample.c:96
int inconference
Definition: chan_dahdi.h:136
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct dahdi_pvt * slaves[MAX_SLAVES]
Definition: chan_dahdi.h:134
#define GET_CHANNEL(p)
Definition: chan_dahdi.c:1053
unsigned int inthreeway
Definition: chan_dahdi.h:91
#define SUB_REAL
Definition: chan_dahdi.h:57
int confno
Definition: chan_dahdi.h:510
static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out)
Definition: chan_dahdi.c:4525
int channel
Definition: chan_dahdi.h:538

◆ dahdi_confmute()

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

Definition at line 4939 of file chan_dahdi.c.

References ast_log, dahdi_pvt::channel, dahdi_subchannel::dfd, errno, LOG_WARNING, muted, 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(), my_handle_dtmf(), and my_wink().

4940 {
4941  int x, res;
4942 
4943  x = muted;
4944 #if defined(HAVE_PRI) || defined(HAVE_SS7)
4945  switch (p->sig) {
4946 #if defined(HAVE_PRI)
4948  if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
4949  /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */
4950  break;
4951  }
4952  /* Fall through */
4953 #endif /* defined(HAVE_PRI) */
4954 #if defined(HAVE_SS7)
4955  case SIG_SS7:
4956 #endif /* defined(HAVE_SS7) */
4957  {
4958  int y = 1;
4959 
4960  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y);
4961  if (res)
4962  ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n",
4963  p->channel, strerror(errno));
4964  }
4965  break;
4966  default:
4967  break;
4968  }
4969 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
4970  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x);
4971  if (res < 0)
4972  ast_log(LOG_WARNING, "DAHDI confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
4973  return res;
4974 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
static int muted
Definition: muted.c:82
void * sig_pvt
Definition: chan_dahdi.h:709
#define ast_log
Definition: astobj2.c:42
#define SIG_SS7
Definition: chan_dahdi.h:750
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
int channel
Definition: chan_dahdi.h:538

◆ dahdi_create_channel_range()

static int dahdi_create_channel_range ( int  start,
int  end 
)
static

Definition at line 11150 of file chan_dahdi.c.

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

11151 {
11152  struct dahdi_pvt *cur;
11153  struct dahdi_chan_conf default_conf = dahdi_chan_conf_default();
11154  struct dahdi_chan_conf base_conf = dahdi_chan_conf_default();
11156  int ret = RESULT_FAILURE; /* be pessimistic */
11157 
11158  ast_debug(1, "channel range caps: %d - %d\n", start, end);
11160  for (cur = iflist; cur; cur = cur->next) {
11161  if (cur->channel >= start && cur->channel <= end) {
11163  "channel range %d-%d is occupied\n",
11164  start, end);
11165  goto out;
11166  }
11167  }
11168 #ifdef HAVE_PRI
11169  {
11170  int i, x;
11171  for (x = 0; x < NUM_SPANS; x++) {
11172  struct dahdi_pri *pri = pris + x;
11173 
11174  if (!pris[x].pri.pvts[0]) {
11175  break;
11176  }
11177  for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
11178  int channo = pri->dchannels[i];
11179 
11180  if (!channo) {
11181  break;
11182  }
11183  if (!pri->pri.fds[i]) {
11184  break;
11185  }
11186  if (channo >= start && channo <= end) {
11188  "channel range %d-%d is occupied by span %d\n",
11189  start, end, x + 1);
11190  goto out;
11191  }
11192  }
11193  }
11194  }
11195 #endif
11196  if (!default_conf.chan.cc_params || !base_conf.chan.cc_params ||
11197  !conf.chan.cc_params) {
11198  goto out;
11199  }
11200  default_conf.wanted_channels_start = start;
11201  base_conf.wanted_channels_start = start;
11202  conf.wanted_channels_start = start;
11203  default_conf.wanted_channels_end = end;
11204  base_conf.wanted_channels_end = end;
11205  conf.wanted_channels_end = end;
11206  if (setup_dahdi_int(0, &default_conf, &base_conf, &conf) == 0) {
11207  ret = RESULT_SUCCESS;
11208  }
11209 out:
11214  return ret;
11215 }
void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
Free memory from CCSS configuration params.
Definition: ccss.c:693
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
static struct dahdi_chan_conf dahdi_chan_conf_default(void)
Definition: chan_dahdi.c:869
#define ast_mutex_lock(a)
Definition: lock.h:187
char * end
Definition: eagi_proxy.c:73
All configuration options for statsd client.
Definition: res_statsd.c:95
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct ast_cc_config_params * cc_params
Definition: chan_dahdi.h:710
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
#define LOG_ERROR
Definition: logger.h:285
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:241
Channel configuration from chan_dahdi.conf . This struct is used for parsing the [channels] section o...
Definition: chan_dahdi.c:831
int wanted_channels_start
Don&#39;t create channels below this number.
Definition: chan_dahdi.c:859
int wanted_channels_end
Don&#39;t create channels above this number (infinity by default)
Definition: chan_dahdi.c:865
FILE * out
Definition: utils/frame.c:33
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
struct dahdi_pvt chan
Definition: chan_dahdi.c:832
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:19348
#define NUM_SPANS
Definition: chan_dahdi.c:553
#define RESULT_SUCCESS
Definition: cli.h:40
int channel
Definition: chan_dahdi.h:538
#define RESULT_FAILURE
Definition: cli.h:42
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_create_channels()

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

Definition at line 15347 of file chan_dahdi.c.

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

15348 {
15349  int start;
15350  int end;
15351  int ret;
15352 
15353  switch (cmd) {
15354  case CLI_INIT:
15355  e->command = "dahdi create channels";
15356  e->usage = "Usage: dahdi create channels <from> [<to>] - a range of channels\n"
15357  " dahdi create channels new - add channels not yet created\n"
15358  "For ISDN and SS7 the range should include complete spans.\n";
15359  return NULL;
15360  case CLI_GENERATE:
15361  return NULL;
15362  }
15363  if ((a->argc < 4) || a->argc > 5) {
15364  return CLI_SHOWUSAGE;
15365  }
15366  if (a->argc == 4 && !strcmp(a->argv[3], "new")) {
15367  ret = dahdi_create_channel_range(0, 0);
15368  return (RESULT_SUCCESS == ret) ? CLI_SUCCESS : CLI_FAILURE;
15369  }
15370  start = atoi(a->argv[3]);
15371  if (start <= 0) {
15372  ast_cli(a->fd, "Invalid starting channel number '%s'.\n",
15373  a->argv[3]);
15374  return CLI_FAILURE;
15375  }
15376  if (a->argc == 5) {
15377  end = atoi(a->argv[4]);
15378  if (end <= 0) {
15379  ast_cli(a->fd, "Invalid ending channel number '%s'.\n",
15380  a->argv[4]);
15381  return CLI_FAILURE;
15382  }
15383  } else {
15384  end = start;
15385  }
15386  if (end < start) {
15387  ast_cli(a->fd,
15388  "range end (%d) is smaller than range start (%d)\n",
15389  end, start);
15390  return CLI_FAILURE;
15391  }
15392  ret = dahdi_create_channel_range(start, end);
15393  return (RESULT_SUCCESS == ret) ? CLI_SUCCESS : CLI_FAILURE;
15394 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
static int dahdi_create_channel_range(int start, int end)
Definition: chan_dahdi.c:11150
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define RESULT_SUCCESS
Definition: cli.h:40

◆ dahdi_destroy_channel_range()

static void dahdi_destroy_channel_range ( int  start,
int  end 
)
static

Definition at line 11068 of file chan_dahdi.c.

References ast_debug, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_module_unref, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, dahdi_pvt::channel, destroy_channel(), dahdi_subchannel::dfd, iflock, dahdi_pvt::next, NULL, reload(), ast_module_info::self, setup_dahdi(), setup_dahdi_int(), SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_cc_callback(), dahdi_destroy_channels(), and do_monitor().

11069 {
11070  struct dahdi_pvt *cur;
11071  struct dahdi_pvt *next;
11072  int destroyed_first = 0;
11073  int destroyed_last = 0;
11074 
11076  ast_debug(1, "range: %d-%d\n", start, end);
11077  for (cur = iflist; cur; cur = next) {
11078  next = cur->next;
11079  if (cur->channel >= start && cur->channel <= end) {
11080  int x = DAHDI_FLASH;
11081 
11082  if (cur->channel > destroyed_last) {
11083  destroyed_last = cur->channel;
11084  }
11085  if (destroyed_first < 1 || cur->channel < destroyed_first) {
11086  destroyed_first = cur->channel;
11087  }
11088  ast_debug(3, "Destroying %d\n", cur->channel);
11089  /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */
11090  ioctl(cur->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
11091 
11092  destroy_channel(cur, 1);
11094  }
11095  }
11097  if (destroyed_first > start || destroyed_last < end) {
11098  ast_debug(1, "Asked to destroy %d-%d, destroyed %d-%d,\n",
11099  start, end, destroyed_first, destroyed_last);
11100  }
11101 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
static void destroy_channel(struct dahdi_pvt *cur, int now)
Definition: chan_dahdi.c:5649
#define ast_mutex_lock(a)
Definition: lock.h:187
Definition: muted.c:95
char * end
Definition: eagi_proxy.c:73
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_module * self
Definition: module.h:342
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
#define SUB_REAL
Definition: chan_dahdi.h:57
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_destroy_channels()

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

Definition at line 15303 of file chan_dahdi.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_destroy_channel_range(), end, ast_cli_args::fd, NULL, and ast_cli_entry::usage.

15304 {
15305  int start;
15306  int end;
15307  switch (cmd) {
15308  case CLI_INIT:
15309  e->command = "dahdi destroy channels";
15310  e->usage =
15311  "Usage: dahdi destroy channels <from_channel> [<to_channel>]\n"
15312  " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n";
15313  return NULL;
15314  case CLI_GENERATE:
15315  return NULL;
15316  }
15317  if ((a->argc < 4) || a->argc > 5) {
15318  return CLI_SHOWUSAGE;
15319  }
15320  start = atoi(a->argv[3]);
15321  if (start < 1) {
15322  ast_cli(a->fd, "Invalid starting channel number %s.\n",
15323  a->argv[4]);
15324  return CLI_FAILURE;
15325  }
15326  if (a->argc == 5) {
15327  end = atoi(a->argv[4]);
15328  if (end < 1) {
15329  ast_cli(a->fd, "Invalid ending channel number %s.\n",
15330  a->argv[4]);
15331  return CLI_FAILURE;
15332  }
15333  } else {
15334  end = start;
15335  }
15336 
15337  if (end < start) {
15338  ast_cli(a->fd,
15339  "range end (%d) is smaller than range start (%d)\n",
15340  end, start);
15341  return CLI_FAILURE;
15342  }
15343  dahdi_destroy_channel_range(start, end);
15344  return CLI_SUCCESS;
15345 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
static void dahdi_destroy_channel_range(int start, int end)
Definition: chan_dahdi.c:11068
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ dahdi_devicestate()

static int dahdi_devicestate ( const char *  data)
static

Definition at line 13667 of file chan_dahdi.c.

References AST_DEVICE_UNKNOWN.

Referenced by dahdi_chan_conf_default().

13668 {
13669 #if defined(HAVE_PRI)
13670  const char *device;
13671  unsigned span;
13672  int res;
13673 
13674  device = data;
13675 
13676  if (*device != 'I') {
13677  /* The request is not for an ISDN span device. */
13678  return AST_DEVICE_UNKNOWN;
13679  }
13680  res = sscanf(device, "I%30u", &span);
13681  if (res != 1 || !span || NUM_SPANS < span) {
13682  /* Bad format for ISDN span device name. */
13683  return AST_DEVICE_UNKNOWN;
13684  }
13685  device = strchr(device, '/');
13686  if (!device) {
13687  /* Bad format for ISDN span device name. */
13688  return AST_DEVICE_UNKNOWN;
13689  }
13690 
13691  /*
13692  * Since there are currently no other span devstate's defined,
13693  * it must be congestion.
13694  */
13695 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
13696  ++device;
13697  if (!strcmp(device, "congestion"))
13698 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
13699  {
13700  return pris[span - 1].pri.congestion_devstate;
13701  }
13702 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
13703  else if (!strcmp(device, "threshold")) {
13704  return pris[span - 1].pri.threshold_devstate;
13705  }
13706  return AST_DEVICE_UNKNOWN;
13707 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
13708 #else
13709  return AST_DEVICE_UNKNOWN;
13710 #endif /* defined(HAVE_PRI) */
13711 }
#define NUM_SPANS
Definition: chan_dahdi.c:553

◆ dahdi_dial_str()

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

Definition at line 1223 of file chan_dahdi.c.

References ast_debug, ast_log, bump_gains(), dahdi_pvt::channel, dahdi_setlinear(), dahdievent_to_analogevent(), dahdi_subchannel::dfd, errno, LOG_WARNING, SUB_REAL, and dahdi_pvt::subs.

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

1224 {
1225  int res;
1226  int offset;
1227  const char *pos;
1228  struct dahdi_dialoperation zo = {
1229  .op = operation,
1230  };
1231 
1232  /* Convert the W's to ww. */
1233  pos = dial_str;
1234  for (offset = 0; offset < sizeof(zo.dialstr) - 1; ++offset) {
1235  if (!*pos) {
1236  break;
1237  }
1238  if (*pos == 'W') {
1239  /* Convert 'W' to "ww" */
1240  ++pos;
1241  if (offset >= sizeof(zo.dialstr) - 3) {
1242  /* No room to expand */
1243  break;
1244  }
1245  zo.dialstr[offset] = 'w';
1246  ++offset;
1247  zo.dialstr[offset] = 'w';
1248  continue;
1249  }
1250  zo.dialstr[offset] = *pos++;
1251  }
1252  /* The zo initialization has already terminated the dialstr. */
1253 
1254  ast_debug(1, "Channel %d: Dial str '%s' expanded to '%s' sent to DAHDI_DIAL.\n",
1255  pvt->channel, dial_str, zo.dialstr);
1256  res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo);
1257  if (res) {
1258  ast_log(LOG_WARNING, "Channel %d: Couldn't dial '%s': %s\n",
1259  pvt->channel, dial_str, strerror(errno));
1260  }
1261 
1262  return res;
1263 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
int channel
Definition: chan_dahdi.h:538

◆ dahdi_digit_begin()

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

Definition at line 4237 of file chan_dahdi.c.

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.

Referenced by dahdi_chan_conf_default().

4238 {
4239  struct dahdi_pvt *pvt;
4240  int idx;
4241  int dtmf;
4242  int res;
4243 
4244  pvt = ast_channel_tech_pvt(chan);
4245 
4246  ast_mutex_lock(&pvt->lock);
4247 
4248  idx = dahdi_get_index(chan, pvt, 0);
4249 
4250  if ((idx != SUB_REAL) || !pvt->owner)
4251  goto out;
4252 
4253 #ifdef HAVE_PRI
4254  switch (pvt->sig) {
4256  res = sig_pri_digit_begin(pvt->sig_pvt, chan, digit);
4257  if (!res)
4258  goto out;
4259  break;
4260  default:
4261  break;
4262  }
4263 #endif
4264  dtmf = digit_to_dtmfindex(digit);
4265  if (dtmf == -1) {
4266  /* Not a valid DTMF digit */
4267  goto out;
4268  }
4269 
4270  if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) {
4271  char dial_str[] = { 'T', digit, '\0' };
4272 
4273  res = dahdi_dial_str(pvt, DAHDI_DIAL_OP_APPEND, dial_str);
4274  if (!res) {
4275  pvt->dialing = 1;
4276  }
4277  } else {
4278  pvt->dialing = 1;
4279  pvt->begindigit = digit;
4280 
4281  /* Flush the write buffer in DAHDI to start sending the digit immediately. */
4282  dtmf = DAHDI_FLUSH_WRITE;
4283  res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &dtmf);
4284  if (res) {
4285  ast_log(LOG_WARNING, "Unable to flush the DAHDI write buffer to send DTMF on channel %d: %s\n",
4286  pvt->channel, strerror(errno));
4287  }
4288 
4289  ast_debug(1, "Channel %s started VLDTMF digit '%c'\n",
4290  ast_channel_name(chan), digit);
4291  }
4292 
4293 out:
4294  ast_mutex_unlock(&pvt->lock);
4295 
4296  return 0;
4297 }
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
char digit
static int dahdi_dial_str(struct dahdi_pvt *pvt, int operation, const char *dial_str)
Definition: chan_dahdi.c:1223
unsigned int dialing
TRUE if in the process of dialing digits or sending something.
Definition: chan_dahdi.h:234
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int digit_to_dtmfindex(char digit)
Definition: chan_dahdi.c:4221
#define LOG_WARNING
Definition: logger.h:274
struct ast_channel * owner
Definition: chan_dahdi.h:127
void * sig_pvt
Definition: chan_dahdi.h:709
#define ast_mutex_lock(a)
Definition: lock.h:187
unsigned int pulse
TRUE if we will pulse dial.
Definition: chan_dahdi.h:316
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
ast_mutex_t lock
Definition: chan_dahdi.h:125
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
FILE * out
Definition: utils/frame.c:33
const char * ast_channel_name(const struct ast_channel *chan)
int sig_pri_digit_begin(struct sig_pri_chan *pvt, struct ast_channel *ast, char digit)
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188
char begindigit
DTMF digit in progress. 0 when no digit in progress.
Definition: chan_dahdi.h:706

◆ dahdi_digit_end()

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

Definition at line 4299 of file chan_dahdi.c.

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, dahdi_pvt::lock, out, dahdi_pvt::owner, dahdi_pvt::pulse, dahdi_pvt::sig, SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_chan_conf_default().

4300 {
4301  struct dahdi_pvt *pvt;
4302  int res = 0;
4303  int idx;
4304  int x;
4305 
4306  pvt = ast_channel_tech_pvt(chan);
4307 
4308  ast_mutex_lock(&pvt->lock);
4309 
4310  idx = dahdi_get_index(chan, pvt, 0);
4311 
4312  if ((idx != SUB_REAL) || !pvt->owner || pvt->pulse)
4313  goto out;
4314 
4315 #ifdef HAVE_PRI
4316  /* This means that the digit was already sent via PRI signalling */
4317  if (dahdi_sig_pri_lib_handles(pvt->sig) && !pvt->begindigit) {
4318  goto out;
4319  }
4320 #endif
4321 
4322  if (pvt->begindigit) {
4323  x = -1;
4324  ast_debug(1, "Channel %s ending VLDTMF digit '%c'\n",
4325  ast_channel_name(chan), digit);
4326  res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x);
4327  pvt->dialing = 0;
4328  pvt->begindigit = 0;
4329  }
4330 
4331 out:
4332  ast_mutex_unlock(&pvt->lock);
4333 
4334  return res;
4335 }
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
char digit
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
unsigned int dialing
TRUE if in the process of dialing digits or sending something.
Definition: chan_dahdi.h:234
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_channel * owner
Definition: chan_dahdi.h:127
#define ast_mutex_lock(a)
Definition: lock.h:187
unsigned int pulse
TRUE if we will pulse dial.
Definition: chan_dahdi.h:316
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
ast_mutex_t lock
Definition: chan_dahdi.h:125
#define SUB_REAL
Definition: chan_dahdi.h:57
FILE * out
Definition: utils/frame.c:33
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_mutex_unlock(a)
Definition: lock.h:188
char begindigit
DTMF digit in progress. 0 when no digit in progress.
Definition: chan_dahdi.h:706

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

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

9467 {
9468  if (dahdi_analog_lib_handles(dahdichan->sig, dahdichan->radio, dahdichan->oprmode)) {
9469  return analog_dnd(dahdichan->sig_pvt, flag);
9470  }
9471 
9472  if (flag == -1) {
9473  return dahdichan->dnd;
9474  }
9475 
9476  /* Do not disturb */
9477  dahdichan->dnd = flag;
9478  ast_verb(3, "%s DND on channel %d\n",
9479  flag? "Enabled" : "Disabled",
9480  dahdichan->channel);
9481  publish_dnd_state(dahdichan->channel, flag ? "enabled" : "disabled");
9482  return 0;
9483 }
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
unsigned int dnd
TRUE if Do-Not-Disturb is enabled, present only for non sig_analog.
Definition: chan_dahdi.h:238
void * sig_pvt
Definition: chan_dahdi.h:709
#define ast_verb(level,...)
Definition: logger.h:463
int oprmode
Definition: chan_dahdi.h:150
long int flag
Definition: f2c.h:83
static void publish_dnd_state(int channel, const char *status)
Definition: chan_dahdi.c:9437
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
int channel
Definition: chan_dahdi.h:538
int analog_dnd(struct analog_pvt *p, int flag)
Definition: sig_analog.c:4019

◆ dahdi_dtmf_detect_disable()

void dahdi_dtmf_detect_disable ( struct dahdi_pvt p)

Definition at line 6473 of file chan_dahdi.c.

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

Referenced by dahdi_setoption(), and native_start().

6474 {
6475  int val = 0;
6476 
6477  p->ignoredtmf = 1;
6478 
6479  ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
6480 
6481  if (!p->hardwaredtmf && p->dsp) {
6484  }
6485 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
Definition: ast_expr2.c:325
unsigned int hardwaredtmf
TRUE if DTMF detection needs to be done by hardware.
Definition: chan_dahdi.h:263
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
int dsp_features
DSP feature flags: DSP_FEATURE_xxx.
Definition: chan_dahdi.h:683
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
#define SUB_REAL
Definition: chan_dahdi.h:57
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
unsigned int ignoredtmf
TRUE if DTMF detection is disabled.
Definition: chan_dahdi.h:278

◆ dahdi_dtmf_detect_enable()

void dahdi_dtmf_detect_enable ( struct dahdi_pvt p)

Definition at line 6487 of file chan_dahdi.c.

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

Referenced by dahdi_setoption(), and native_stop().

6488 {
6489  int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
6490 
6491  if (p->channel == CHAN_PSEUDO)
6492  return;
6493 
6494  p->ignoredtmf = 0;
6495 
6496  ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
6497 
6498  if (!p->hardwaredtmf && p->dsp) {
6501  }
6502 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
Definition: ast_expr2.c:325
unsigned int hardwaredtmf
TRUE if DTMF detection needs to be done by hardware.
Definition: chan_dahdi.h:263
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
int dsp_features
DSP feature flags: DSP_FEATURE_xxx.
Definition: chan_dahdi.h:683
#define CHAN_PSEUDO
Definition: chan_dahdi.c:556
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
#define SUB_REAL
Definition: chan_dahdi.h:57
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
unsigned int ignoredtmf
TRUE if DTMF detection is disabled.
Definition: chan_dahdi.h:278
int channel
Definition: chan_dahdi.h:538

◆ dahdi_ec_disable()

void dahdi_ec_disable ( struct dahdi_pvt p)

Definition at line 4710 of file chan_dahdi.c.

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

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

4711 {
4712  int res;
4713 
4714  if (p->echocanon) {
4715  struct dahdi_echocanparams ecp = { .tap_length = 0 };
4716 
4717  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &ecp);
4718 
4719  if (res)
4720  ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno));
4721  else
4722  ast_debug(1, "Disabled echo cancellation on channel %d\n", p->channel);
4723  }
4724 
4725  p->echocanon = 0;
4726 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
unsigned int echocanon
TRUE if echo cancellation is turned on.
Definition: chan_dahdi.h:248
int channel
Definition: chan_dahdi.h:538

◆ dahdi_ec_enable()

void dahdi_ec_enable ( struct dahdi_pvt p)

Definition at line 4638 of file chan_dahdi.c.

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

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

4639 {
4640  int res;
4641  if (!p)
4642  return;
4643  if (p->echocanon) {
4644  ast_debug(1, "Echo cancellation already on\n");
4645  return;
4646  }
4647  if (p->digital) {
4648  ast_debug(1, "Echo cancellation isn't required on digital connection\n");
4649  return;
4650  }
4651  if (p->echocancel.head.tap_length) {
4652 #if defined(HAVE_PRI) || defined(HAVE_SS7)
4653  switch (p->sig) {
4654 #if defined(HAVE_PRI)
4656  if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
4657  /*
4658  * PRI nobch pseudo channel. Does not need ec anyway.
4659  * Does not handle ioctl(DAHDI_AUDIOMODE)
4660  */
4661  return;
4662  }
4663  /* Fall through */
4664 #endif /* defined(HAVE_PRI) */
4665 #if defined(HAVE_SS7)
4666  case SIG_SS7:
4667 #endif /* defined(HAVE_SS7) */
4668  {
4669  int x = 1;
4670 
4671  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x);
4672  if (res)
4674  "Unable to enable audio mode on channel %d (%s)\n",
4675  p->channel, strerror(errno));
4676  }
4677  break;
4678  default:
4679  break;
4680  }
4681 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
4682  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &p->echocancel);
4683  if (res) {
4684  ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
4685  } else {
4686  p->echocanon = 1;
4687  ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel);
4688  }
4689  } else
4690  ast_debug(1, "No echo cancellation requested\n");
4691 }
unsigned int digital
TRUE if the transfer capability of the call is digital.
Definition: chan_dahdi.h:236
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
void * sig_pvt
Definition: chan_dahdi.h:709
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define SIG_SS7
Definition: chan_dahdi.h:750
struct dahdi_pvt::@110 echocancel
Echo cancel parameters.
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
struct dahdi_echocanparams head
Definition: chan_dahdi.h:580
unsigned int echocanon
TRUE if echo cancellation is turned on.
Definition: chan_dahdi.h:248
int channel
Definition: chan_dahdi.h:538

◆ dahdi_exception()

static struct ast_frame * dahdi_exception ( struct ast_channel ast)
static

Definition at line 8403 of file chan_dahdi.c.

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.

Referenced by dahdi_chan_conf_default().

8404 {
8405  struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
8406  struct ast_frame *f;
8407  ast_mutex_lock(&p->lock);
8408  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
8409  struct analog_pvt *analog_p = p->sig_pvt;
8410  f = analog_exception(analog_p, ast);
8411  } else {
8412  f = __dahdi_exception(ast);
8413  }
8414  ast_mutex_unlock(&p->lock);
8415  return f;
8416 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
static struct ast_frame * __dahdi_exception(struct ast_channel *ast)
Definition: chan_dahdi.c:8281
void * sig_pvt
Definition: chan_dahdi.h:709
#define ast_mutex_lock(a)
Definition: lock.h:187
int oprmode
Definition: chan_dahdi.h:150
ast_mutex_t lock
Definition: chan_dahdi.h:125
struct ast_frame * analog_exception(struct analog_pvt *p, struct ast_channel *ast)
Definition: sig_analog.c:3555
Data structure associated with a single frame of data.
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_fake_event()

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

Definition at line 16237 of file chan_dahdi.c.

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

Referenced by action_transfer(), and action_transferhangup().

16238 {
16239  if (p) {
16240  switch (mode) {
16241  case TRANSFER:
16242  p->fake_event = DAHDI_EVENT_WINKFLASH;
16243  break;
16244  case HANGUP:
16245  p->fake_event = DAHDI_EVENT_ONHOOK;
16246  break;
16247  default:
16248  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));
16249  }
16250  }
16251  return 0;
16252 }
#define LOG_WARNING
Definition: logger.h:274
struct ast_channel * owner
Definition: chan_dahdi.h:127
#define TRANSFER
Definition: chan_dahdi.c:16234
#define ast_log
Definition: astobj2.c:42
#define HANGUP
Definition: chan_dahdi.c:16235
int fake_event
Holding place for event injected from outside normal operation.
Definition: chan_dahdi.h:667
const char * ast_channel_name(const struct ast_channel *chan)

◆ dahdi_fixup()

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

Definition at line 7061 of file chan_dahdi.c.

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.

Referenced by dahdi_chan_conf_default().

7062 {
7063  struct dahdi_pvt *p = ast_channel_tech_pvt(newchan);
7064  int x;
7065 
7066  ast_mutex_lock(&p->lock);
7067 
7068  ast_debug(1, "New owner for channel %d is %s\n", p->channel, ast_channel_name(newchan));
7069  if (p->owner == oldchan) {
7070  p->owner = newchan;
7071  }
7072  for (x = 0; x < 3; x++) {
7073  if (p->subs[x].owner == oldchan) {
7074  if (!x) {
7076  }
7077  p->subs[x].owner = newchan;
7078  }
7079  }
7080  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
7081  analog_fixup(oldchan, newchan, p->sig_pvt);
7082 #if defined(HAVE_PRI)
7083  } else if (dahdi_sig_pri_lib_handles(p->sig)) {
7084  sig_pri_fixup(oldchan, newchan, p->sig_pvt);
7085 #endif /* defined(HAVE_PRI) */
7086 #if defined(HAVE_SS7)
7087  } else if (p->sig == SIG_SS7) {
7088  sig_ss7_fixup(oldchan, newchan, p->sig_pvt);
7089 #endif /* defined(HAVE_SS7) */
7090  }
7091  dahdi_conf_update(p);
7092 
7093  ast_mutex_unlock(&p->lock);
7094 
7095  if (ast_channel_state(newchan) == AST_STATE_RINGING) {
7096  dahdi_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
7097  }
7098  return 0;
7099 }
static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Definition: chan_dahdi.c:8975
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
void dahdi_master_slave_unlink(struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
Definition: chan_dahdi.c:6981
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
struct ast_channel * owner
Definition: chan_dahdi.h:127
ast_channel_state
ast_channel states
Definition: channelstate.h:35
void * sig_pvt
Definition: chan_dahdi.h:709
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
void dahdi_conf_update(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4583
int analog_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, void *newp)
Definition: sig_analog.c:3981
int oprmode
Definition: chan_dahdi.h:150
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
ast_mutex_t lock
Definition: chan_dahdi.h:125
struct ast_channel * owner
Definition: chan_dahdi.h:79
#define SIG_SS7
Definition: chan_dahdi.h:750
void sig_pri_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan)
const char * ast_channel_name(const struct ast_channel *chan)
void sig_ss7_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_ss7_chan *pchan)
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

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

References ast_channel_tech_pvt(), ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, dahdi_pvt::group, dahdi_pvt::lock, dahdi_pvt::rxgain, dahdi_pvt::sig, SIG_MFCR2, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, SIG_SS7, dahdi_pvt::span, and dahdi_pvt::txgain.

Referenced by dahdi_chan_conf_default().

6765 {
6766  struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
6767  int res = 0;
6768 
6769  if (!p) {
6770  /* No private structure! */
6771  *buf = '\0';
6772  return -1;
6773  }
6774 
6775  if (!strcasecmp(data, "rxgain")) {
6776  ast_mutex_lock(&p->lock);
6777  snprintf(buf, len, "%f", p->rxgain);
6778  ast_mutex_unlock(&p->lock);
6779  } else if (!strcasecmp(data, "txgain")) {
6780  ast_mutex_lock(&p->lock);
6781  snprintf(buf, len, "%f", p->txgain);
6782  ast_mutex_unlock(&p->lock);
6783  } else if (!strcasecmp(data, "dahdi_channel")) {
6784  ast_mutex_lock(&p->lock);
6785  snprintf(buf, len, "%d", p->channel);
6786  ast_mutex_unlock(&p->lock);
6787  } else if (!strcasecmp(data, "dahdi_span")) {
6788  ast_mutex_lock(&p->lock);
6789  snprintf(buf, len, "%d", p->span);
6790  ast_mutex_unlock(&p->lock);
6791  } else if (!strcasecmp(data, "dahdi_group")) {
6792  ast_mutex_lock(&p->lock);
6793  snprintf(buf, len, "%llu", p->group);
6794  ast_mutex_unlock(&p->lock);
6795  } else if (!strcasecmp(data, "dahdi_type")) {
6796  ast_mutex_lock(&p->lock);
6797  switch (p->sig) {
6798 #if defined(HAVE_OPENR2)
6799  case SIG_MFCR2:
6800  ast_copy_string(buf, "mfc/r2", len);
6801  break;
6802 #endif /* defined(HAVE_OPENR2) */
6803 #if defined(HAVE_PRI)
6805  ast_copy_string(buf, "pri", len);
6806  break;
6807 #endif /* defined(HAVE_PRI) */
6808  case 0:
6809  ast_copy_string(buf, "pseudo", len);
6810  break;
6811 #if defined(HAVE_SS7)
6812  case SIG_SS7:
6813  ast_copy_string(buf, "ss7", len);
6814  break;
6815 #endif /* defined(HAVE_SS7) */
6816  default:
6817  /* The only thing left is analog ports. */
6818  ast_copy_string(buf, "analog", len);
6819  break;
6820  }
6821  ast_mutex_unlock(&p->lock);
6822 #if defined(HAVE_PRI)
6823 #if defined(HAVE_PRI_REVERSE_CHARGE)
6824  } else if (!strcasecmp(data, "reversecharge")) {
6825  ast_mutex_lock(&p->lock);
6826  switch (p->sig) {
6828  snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->reverse_charging_indication);
6829  break;
6830  default:
6831  *buf = '\0';
6832  res = -1;
6833  break;
6834  }
6835  ast_mutex_unlock(&p->lock);
6836 #endif
6837 #if defined(HAVE_PRI_SETUP_KEYPAD)
6838  } else if (!strcasecmp(data, "keypad_digits")) {
6839  ast_mutex_lock(&p->lock);
6840  switch (p->sig) {
6842  ast_copy_string(buf, ((struct sig_pri_chan *) p->sig_pvt)->keypad_digits,
6843  len);
6844  break;
6845  default:
6846  *buf = '\0';
6847  res = -1;
6848  break;
6849  }
6850  ast_mutex_unlock(&p->lock);
6851 #endif /* defined(HAVE_PRI_SETUP_KEYPAD) */
6852  } else if (!strcasecmp(data, "no_media_path")) {
6853  ast_mutex_lock(&p->lock);
6854  switch (p->sig) {
6856  /*
6857  * TRUE if the call is on hold or is call waiting because
6858  * there is no media path available.
6859  */
6860  snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel);
6861  break;
6862  default:
6863  *buf = '\0';
6864  res = -1;
6865  break;
6866  }
6867  ast_mutex_unlock(&p->lock);
6868 #endif /* defined(HAVE_PRI) */
6869  } else {
6870  *buf = '\0';
6871  res = -1;
6872  }
6873 
6874  return res;
6875 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void * sig_pvt
Definition: chan_dahdi.h:709
#define ast_mutex_lock(a)
Definition: lock.h:187
float txgain
Software Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:161
ast_mutex_t lock
Definition: chan_dahdi.h:125
#define SIG_SS7
Definition: chan_dahdi.h:750
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
#define SIG_MFCR2
Definition: chan_dahdi.h:753
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
float rxgain
Software Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:159
ast_group_t group
Bitmapped groups this belongs to.
Definition: chan_dahdi.h:505
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_func_write()

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

Definition at line 6907 of file chan_dahdi.c.

References ast_channel_tech_pvt(), ast_log, ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::bufferoverrideinuse, dahdi_pvt::bufsize, dahdi_pvt::channel, dahdi_ec_disable(), dahdi_ec_enable(), dahdi_subchannel::dfd, dahdi_pvt::echocanon, errno, dahdi_pvt::lock, LOG_WARNING, parse_buffers_policy(), SUB_REAL, and dahdi_pvt::subs.

Referenced by dahdi_chan_conf_default().

6908 {
6909  struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
6910  int res = 0;
6911 
6912  if (!p) {
6913  /* No private structure! */
6914  return -1;
6915  }
6916 
6917  if (!strcasecmp(data, "buffers")) {
6918  int num_bufs, policy;
6919 
6920  if (!(parse_buffers_policy(value, &num_bufs, &policy))) {
6921  struct dahdi_bufferinfo bi = {
6922  .txbufpolicy = policy,
6923  .rxbufpolicy = policy,
6924  .bufsize = p->bufsize,
6925  .numbufs = num_bufs,
6926  };
6927  int bpres;
6928 
6929  if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
6930  ast_log(LOG_WARNING, "Channel '%d' unable to override buffer policy: %s\n", p->channel, strerror(errno));
6931  } else {
6932  p->bufferoverrideinuse = 1;
6933  }
6934  } else {
6935  res = -1;
6936  }
6937  } else if (!strcasecmp(data, "echocan_mode")) {
6938  if (!strcasecmp(value, "on")) {
6939  ast_mutex_lock(&p->lock);
6940  dahdi_ec_enable(p);
6941  ast_mutex_unlock(&p->lock);
6942  } else if (!strcasecmp(value, "off")) {
6943  ast_mutex_lock(&p->lock);
6944  dahdi_ec_disable(p);
6945  ast_mutex_unlock(&p->lock);
6946 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
6947  } else if (!strcasecmp(value, "fax")) {
6948  int blah = 1;
6949 
6950  ast_mutex_lock(&p->lock);
6951  if (!p->echocanon) {
6952  dahdi_ec_enable(p);
6953  }
6954  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) {
6955  ast_log(LOG_WARNING, "Unable to place echocan into fax mode on channel %d: %s\n", p->channel, strerror(errno));
6956  }
6957  ast_mutex_unlock(&p->lock);
6958  } else if (!strcasecmp(value, "voice")) {
6959  int blah = 0;
6960 
6961  ast_mutex_lock(&p->lock);
6962  if (!p->echocanon) {
6963  dahdi_ec_enable(p);
6964  }
6965  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_FAX_MODE, &blah)) {
6966  ast_log(LOG_WARNING, "Unable to place echocan into voice mode on channel %d: %s\n", p->channel, strerror(errno));
6967  }
6968  ast_mutex_unlock(&p->lock);
6969 #endif
6970  } else {
6971  ast_log(LOG_WARNING, "Unsupported value '%s' provided for '%s' item.\n", value, data);
6972  res = -1;
6973  }
6974  } else {
6975  res = -1;
6976  }
6977 
6978  return res;
6979 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void dahdi_ec_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4638
static int parse_buffers_policy(const char *parse, int *num_buffers, int *policy)
Definition: chan_dahdi.c:6878
#define LOG_WARNING
Definition: logger.h:274
int bufsize
Definition: chan_dahdi.h:138
void dahdi_ec_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4710
#define ast_mutex_lock(a)
Definition: lock.h:187
int value
Definition: syslog.c:37
unsigned int bufferoverrideinuse
Definition: chan_dahdi.h:254
#define ast_log
Definition: astobj2.c:42
ast_mutex_t lock
Definition: chan_dahdi.h:125
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
unsigned int echocanon
TRUE if echo cancellation is turned on.
Definition: chan_dahdi.h:248
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

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

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

653 {
654  int j;
655  if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
656  return -1;
657  return j;
658 }

◆ dahdi_handle_dtmf()

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

Definition at line 7231 of file chan_dahdi.c.

References ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_macrocontext(), 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, DSP_FEATURE_FAX_DETECT, 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, S_OR, send_cwcidspill(), ast_frame::subclass, dahdi_pvt::subs, and dahdi_pvt::usefaxbuffers.

Referenced by dahdi_handle_event(), and dahdi_read().

7232 {
7233  struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
7234  struct ast_frame *f = *dest;
7235 
7236  ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
7237  f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
7238  (unsigned)f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
7239 
7240  if (p->confirmanswer) {
7241  if (f->frametype == AST_FRAME_DTMF_END) {
7242  ast_debug(1, "Confirm answer on %s!\n", ast_channel_name(ast));
7243  /* Upon receiving a DTMF digit, consider this an answer confirmation instead
7244  of a DTMF digit */
7245  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
7247  /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
7248  p->confirmanswer = 0;
7249  } else {
7250  p->subs[idx].f.frametype = AST_FRAME_NULL;
7251  p->subs[idx].f.subclass.integer = 0;
7252  }
7253  *dest = &p->subs[idx].f;
7254  } else if (p->callwaitcas) {
7255  if (f->frametype == AST_FRAME_DTMF_END) {
7256  if ((f->subclass.integer == 'A') || (f->subclass.integer == 'D')) {
7257  ast_debug(1, "Got some DTMF, but it's for the CAS\n");
7258  ast_free(p->cidspill);
7259  p->cidspill = NULL;
7260  send_cwcidspill(p);
7261  }
7262  p->callwaitcas = 0;
7263  }
7264  p->subs[idx].f.frametype = AST_FRAME_NULL;
7265  p->subs[idx].f.subclass.integer = 0;
7266  *dest = &p->subs[idx].f;
7267  } else if (f->subclass.integer == 'f') {
7268  if (f->frametype == AST_FRAME_DTMF_END) {
7269  /* Fax tone -- Handle and return NULL */
7270  if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
7271  /* If faxbuffers are configured, use them for the fax transmission */
7272  if (p->usefaxbuffers && !p->bufferoverrideinuse) {
7273  struct dahdi_bufferinfo bi = {
7274  .txbufpolicy = p->faxbuf_policy,
7275  .bufsize = p->bufsize,
7276  .numbufs = p->faxbuf_no
7277  };
7278  int res;
7279 
7280  if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
7281  ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno));
7282  } else {
7283  p->bufferoverrideinuse = 1;
7284  }
7285  }
7286  p->faxhandled = 1;
7287  if (p->dsp) {
7290  ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
7291  }
7292  if (strcmp(ast_channel_exten(ast), "fax")) {
7293  const char *target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
7294 
7295  /*
7296  * We need to unlock 'ast' here because ast_exists_extension has the
7297  * potential to start autoservice on the channel. Such action is prone
7298  * to deadlock if the channel is locked.
7299  *
7300  * ast_async_goto() has its own restriction on not holding the
7301  * channel lock.
7302  */
7303  ast_mutex_unlock(&p->lock);
7304  ast_channel_unlock(ast);
7305  if (ast_exists_extension(ast, target_context, "fax", 1,
7306  S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, NULL))) {
7307  ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast));
7308  /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
7309  pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
7310  if (ast_async_goto(ast, target_context, "fax", 1))
7311  ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
7312  } else {
7313  ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
7314  }
7315  ast_channel_lock(ast);
7316  ast_mutex_lock(&p->lock);
7317  } else {
7318  ast_debug(1, "Already in a fax extension, not redirecting\n");
7319  }
7320  } else {
7321  ast_debug(1, "Fax already handled\n");
7322  }
7323  dahdi_confmute(p, 0);
7324  }
7325  p->subs[idx].f.frametype = AST_FRAME_NULL;
7326  p->subs[idx].f.subclass.integer = 0;
7327  *dest = &p->subs[idx].f;
7328  }
7329 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int faxbuf_no
Definition: chan_dahdi.h:141
#define ast_channel_lock(chan)
Definition: channel.h:2945
int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: chan_dahdi.h:575
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int dahdi_confmute(struct dahdi_pvt *p, int muted)
Definition: chan_dahdi.c:4939
#define LOG_WARNING
Definition: logger.h:274
int dsp_features
DSP feature flags: DSP_FEATURE_xxx.
Definition: chan_dahdi.h:683
unsigned int usefaxbuffers
Definition: chan_dahdi.h:252
int bufsize
Definition: chan_dahdi.h:138
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
struct ast_frame f
Definition: chan_dahdi.h:82
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_frame_subclass subclass
Number structure.
Definition: app_followme.c:154
unsigned int bufferoverrideinuse
Definition: chan_dahdi.h:254
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
ast_mutex_t lock
Definition: chan_dahdi.h:125
#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:85
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
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:4179
const char * ast_channel_exten(const struct ast_channel *chan)
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
unsigned int faxhandled
TRUE if a fax tone has already been handled.
Definition: chan_dahdi.h:250
static int send_cwcidspill(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5017
int errno
#define LOG_NOTICE
Definition: logger.h:263
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
#define ast_free(a)
Definition: astmm.h:182
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...
unsigned int confirmanswer
TRUE if to wait for a DTMF digit to confirm answer.
Definition: chan_dahdi.h:221
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
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:7011
Data structure associated with a single frame of data.
int faxbuf_policy
Definition: chan_dahdi.h:142
const char * ast_channel_context(const struct ast_channel *chan)
enum ast_frame_type frametype
const char * ast_channel_macrocontext(const struct ast_channel *chan)
int callprogress
Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
Definition: chan_dahdi.h:604
#define CALLPROGRESS_FAX
Definition: chan_dahdi.c:561
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_handle_event()

static struct ast_frame* dahdi_handle_event ( struct ast_channel ast)
static

Definition at line 7386 of file chan_dahdi.c.

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(), cid_name, dahdi_pvt::cid_name, cid_num, 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().

7387 {
7388  int res, x;
7389  int idx, mysig;
7390  char *c;
7391  struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
7392  pthread_t threadid;
7393  struct ast_channel *chan;
7394  struct ast_frame *f;
7395 
7396  idx = dahdi_get_index(ast, p, 0);
7397  if (idx < 0) {
7398  return &ast_null_frame;
7399  }
7400  mysig = p->sig;
7401  if (p->outsigmod > -1)
7402  mysig = p->outsigmod;
7403  p->subs[idx].f.frametype = AST_FRAME_NULL;
7404  p->subs[idx].f.subclass.integer = 0;
7405  p->subs[idx].f.datalen = 0;
7406  p->subs[idx].f.samples = 0;
7407  p->subs[idx].f.mallocd = 0;
7408  p->subs[idx].f.offset = 0;
7409  p->subs[idx].f.src = "dahdi_handle_event";
7410  p->subs[idx].f.data.ptr = NULL;
7411  f = &p->subs[idx].f;
7412 
7413  if (p->fake_event) {
7414  res = p->fake_event;
7415  p->fake_event = 0;
7416  } else
7417  res = dahdi_get_event(p->subs[idx].dfd);
7418 
7419  ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, idx);
7420 
7421  if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) {
7422  p->pulsedial = (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0;
7423  ast_debug(1, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
7424 #if defined(HAVE_PRI)
7426  && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING
7427  && p->pri
7428  && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
7429  /* absorb event */
7430  } else
7431 #endif /* defined(HAVE_PRI) */
7432  {
7433  /* Unmute conference */
7434  dahdi_confmute(p, 0);
7435  p->subs[idx].f.frametype = AST_FRAME_DTMF_END;
7436  p->subs[idx].f.subclass.integer = res & 0xff;
7437  dahdi_handle_dtmf(ast, idx, &f);
7438  }
7439  return f;
7440  }
7441 
7442  if (res & DAHDI_EVENT_DTMFDOWN) {
7443  ast_debug(1, "DTMF Down '%c'\n", res & 0xff);
7444 #if defined(HAVE_PRI)
7446  && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING
7447  && p->pri
7448  && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
7449  /* absorb event */
7450  } else
7451 #endif /* defined(HAVE_PRI) */
7452  {
7453  /* Mute conference */
7454  dahdi_confmute(p, 1);
7456  p->subs[idx].f.subclass.integer = res & 0xff;
7457  dahdi_handle_dtmf(ast, idx, &f);
7458  }
7459  return &p->subs[idx].f;
7460  }
7461 
7462  switch (res) {
7463  case DAHDI_EVENT_EC_DISABLED:
7464  ast_verb(3, "Channel %d echo canceler disabled.\n", p->channel);
7465  p->echocanon = 0;
7466  break;
7467 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
7468  case DAHDI_EVENT_TX_CED_DETECTED:
7469  ast_verb(3, "Channel %d detected a CED tone towards the network.\n", p->channel);
7470  break;
7471  case DAHDI_EVENT_RX_CED_DETECTED:
7472  ast_verb(3, "Channel %d detected a CED tone from the network.\n", p->channel);
7473  break;
7474  case DAHDI_EVENT_EC_NLP_DISABLED:
7475  ast_verb(3, "Channel %d echo canceler disabled its NLP.\n", p->channel);
7476  break;
7477  case DAHDI_EVENT_EC_NLP_ENABLED:
7478  ast_verb(3, "Channel %d echo canceler enabled its NLP.\n", p->channel);
7479  break;
7480 #endif
7481  case DAHDI_EVENT_BITSCHANGED:
7482 #ifdef HAVE_OPENR2
7483  if (p->sig != SIG_MFCR2) {
7484  ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig));
7485  } else {
7486  ast_debug(1, "bits changed in chan %d\n", p->channel);
7487  openr2_chan_handle_cas(p->r2chan);
7488  }
7489 #else
7490  ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig));
7491 #endif
7492  break;
7493  case DAHDI_EVENT_PULSE_START:
7494  /* Stop tone if there's a pulse start and the PBX isn't started */
7495  if (!ast_channel_pbx(ast))
7496  tone_zone_play_tone(p->subs[idx].dfd, -1);
7497  break;
7498  case DAHDI_EVENT_DIALCOMPLETE:
7499  /* DAHDI has completed dialing all digits sent using DAHDI_DIAL. */
7500 #if defined(HAVE_PRI)
7501  if (dahdi_sig_pri_lib_handles(p->sig)) {
7502  if (p->inalarm) {
7503  break;
7504  }
7505  if (ioctl(p->subs[idx].dfd, DAHDI_DIALING, &x) == -1) {
7506  ast_debug(1, "DAHDI_DIALING ioctl failed on %s: %s\n",
7507  ast_channel_name(ast), strerror(errno));
7508  return NULL;
7509  }
7510  if (x) {
7511  /* Still dialing in DAHDI driver */
7512  break;
7513  }
7514  /*
7515  * The ast channel is locked and the private may be locked more
7516  * than once.
7517  */
7518  sig_pri_dial_complete(p->sig_pvt, ast);
7519  break;
7520  }
7521 #endif /* defined(HAVE_PRI) */
7522 #ifdef HAVE_OPENR2
7523  if ((p->sig & SIG_MFCR2) && p->r2chan && ast_channel_state(ast) != AST_STATE_UP) {
7524  /* we don't need to do anything for this event for R2 signaling
7525  if the call is being setup */
7526  break;
7527  }
7528 #endif
7529  if (p->inalarm) break;
7530  if ((p->radio || (p->oprmode < 0))) break;
7531  if (ioctl(p->subs[idx].dfd,DAHDI_DIALING,&x) == -1) {
7532  ast_debug(1, "DAHDI_DIALING ioctl failed on %s: %s\n",ast_channel_name(ast), strerror(errno));
7533  return NULL;
7534  }
7535  if (!x) { /* if not still dialing in driver */
7536  dahdi_ec_enable(p);
7537  if (p->echobreak) {
7538  dahdi_train_ec(p);
7539  ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
7540  p->dop.op = DAHDI_DIAL_OP_REPLACE;
7541  res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
7542  p->echobreak = 0;
7543  } else {
7544  p->dialing = 0;
7545  if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
7546  /* if thru with dialing after offhook */
7548  ast_setstate(ast, AST_STATE_UP);
7549  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
7551  break;
7552  } else { /* if to state wait for offhook to dial rest */
7553  /* we now wait for off hook */
7555  }
7556  }
7557  if (ast_channel_state(ast) == AST_STATE_DIALING) {
7558  if ((p->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
7559  ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n");
7560  } else if (p->confirmanswer || (!p->dialednone
7561  && ((mysig == SIG_EM) || (mysig == SIG_EM_E1)
7562  || (mysig == SIG_EMWINK) || (mysig == SIG_FEATD)
7563  || (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF)
7564  || (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA)
7565  || (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB)
7566  || (mysig == SIG_SF) || (mysig == SIG_SFWINK)
7567  || (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF)
7568  || (mysig == SIG_SF_FEATB)))) {
7570  } else if (!p->answeronpolarityswitch) {
7571  ast_setstate(ast, AST_STATE_UP);
7572  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
7574  /* If aops=0 and hops=1, this is necessary */
7575  p->polarity = POLARITY_REV;
7576  } else {
7577  /* Start clean, so we can catch the change to REV polarity when party answers */
7578  p->polarity = POLARITY_IDLE;
7579  }
7580  }
7581  }
7582  }
7583  break;
7584  case DAHDI_EVENT_ALARM:
7585  switch (p->sig) {
7586 #if defined(HAVE_PRI)
7589  break;
7590 #endif /* defined(HAVE_PRI) */
7591 #if defined(HAVE_SS7)
7592  case SIG_SS7:
7593  sig_ss7_set_alarm(p->sig_pvt, 1);
7594  break;
7595 #endif /* defined(HAVE_SS7) */
7596  default:
7597  p->inalarm = 1;
7598  break;
7599  }
7600  res = get_alarms(p);
7601  handle_alarms(p, res);
7602 #ifdef HAVE_PRI
7603  if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
7604  /* fall through intentionally */
7605  } else {
7606  break;
7607  }
7608 #endif
7609 #if defined(HAVE_SS7)
7610  if (p->sig == SIG_SS7)
7611  break;
7612 #endif /* defined(HAVE_SS7) */
7613 #ifdef HAVE_OPENR2
7614  if (p->sig == SIG_MFCR2)
7615  break;
7616 #endif
7617  case DAHDI_EVENT_ONHOOK:
7618  if (p->radio) {
7619  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
7621  break;
7622  }
7623  if (p->oprmode < 0)
7624  {
7625  if (p->oprmode != -1) break;
7626  if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
7627  {
7628  /* Make sure it starts ringing */
7629  dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
7630  dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RING);
7632  tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
7633  }
7634  break;
7635  }
7636  switch (p->sig) {
7637  case SIG_FXOLS:
7638  case SIG_FXOGS:
7639  case SIG_FXOKS:
7640  /* Check for some special conditions regarding call waiting */
7641  if (idx == SUB_REAL) {
7642  /* The normal line was hung up */
7643  if (p->subs[SUB_CALLWAIT].owner) {
7644  /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
7646  ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel);
7648 #if 0
7649  p->subs[idx].needanswer = 0;
7650  p->subs[idx].needringing = 0;
7651 #endif
7652  p->callwaitingrepeat = 0;
7653  p->cidcwexpire = 0;
7654  p->cid_suppress_expire = 0;
7655  p->owner = NULL;
7656  /* Don't start streaming audio yet if the incoming call isn't up yet */
7658  p->dialing = 1;
7659  dahdi_ring_phone(p);
7660  } else if (p->subs[SUB_THREEWAY].owner) {
7661  unsigned int mssinceflash;
7662  /* Here we have to retain the lock on both the main channel, the 3-way channel, and
7663  the private structure -- not especially easy or clean */
7665  /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
7666  DLA_UNLOCK(&p->lock);
7668  /* We can grab ast and p in that order, without worry. We should make sure
7669  nothing seriously bad has happened though like some sort of bizarre double
7670  masquerade! */
7671  DLA_LOCK(&p->lock);
7672  if (p->owner != ast) {
7673  ast_log(LOG_WARNING, "This isn't good...\n");
7674  return NULL;
7675  }
7676  }
7677  if (!p->subs[SUB_THREEWAY].owner) {
7678  ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
7679  return NULL;
7680  }
7681  mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
7682  ast_debug(1, "Last flash was %u ms ago\n", mssinceflash);
7683  if (mssinceflash < MIN_MS_SINCE_FLASH) {
7684  /* It hasn't been long enough since the last flashook. This is probably a bounce on
7685  hanging up. Hangup both channels now */
7686  if (p->subs[SUB_THREEWAY].owner)
7689  ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
7691  } else if ((ast_channel_pbx(ast)) || (ast_channel_state(ast) == AST_STATE_UP)) {
7692  if (p->transfer) {
7693  /* In any case this isn't a threeway call anymore */
7694  p->subs[SUB_REAL].inthreeway = 0;
7695  p->subs[SUB_THREEWAY].inthreeway = 0;
7696  /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
7697  if (!p->transfertobusy && ast_channel_state(ast) == AST_STATE_BUSY) {
7699  /* Swap subs and dis-own channel */
7701  p->owner = NULL;
7702  /* Ring the phone */
7703  dahdi_ring_phone(p);
7704  } else if (!attempt_transfer(p)) {
7705  /*
7706  * Transfer successful. Don't actually hang up at this point.
7707  * Let our channel legs of the calls die off as the transfer
7708  * percolates through the core.
7709  */
7710  break;
7711  }
7712  } else {
7714  if (p->subs[SUB_THREEWAY].owner)
7716  }
7717  } else {
7719  /* Swap subs and dis-own channel */
7721  p->owner = NULL;
7722  /* Ring the phone */
7723  dahdi_ring_phone(p);
7724  }
7725  }
7726  } else {
7727  ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", idx);
7728  }
7729  /* Fall through */
7730  default:
7731  dahdi_ec_disable(p);
7732  return NULL;
7733  }
7734  break;
7735  case DAHDI_EVENT_RINGOFFHOOK:
7736  if (p->inalarm) break;
7737  if (p->oprmode < 0)
7738  {
7739  if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
7740  {
7741  /* Make sure it stops ringing */
7742  dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
7743  tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, -1);
7745  }
7746  break;
7747  }
7748  if (p->radio)
7749  {
7750  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
7752  break;
7753  }
7754  /* for E911, its supposed to wait for offhook then dial
7755  the second half of the dial string */
7756  if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast_channel_state(ast) == AST_STATE_DIALING_OFFHOOK)) {
7757  c = strchr(p->dialdest, '/');
7758  if (c)
7759  c++;
7760  else
7761  c = p->dialdest;
7762 
7763  if (*c) {
7764  int numchars = snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
7765  if (numchars >= sizeof(p->dop.dialstr)) {
7766  ast_log(LOG_WARNING, "Dial string '%s' truncated\n", c);
7767  }
7768  } else {
7769  ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
7770  }
7771 
7772  if (strlen(p->dop.dialstr) > 4) {
7773  memset(p->echorest, 'w', sizeof(p->echorest) - 1);
7774  strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
7775  p->echorest[sizeof(p->echorest) - 1] = '\0';
7776  p->echobreak = 1;
7777  p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
7778  } else
7779  p->echobreak = 0;
7780  if (dahdi_dial_str(p, p->dop.op, p->dop.dialstr)) {
7781  x = DAHDI_ONHOOK;
7782  ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
7783  return NULL;
7784  }
7785  p->dialing = 1;
7786  return &p->subs[idx].f;
7787  }
7788  switch (p->sig) {
7789  case SIG_FXOLS:
7790  case SIG_FXOGS:
7791  case SIG_FXOKS:
7792  switch (ast_channel_state(ast)) {
7793  case AST_STATE_RINGING:
7794  dahdi_ec_enable(p);
7795  dahdi_train_ec(p);
7796  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
7798  /* Make sure it stops ringing */
7799  p->subs[SUB_REAL].needringing = 0;
7800  dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
7801  ast_debug(1, "channel %d answered\n", p->channel);
7802 
7803  /* Cancel any running CallerID spill */
7804  ast_free(p->cidspill);
7805  p->cidspill = NULL;
7806  restore_conference(p);
7807 
7808  p->dialing = 0;
7809  p->callwaitcas = 0;
7810  if (p->confirmanswer) {
7811  /* Ignore answer if "confirm answer" is enabled */
7812  p->subs[idx].f.frametype = AST_FRAME_NULL;
7813  p->subs[idx].f.subclass.integer = 0;
7814  } else if (!ast_strlen_zero(p->dop.dialstr)) {
7815  /* [email protected] 4/3/03 - fxo should be able to do deferred dialing */
7816  res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
7817  if (res) {
7818  p->dop.dialstr[0] = '\0';
7819  return NULL;
7820  } else {
7821  ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
7822  p->subs[idx].f.frametype = AST_FRAME_NULL;
7823  p->subs[idx].f.subclass.integer = 0;
7824  p->dialing = 1;
7825  }
7826  p->dop.dialstr[0] = '\0';
7828  } else
7829  ast_setstate(ast, AST_STATE_UP);
7830  return &p->subs[idx].f;
7831  case AST_STATE_DOWN:
7833  ast_channel_rings_set(ast, 1);
7834  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
7836  ast_debug(1, "channel %d picked up\n", p->channel);
7837  return &p->subs[idx].f;
7838  case AST_STATE_UP:
7839  /* Make sure it stops ringing */
7840  dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
7841  /* Okay -- probably call waiting*/
7842  ast_queue_unhold(p->owner);
7843  p->subs[idx].needunhold = 1;
7844  break;
7845  case AST_STATE_RESERVED:
7846  /* Start up dialtone */
7847  if (has_voicemail(p))
7848  res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
7849  else
7850  res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
7851  break;
7852  default:
7853  ast_log(LOG_WARNING, "FXO phone off hook in weird state %u??\n", ast_channel_state(ast));
7854  }
7855  break;
7856  case SIG_FXSLS:
7857  case SIG_FXSGS:
7858  case SIG_FXSKS:
7859  if (ast_channel_state(ast) == AST_STATE_RING) {
7860  p->ringt = p->ringt_base;
7861  }
7862 
7863  /* If we get a ring then we cannot be in
7864  * reversed polarity. So we reset to idle */
7865  ast_debug(1, "Setting IDLE polarity due "
7866  "to ring. Old polarity was %d\n",
7867  p->polarity);
7868  p->polarity = POLARITY_IDLE;
7869 
7870  /* Fall through */
7871  case SIG_EM:
7872  case SIG_EM_E1:
7873  case SIG_EMWINK:
7874  case SIG_FEATD:
7875  case SIG_FEATDMF:
7876  case SIG_FEATDMF_TA:
7877  case SIG_E911:
7878  case SIG_FGC_CAMA:
7879  case SIG_FGC_CAMAMF:
7880  case SIG_FEATB:
7881  case SIG_SF:
7882  case SIG_SFWINK:
7883  case SIG_SF_FEATD:
7884  case SIG_SF_FEATDMF:
7885  case SIG_SF_FEATB:
7889  ast_debug(1, "Ring detected\n");
7890  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
7892  } else if (p->outgoing && ((ast_channel_state(ast) == AST_STATE_RINGING) || (ast_channel_state(ast) == AST_STATE_DIALING))) {
7893  ast_debug(1, "Line answered\n");
7894  if (p->confirmanswer) {
7895  p->subs[idx].f.frametype = AST_FRAME_NULL;
7896  p->subs[idx].f.subclass.integer = 0;
7897  } else {
7898  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
7900  ast_setstate(ast, AST_STATE_UP);
7901  }
7902  } else if (ast_channel_state(ast) != AST_STATE_RING)
7903  ast_log(LOG_WARNING, "Ring/Off-hook in strange state %u on channel %d\n", ast_channel_state(ast), p->channel);
7904  break;
7905  default:
7906  ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
7907  }
7908  break;
7909  case DAHDI_EVENT_RINGBEGIN:
7910  switch (p->sig) {
7911  case SIG_FXSLS:
7912  case SIG_FXSGS:
7913  case SIG_FXSKS:
7914  if (ast_channel_state(ast) == AST_STATE_RING) {
7915  p->ringt = p->ringt_base;
7916  }
7917  break;
7918  }
7919  break;
7920  case DAHDI_EVENT_RINGERON:
7921  break;
7922  case DAHDI_EVENT_NOALARM:
7923  switch (p->sig) {
7924 #if defined(HAVE_PRI)
7927  break;
7928 #endif /* defined(HAVE_PRI) */
7929 #if defined(HAVE_SS7)
7930  case SIG_SS7:
7931  sig_ss7_set_alarm(p->sig_pvt, 0);
7932  break;
7933 #endif /* defined(HAVE_SS7) */
7934  default:
7935  p->inalarm = 0;
7936  break;
7937  }
7939  break;
7940  case DAHDI_EVENT_WINKFLASH:
7941  if (p->inalarm) break;
7942  if (p->radio) break;
7943  if (p->oprmode < 0) break;
7944  if (p->oprmode > 1)
7945  {
7946  struct dahdi_params par;
7947 
7948  memset(&par, 0, sizeof(par));
7949  if (ioctl(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par) != -1)
7950  {
7951  if (!par.rxisoffhook)
7952  {
7953  /* Make sure it stops ringing */
7954  dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
7955  dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RING);
7956  save_conference(p);
7957  tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
7958  }
7959  }
7960  break;
7961  }
7962  /* Remember last time we got a flash-hook */
7963  p->flashtime = ast_tvnow();
7964  switch (mysig) {
7965  case SIG_FXOLS:
7966  case SIG_FXOGS:
7967  case SIG_FXOKS:
7968  ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
7969  idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
7970 
7971  /* Cancel any running CallerID spill */
7972  ast_free(p->cidspill);
7973  p->cidspill = NULL;
7974  restore_conference(p);
7975  p->callwaitcas = 0;
7976 
7977  if (idx != SUB_REAL) {
7978  ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", idx, p->channel);
7979  goto winkflashdone;
7980  }
7981 
7982  if (p->subs[SUB_CALLWAIT].owner) {
7983  /* Swap to call-wait */
7985  tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
7986  p->owner = p->subs[SUB_REAL].owner;
7987  ast_debug(1, "Making %s the new owner\n", ast_channel_name(p->owner));
7990  p->subs[SUB_REAL].needanswer = 1;
7991  }
7992  p->callwaitingrepeat = 0;
7993  p->cidcwexpire = 0;
7994  p->cid_suppress_expire = 0;
7995  /* Start music on hold if appropriate */
7996  if (!p->subs[SUB_CALLWAIT].inthreeway) {
7998  }
7999  p->subs[SUB_CALLWAIT].needhold = 1;
8001  p->subs[SUB_REAL].needunhold = 1;
8002  } else if (!p->subs[SUB_THREEWAY].owner) {
8003  if (!p->threewaycalling) {
8004  /* Just send a flash if no 3-way calling */
8005  p->subs[SUB_REAL].needflash = 1;
8006  goto winkflashdone;
8007  } else if (!check_for_conference(p)) {
8008  ast_callid callid = 0;
8009  int callid_created;
8010  char cid_num[256];
8011  char cid_name[256];
8012 
8013  cid_num[0] = 0;
8014  cid_name[0] = 0;
8015  if (p->dahditrcallerid && p->owner) {
8017  && ast_channel_caller(p->owner)->id.number.str) {
8019  sizeof(cid_num));
8020  }
8022  && ast_channel_caller(p->owner)->id.name.str) {
8024  sizeof(cid_name));
8025  }
8026  }
8027  /* XXX This section needs much more error checking!!! XXX */
8028  /* Start a 3-way call if feasible */
8029  if (!((ast_channel_pbx(ast)) ||
8030  (ast_channel_state(ast) == AST_STATE_UP) ||
8031  (ast_channel_state(ast) == AST_STATE_RING))) {
8032  ast_debug(1, "Flash when call not up or ringing\n");
8033  goto winkflashdone;
8034  }
8035  if (alloc_sub(p, SUB_THREEWAY)) {
8036  ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
8037  goto winkflashdone;
8038  }
8039  callid_created = ast_callid_threadstorage_auto(&callid);
8040  /*
8041  * Make new channel
8042  *
8043  * We cannot hold the p or ast locks while creating a new
8044  * channel.
8045  */
8046  ast_mutex_unlock(&p->lock);
8047  ast_channel_unlock(ast);
8048  chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, NULL, NULL, callid);
8049  ast_channel_lock(ast);
8050  ast_mutex_lock(&p->lock);
8051  if (p->dahditrcallerid) {
8052  if (!p->origcid_num)
8053  p->origcid_num = ast_strdup(p->cid_num);
8054  if (!p->origcid_name)
8055  p->origcid_name = ast_strdup(p->cid_name);
8056  ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
8057  ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
8058  }
8059  /* Swap things around between the three-way and real call */
8061  /* Disable echo canceller for better dialing */
8062  dahdi_ec_disable(p);
8063  res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALRECALL);
8064  if (res)
8065  ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
8066  p->owner = chan;
8067  if (!chan) {
8068  ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
8069  } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
8070  ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
8071  res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
8072  dahdi_ec_enable(p);
8073  ast_hangup(chan);
8074  } else {
8075  ast_verb(3, "Started three way call on channel %d\n", p->channel);
8076 
8077  /* Start music on hold */
8079  p->subs[SUB_THREEWAY].needhold = 1;
8080  }
8081  ast_callid_threadstorage_auto_clean(callid, callid_created);
8082  }
8083  } else {
8084  /* Already have a 3 way call */
8085  if (p->subs[SUB_THREEWAY].inthreeway) {
8086  /* Call is already up, drop the last person */
8087  ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel);
8088  /* If the primary call isn't answered yet, use it */
8090  /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
8092  p->owner = p->subs[SUB_REAL].owner;
8093  }
8094  /* Drop the last call and stop the conference */
8095  ast_verb(3, "Dropping three-way call on %s\n", ast_channel_name(p->subs[SUB_THREEWAY].owner));
8097  p->subs[SUB_REAL].inthreeway = 0;
8098  p->subs[SUB_THREEWAY].inthreeway = 0;
8099  } else {
8100  /* Lets see what we're up to */
8101  if (((ast_channel_pbx(ast)) || (ast_channel_state(ast) == AST_STATE_UP)) &&
8102  (p->transfertobusy || (ast_channel_state(ast) != AST_STATE_BUSY))) {
8103  int otherindex = SUB_THREEWAY;
8104 
8105  ast_verb(3, "Building conference call with %s and %s\n",
8108  /* Put them in the threeway, and flip */
8109  p->subs[SUB_THREEWAY].inthreeway = 1;
8110  p->subs[SUB_REAL].inthreeway = 1;
8111  if (ast_channel_state(ast) == AST_STATE_UP) {
8113  otherindex = SUB_REAL;
8114  }
8115  if (p->subs[otherindex].owner) {
8116  ast_queue_unhold(p->subs[otherindex].owner);
8117  }
8118  p->subs[otherindex].needunhold = 1;
8119  p->owner = p->subs[SUB_REAL].owner;
8120  } else {
8121  ast_verb(3, "Dumping incomplete call on %s\n", ast_channel_name(p->subs[SUB_THREEWAY].owner));
8124  p->owner = p->subs[SUB_REAL].owner;
8125  if (p->subs[SUB_REAL].owner) {
8127  }
8128  p->subs[SUB_REAL].needunhold = 1;
8129  dahdi_ec_enable(p);
8130  }
8131  }
8132  }
8133 winkflashdone:
8134  dahdi_conf_update(p);
8135  break;
8136  case SIG_EM:
8137  case SIG_EM_E1:
8138  case SIG_FEATD:
8139  case SIG_SF:
8140  case SIG_SFWINK:
8141  case SIG_SF_FEATD:
8142  case SIG_FXSLS:
8143  case SIG_FXSGS:
8144  if (p->dialing)
8145  ast_debug(1, "Ignoring wink on channel %d\n", p->channel);
8146  else
8147  ast_debug(1, "Got wink in weird state %u on channel %d\n", ast_channel_state(ast), p->channel);
8148  break;
8149  case SIG_FEATDMF_TA:
8150  switch (p->whichwink) {
8151  case 0:
8152  ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", ast_channel_caller(p->owner)->ani2,
8154  ast_channel_caller(p->owner)->ani.number.str, ""));
8155  snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#",
8158  ast_channel_caller(p->owner)->ani.number.str, ""));
8159  break;
8160  case 1:
8161  ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
8162  break;
8163  case 2:
8164  ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
8165  return NULL;
8166  }
8167  p->whichwink++;
8168  /* Fall through */
8169  case SIG_FEATDMF:
8170  case SIG_E911:
8171  case SIG_FGC_CAMAMF:
8172  case SIG_FGC_CAMA:
8173  case SIG_FEATB:
8174  case SIG_SF_FEATDMF:
8175  case SIG_SF_FEATB:
8176  case SIG_EMWINK:
8177  /* FGD MF and EMWINK *Must* wait for wink */
8178  if (!ast_strlen_zero(p->dop.dialstr)) {
8179  res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
8180  if (res) {
8181  p->dop.dialstr[0] = '\0';
8182  return NULL;
8183  } else
8184  ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
8185  }
8186  p->dop.dialstr[0] = '\0';
8187  break;
8188  default:
8189  ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
8190  }
8191  break;
8192  case DAHDI_EVENT_HOOKCOMPLETE:
8193  if (p->inalarm) break;
8194  if ((p->radio || (p->oprmode < 0))) break;
8195  if (p->waitingfordt.tv_sec) break;
8196  switch (mysig) {
8197  case SIG_FXSLS: /* only interesting for FXS */
8198  case SIG_FXSGS:
8199  case SIG_FXSKS:
8200  case SIG_EM:
8201  case SIG_EM_E1:
8202  case SIG_EMWINK:
8203  case SIG_FEATD:
8204  case SIG_SF:
8205  case SIG_SFWINK:
8206  case SIG_SF_FEATD:
8207  if (!ast_strlen_zero(p->dop.dialstr)) {
8208  res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
8209  if (res) {
8210  p->dop.dialstr[0] = '\0';
8211  return NULL;
8212  } else
8213  ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
8214  }
8215  p->dop.dialstr[0] = '\0';
8216  p->dop.op = DAHDI_DIAL_OP_REPLACE;
8217  break;
8218  case SIG_FEATDMF:
8219  case SIG_FEATDMF_TA:
8220  case SIG_E911:
8221  case SIG_FGC_CAMA:
8222  case SIG_FGC_CAMAMF:
8223  case SIG_FEATB:
8224  case SIG_SF_FEATDMF:
8225  case SIG_SF_FEATB:
8226  ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
8227  break;
8228  default:
8229  break;
8230  }
8231  break;
8232  case DAHDI_EVENT_POLARITY:
8233  /*
8234  * If we get a Polarity Switch event, check to see
8235  * if we should change the polarity state and
8236  * mark the channel as UP or if this is an indication
8237  * of remote end disconnect.
8238  */
8239  if (p->polarity == POLARITY_IDLE) {
8240  p->polarity = POLARITY_REV;
8241  if (p->answeronpolarityswitch &&
8242  ((ast_channel_state(ast) == AST_STATE_DIALING) ||
8243  (ast_channel_state(ast) == AST_STATE_RINGING))) {
8244  ast_debug(1, "Answering on polarity switch!\n");
8246  if (p->hanguponpolarityswitch) {
8247  p->polaritydelaytv = ast_tvnow();
8248  }
8249  } else
8250  ast_debug(1, "Ignore switch to REVERSED Polarity on channel %d, state %u\n", p->channel, ast_channel_state(ast));
8251  }
8252  /* Removed else statement from here as it was preventing hangups from ever happening*/
8253  /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
8254  if (p->hanguponpolarityswitch &&
8255  (p->polarityonanswerdelay > 0) &&
8256  (p->polarity == POLARITY_REV) &&
8257  ((ast_channel_state(ast) == AST_STATE_UP) || (ast_channel_state(ast) == AST_STATE_RING)) ) {
8258  /* Added log_debug information below to provide a better indication of what is going on */
8259  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) );
8260 
8262  ast_debug(1, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
8264  p->polarity = POLARITY_IDLE;
8265  } else
8266  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));
8267 
8268  } else {
8269  p->polarity = POLARITY_IDLE;
8270  ast_debug(1, "Ignoring Polarity switch to IDLE on channel %d, state %u\n", p->channel, ast_channel_state(ast));
8271  }
8272  /* Added more log_debug information below to provide a better indication of what is going on */
8273  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) );
8274  break;
8275  default:
8276  ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel);
8277  }
8278  return &p->subs[idx].f;
8279 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
unsigned int outgoing
TRUE if we originated the call leg.
Definition: chan_dahdi.h:290
int outsigmod
Definition: chan_dahdi.h:149
static void swap_subs(struct dahdi_pvt *p, int a, int b)
Definition: chan_dahdi.c:4058
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
static void dahdi_handle_dtmf(struct ast_channel *ast, int idx, struct ast_frame **dest)
Definition: chan_dahdi.c:7231
void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm)
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define DAHDI_OVERLAPDIAL_INCOMING
Definition: sig_pri.h:255
Main Channel structure associated with a channel.
static void handle_clear_alarms(struct dahdi_pvt *p)
Definition: chan_dahdi.c:3537
struct dahdi_dialoperation dop
DAHDI dial operation command struct for ioctl() call.
Definition: chan_dahdi.h:641
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
unsigned int needflash
Definition: chan_dahdi.h:87
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: chan_dahdi.h:575
#define POLARITY_IDLE
Definition: chan_dahdi.c:792
static int dahdi_dial_str(struct dahdi_pvt *pvt, int operation, const char *dial_str)
Definition: chan_dahdi.c:1223
unsigned int dialing
TRUE if in the process of dialing digits or sending something.
Definition: chan_dahdi.h:234
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define SIG_FXOGS
Definition: chan_dahdi.h:735
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:563
#define SIG_SF_FEATDMF
Definition: chan_dahdi.h:740
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int dahdi_confmute(struct dahdi_pvt *p, int muted)
Definition: chan_dahdi.c:4939
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
void dahdi_ec_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4638
unsigned int needanswer
Definition: chan_dahdi.h:86
int ringt
Ring timeout timer??
Definition: chan_dahdi.h:556
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
#define SUB_THREEWAY
Definition: chan_dahdi.h:59
#define LOG_WARNING
Definition: logger.h:274
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:2042
static void * analog_ss_thread(void *data)
Definition: chan_dahdi.c:9512
#define SIG_EM
Definition: chan_dahdi.h:722
struct ast_channel * owner
Definition: chan_dahdi.h:127
unsigned int dahditrcallerid
TRUE if we should use the callerid from incoming call on dahdi transfer.
Definition: chan_dahdi.h:365
#define SIG_FXOKS
Definition: chan_dahdi.h:736
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define SIG_FEATB
Definition: chan_dahdi.h:726
void * sig_pvt
Definition: chan_dahdi.h:709
char * str
Subscriber name (Malloced)
Definition: channel.h:265
static int unalloc_sub(struct dahdi_pvt *p, int x)
Definition: chan_dahdi.c:4204
unsigned int transfertobusy
TRUE if allowed to flash-transfer to busy channels.
Definition: chan_dahdi.h:370
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
unsigned int ast_callid
Definition: logger.h:87
#define SIG_FEATDMF_TA
Definition: chan_dahdi.h:728
void dahdi_ec_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4710
static int attempt_transfer(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7145
#define ast_mutex_lock(a)
Definition: lock.h:187
int whichwink
Definition: chan_dahdi.h:642
char * origcid_num
Definition: chan_dahdi.h:491
static struct test_val c
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
static int alloc_sub(struct dahdi_pvt *p, int x)
Definition: chan_dahdi.c:4167
#define CALLPROGRESS_PROGRESS
Definition: chan_dahdi.c:558
#define NULL
Definition: resample.c:96
int callwaitingrepeat
Definition: chan_dahdi.h:546
void dahdi_conf_update(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4583
struct ast_frame f
Definition: chan_dahdi.h:82
struct dahdi_pvt * oprpeer
Definition: chan_dahdi.h:151
int ringt_base
Ring timeout base.
Definition: chan_dahdi.h:561
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
#define ast_verb(level,...)
Definition: logger.h:463
unsigned int needhold
Definition: chan_dahdi.h:88
struct ast_frame_subclass subclass
#define SIG_SF
Definition: chan_dahdi.h:737
int oprmode
Definition: chan_dahdi.h:150
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
#define ast_strlen_zero(foo)
Definition: strings.h:52
char cid_name[AST_MAX_EXTENSION]
Caller ID name from an incoming call.
Definition: chan_dahdi.h:488
char finaldial[64]
Second part of SIG_FEATDMF_TA wink operation.
Definition: chan_dahdi.h:644
#define SIG_EMWINK
Definition: chan_dahdi.h:723
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
static void handle_alarms(struct dahdi_pvt *p, int alms)
Definition: chan_dahdi.c:7364
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:183
static int has_voicemail(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5033
#define SIG_FGC_CAMAMF
Definition: chan_dahdi.h:730
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int polarity
Current line interface polarity. POLARITY_IDLE, POLARITY_REV.
Definition: chan_dahdi.h:681
unsigned int hanguponpolarityswitch
TRUE if the call will be considered "hung up" on a polarity reversal.
Definition: chan_dahdi.h:261
unsigned int transfer
TRUE if call transfer is enabled.
Definition: chan_dahdi.h:339
unsigned int echobreak
XXX BOOLEAN Purpose???
Definition: chan_dahdi.h:240
static int dahdi_ring_phone(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7101
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:428
void ast_channel_rings_set(struct ast_channel *chan, int value)
const char * src
unsigned int needunhold
Definition: chan_dahdi.h:89
char echorest[20]
Filled with &#39;w&#39;. XXX Purpose??
Definition: chan_dahdi.h:589
struct timeval flashtime
Definition: chan_dahdi.h:637
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
#define SIG_FEATD
Definition: chan_dahdi.h:724
int echotraining
Echo training time. 0 = disabled.
Definition: chan_dahdi.h:587
ast_mutex_t lock
Definition: chan_dahdi.h:125
#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:85
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
#define MIN_MS_SINCE_FLASH
Definition: chan_dahdi.c:682
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
void sig_ss7_set_alarm(struct sig_ss7_chan *p, int in_alarm)
struct ast_channel * owner
Definition: chan_dahdi.h:79
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
static void dahdi_train_ec(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4693
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1191
#define SIG_SS7
Definition: chan_dahdi.h:750
#define SIG_E911
Definition: chan_dahdi.h:727
unsigned int inthreeway
Definition: chan_dahdi.h:91
struct timeval waitingfordt
Definition: chan_dahdi.h:636
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
char cid_num[AST_MAX_EXTENSION]
Caller ID number from an incoming call.
Definition: chan_dahdi.h:479
#define POLARITY_REV
Definition: chan_dahdi.c:793
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:434
int errno
unsigned int needringing
Definition: chan_dahdi.h:83
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SIG_FXSGS
Definition: chan_dahdi.h:732
#define LOG_NOTICE
Definition: logger.h:263
char * origcid_name
Definition: chan_dahdi.h:492
static int restore_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5002
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define SIG_SF_FEATD
Definition: chan_dahdi.h:739
#define ast_free(a)
Definition: astmm.h:182
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922
static int get_alarms(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7204
static int dahdi_get_event(int fd)
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition: chan_dahdi.c:652
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
Definition: lock.h:352
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
unsigned int threewaycalling
TRUE if three way calling is enabled.
Definition: chan_dahdi.h:330
static const char * event2str(int event)
Definition: chan_dahdi.c:4382
#define SIG_SFWINK
Definition: chan_dahdi.h:738
#define SIG_FGC_CAMA
Definition: chan_dahdi.h:729
#define SIG_SF_FEATB
Definition: chan_dahdi.h:741
#define SIG_MFCR2
Definition: chan_dahdi.h:753
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
#define SIG_FXSKS
Definition: chan_dahdi.h:733
int fake_event
Holding place for event injected from outside normal operation.
Definition: chan_dahdi.h:667
struct ast_frame ast_null_frame
Definition: main/frame.c:79
unsigned int confirmanswer
TRUE if to wait for a DTMF digit to confirm answer.
Definition: chan_dahdi.h:221
static int save_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4976
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
unsigned int echocanon
TRUE if echo cancellation is turned on.
Definition: chan_dahdi.h:248
const char * ast_channel_name(const struct ast_channel *chan)
static int check_for_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7178
int cidcwexpire
Definition: chan_dahdi.h:547
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:2020
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
int cid_suppress_expire
Definition: chan_dahdi.h:548
void sig_pri_dial_complete(struct sig_pri_chan *pvt, struct ast_channel *ast)
#define SIG_FXSLS
Definition: chan_dahdi.h:731
unsigned int dialednone
TRUE if analog type line dialed no digits in Dial()
Definition: chan_dahdi.h:229
Data structure associated with a single frame of data.
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
struct timeval polaritydelaytv
Start delay time if polarityonanswerdelay is nonzero.
Definition: chan_dahdi.h:674
#define DLA_UNLOCK(lock)
Deadlock avoidance unlock.
Definition: lock.h:408
union ast_frame::@263 data
int polarityonanswerdelay
Minimal time period (ms) between the answer polarity switch and hangup polarity switch.
Definition: chan_dahdi.h:672
enum ast_frame_type frametype
#define ast_channel_trylock(chan)
Definition: channel.h:2947
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
#define SIG_FXOLS
Definition: chan_dahdi.h:734
#define sig2str
Definition: chan_dahdi.c:4455
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
#define SIG_FEATDMF
Definition: chan_dahdi.h:725
int callprogress
Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
Definition: chan_dahdi.h:604
unsigned int inalarm
TRUE if in an alarm condition.
Definition: chan_dahdi.h:286
int channel
Definition: chan_dahdi.h:538
#define DLA_LOCK(lock)
Deadlock avoidance lock.
Definition: lock.h:427
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
char dialdest[256]
Delayed dialing for E911. Overlap digits for ISDN.
Definition: chan_dahdi.h:658
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:9153
#define CANPROGRESSDETECT(p)
Definition: chan_dahdi.c:594
#define SIG_EM_E1
Definition: chan_dahdi.h:742
unsigned int pulsedial
TRUE if a pulsed digit was detected. (Pulse dial phone detected)
Definition: chan_dahdi.h:318
char mohsuggest[MAX_MUSICCLASS]
Suggested music-on-hold class for peer channel to use for calls.
Definition: chan_dahdi.h:470
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define SUB_CALLWAIT
Definition: chan_dahdi.h:58
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ dahdi_hangup()

static int dahdi_hangup ( struct ast_channel ast)
static

Definition at line 5992 of file chan_dahdi.c.

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::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, 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, 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.

Referenced by dahdi_chan_conf_default().

5993 {
5994  int res = 0;
5995  int idx,x;
5996  int law;
5997  /*static int restore_gains(struct dahdi_pvt *p);*/
5998  struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
5999  struct dahdi_params par;
6000 
6001  ast_debug(1, "dahdi_hangup(%s)\n", ast_channel_name(ast));
6002  if (!ast_channel_tech_pvt(ast)) {
6003  ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
6004  return 0;
6005  }
6006 
6007  ast_mutex_lock(&p->lock);
6008  p->exten[0] = '\0';
6009  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
6010  dahdi_confmute(p, 0);
6011  restore_gains(p);
6012  p->ignoredtmf = 0;
6013  p->waitingfordt.tv_sec = 0;
6014 
6015  res = analog_hangup(p->sig_pvt, ast);
6016  revert_fax_buffers(p, ast);
6017 
6018  goto hangup_out;
6019  } else {
6020  p->cid_num[0] = '\0';
6021  p->cid_name[0] = '\0';
6022  p->cid_subaddr[0] = '\0';
6023  }
6024 
6025 #if defined(HAVE_PRI)
6026  if (dahdi_sig_pri_lib_handles(p->sig)) {
6027  x = 1;
6028  ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
6029 
6030  dahdi_confmute(p, 0);
6031  p->muting = 0;
6032  restore_gains(p);
6033  if (p->dsp) {
6034  ast_dsp_free(p->dsp);
6035  p->dsp = NULL;
6036  }
6037  p->ignoredtmf = 0;
6038 
6039  /* Real channel, do some fixup */
6040  p->subs[SUB_REAL].owner = NULL;
6041  p->subs[SUB_REAL].needbusy = 0;
6042  dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
6043 
6044  p->owner = NULL;
6045  p->cid_tag[0] = '\0';
6046  p->ringt = 0;/* Probably not used in this mode. Reset anyway. */
6047  p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */
6048  p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */
6049  p->outgoing = 0;
6050  p->digital = 0;
6051  p->faxhandled = 0;
6052  p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */
6053 
6054  revert_fax_buffers(p, ast);
6055 
6056  p->law = p->law_default;
6057  law = p->law_default;
6058  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
6059  if (res < 0) {
6060  ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n",
6061  p->channel, strerror(errno));
6062  }
6063 
6064  sig_pri_hangup(p->sig_pvt, ast);
6065 
6066  tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
6067  dahdi_ec_disable(p);
6068 
6069  x = 0;
6070  ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0);
6071  p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */
6072 
6073  p->rdnis[0] = '\0';
6074  dahdi_conf_update(p);
6075  reset_conf(p);
6076 
6077  /* Restore data mode */
6078  x = 0;
6079  ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
6080 
6081  if (num_restart_pending == 0) {
6082  restart_monitor();
6083  }
6084  goto hangup_out;
6085  }
6086 #endif /* defined(HAVE_PRI) */
6087 
6088 #if defined(HAVE_SS7)
6089  if (p->sig == SIG_SS7) {
6090  x = 1;
6091  ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
6092 
6093  dahdi_confmute(p, 0);
6094  p->muting = 0;
6095  restore_gains(p);
6096  if (p->dsp) {
6097  ast_dsp_free(p->dsp);
6098  p->dsp = NULL;
6099  }
6100  p->ignoredtmf = 0;
6101 
6102  /* Real channel, do some fixup */
6103  p->subs[SUB_REAL].owner = NULL;
6104  p->subs[SUB_REAL].needbusy = 0;
6105  dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
6106 
6107  p->owner = NULL;
6108  p->ringt = 0;/* Probably not used in this mode. Reset anyway. */
6109  p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */
6110  p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */
6111  p->outgoing = 0;
6112  p->digital = 0;
6113  p->faxhandled = 0;
6114  p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */
6115 
6116  revert_fax_buffers(p, ast);
6117 
6118  p->law = p->law_default;
6119  law = p->law_default;
6120  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
6121  if (res < 0) {
6122  ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n",
6123  p->channel, strerror(errno));
6124  }
6125 
6126  sig_ss7_hangup(p->sig_pvt, ast);
6127 
6128  tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
6129  dahdi_ec_disable(p);
6130 
6131  x = 0;
6132  ast_channel_setoption(ast, AST_OPTION_TDD, &x, sizeof(char), 0);
6133  p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */
6134 
6135  dahdi_conf_update(p);
6136  reset_conf(p);
6137 
6138  /* Restore data mode */
6139  x = 0;
6140  ast_channel_setoption(ast, AST_OPTION_AUDIO_MODE, &x, sizeof(char), 0);
6141 
6142  if (num_restart_pending == 0) {
6143  restart_monitor();
6144  }
6145  goto hangup_out;
6146  }
6147 #endif /* defined(HAVE_SS7) */
6148 
6149  idx = dahdi_get_index(ast, p, 1);
6150 
6151  dahdi_confmute(p, 0);
6152  p->muting = 0;
6153  restore_gains(p);
6154  if (p->origcid_num) {
6155  ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
6156  ast_free(p->origcid_num);
6157  p->origcid_num = NULL;
6158  }
6159  if (p->origcid_name) {
6160  ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
6161  ast_free(p->origcid_name);
6162  p->origcid_name = NULL;
6163  }
6164  if (p->dsp)
6166 
6167  ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
6168  p->channel, idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
6169  p->ignoredtmf = 0;
6170 
6171  if (idx > -1) {
6172  /* Real channel, do some fixup */
6173  p->subs[idx].owner = NULL;
6174  p->subs[idx].needanswer = 0;
6175  p->subs[idx].needflash = 0;
6176  p->subs[idx].needringing = 0;
6177  p->subs[idx].needbusy = 0;
6178  p->subs[idx].needcongestion = 0;
6179  p->subs[idx].linear = 0;
6180  p->polarity = POLARITY_IDLE;
6181  dahdi_setlinear(p->subs[idx].dfd, 0);
6182  if (idx == SUB_REAL) {
6183  if ((p->subs[SUB_CALLWAIT].dfd > -1) && (p->subs[SUB_THREEWAY].dfd > -1)) {
6184  ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n");
6185  if (p->subs[SUB_CALLWAIT].inthreeway) {
6186  /* We had flipped over to answer a callwait and now it's gone */
6187  ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n");
6188  /* Move to the call-wait, but un-own us until they flip back. */
6191  p->owner = NULL;
6192  } else {
6193  /* The three way hung up, but we still have a call wait */
6194  ast_debug(1, "We were in the threeway and have a callwait still. Ditching the threeway.\n");
6197  if (p->subs[SUB_REAL].inthreeway) {
6198  /* This was part of a three way call. Immediately make way for
6199  another call */
6200  ast_debug(1, "Call was complete, setting owner to former third call\n");
6201  p->owner = p->subs[SUB_REAL].owner;
6202  } else {
6203  /* This call hasn't been completed yet... Set owner to NULL */
6204  ast_debug(1, "Call was incomplete, setting owner to NULL\n");
6205  p->owner = NULL;
6206  }
6207  p->subs[SUB_REAL].inthreeway = 0;
6208  }
6209  } else if (p->subs[SUB_CALLWAIT].dfd > -1) {
6210  /* Move to the call-wait and switch back to them. */
6213  p->owner = p->subs[SUB_REAL].owner;
6215  p->subs[SUB_REAL].needanswer = 1;
6217  } else if (p->subs[SUB_THREEWAY].dfd > -1) {
6220  if (p->subs[SUB_REAL].inthreeway) {
6221  /* This was part of a three way call. Immediately make way for
6222  another call */
6223  ast_debug(1, "Call was complete, setting owner to former third call\n");
6224  p->owner = p->subs[SUB_REAL].owner;
6225  } else {
6226  /* This call hasn't been completed yet... Set owner to NULL */
6227  ast_debug(1, "Call was incomplete, setting owner to NULL\n");
6228  p->owner = NULL;
6229  }
6230  p->subs[SUB_REAL].inthreeway = 0;
6231  }
6232  } else if (idx == SUB_CALLWAIT) {
6233  /* Ditch the holding callwait call, and immediately make it availabe */
6234  if (p->subs[SUB_CALLWAIT].inthreeway) {
6235  /* This is actually part of a three way, placed on hold. Place the third part
6236  on music on hold now */
6237  if (p->subs[SUB_THREEWAY].owner) {
6239  }
6240  p->subs[SUB_THREEWAY].inthreeway = 0;
6241  /* Make it the call wait now */
6244  } else
6246  } else if (idx == SUB_THREEWAY) {
6247  if (p->subs[SUB_CALLWAIT].inthreeway) {
6248  /* The other party of the three way call is currently in a call-wait state.
6249  Start music on hold for them, and take the main guy out of the third call */
6250  if (p->subs[SUB_CALLWAIT].owner) {
6252  }
6253  p->subs[SUB_CALLWAIT].inthreeway = 0;
6254  }
6255  p->subs[SUB_REAL].inthreeway = 0;
6256  /* If this was part of a three way call index, let us make
6257  another three way call */
6259  } else {
6260  /* This wasn't any sort of call, but how are we an index? */
6261  ast_log(LOG_WARNING, "Index found but not any type of call?\n");
6262  }
6263  }
6264 
6265  if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
6266  p->owner = NULL;
6267  p->ringt = 0;
6268  p->distinctivering = 0;
6269  p->confirmanswer = 0;
6270  p->outgoing = 0;
6271  p->digital = 0;
6272  p->faxhandled = 0;
6273  p->pulsedial = 0;
6274  if (p->dsp) {
6275  ast_dsp_free(p->dsp);
6276  p->dsp = NULL;
6277  }
6278 
6279  revert_fax_buffers(p, ast);
6280 
6281  p->law = p->law_default;
6282  law = p->law_default;
6283  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
6284  if (res < 0)
6285  ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
6286  /* Perform low level hangup if no owner left */
6287 #ifdef HAVE_OPENR2
6288  if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) {
6289  ast_debug(1, "disconnecting MFC/R2 call on chan %d\n", p->channel);
6290  /* If it's an incoming call, check the mfcr2_forced_release setting */
6291  if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) {
6292  dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE);
6293  } else {
6294  const char *r2causestr = pbx_builtin_getvar_helper(ast, "MFCR2_CAUSE");
6295  int r2cause_user = r2causestr ? atoi(r2causestr) : 0;
6296  openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user)
6297  : dahdi_ast_cause_to_r2_cause(ast_channel_hangupcause(ast));
6298  dahdi_r2_disconnect_call(p, r2cause);
6299  }
6300  } else if (p->mfcr2call) {
6301  ast_debug(1, "Clearing call request on channel %d\n", p->channel);
6302  /* since ast_request() was called but not ast_call() we have not yet dialed
6303  and the openr2 stack will not call on_call_end callback, we need to unset
6304  the mfcr2call flag and bump the monitor count so the monitor thread can take
6305  care of this channel events from now on */
6306  p->mfcr2call = 0;
6307  }
6308 #endif
6309  switch (p->sig) {
6310  case SIG_SS7:
6311  case SIG_MFCR2:
6313  case 0:
6314  break;
6315  default:
6316  res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
6317  break;
6318  }
6319  if (res < 0) {
6320  ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast_channel_name(ast));
6321  }
6322  switch (p->sig) {
6323  case SIG_FXOGS:
6324  case SIG_FXOLS:
6325  case SIG_FXOKS:
6326  memset(&par, 0, sizeof(par));
6327  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
6328  if (!res) {
6329  struct analog_pvt *analog_p = p->sig_pvt;
6330 #if 0
6331  ast_debug(1, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
6332 #endif
6333  /* If they're off hook, try playing congestion */
6334  if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
6335  tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
6336  else
6337  tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
6338  analog_p->fxsoffhookstate = par.rxisoffhook;
6339  }
6340  break;
6341  case SIG_FXSGS:
6342  case SIG_FXSLS:
6343  case SIG_FXSKS:
6344  /* Make sure we're not made available for at least two seconds assuming
6345  we were actually used for an inbound or outbound call. */
6346  if (ast_channel_state(ast) != AST_STATE_RESERVED) {
6347  time(&p->guardtime);
6348  p->guardtime += 2;
6349  }
6350  break;
6351  default:
6352  tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
6353  break;
6354  }
6355  if (p->sig)
6356  dahdi_ec_disable(p);
6357  x = 0;
6358  ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
6359  ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
6360  p->didtdd = 0;
6361  p->callwaitcas = 0;
6362  p->callwaiting = p->permcallwaiting;
6364  p->waitingfordt.tv_sec = 0;
6365  p->dialing = 0;
6366  p->rdnis[0] = '\0';
6367  dahdi_conf_update(p);
6368  reset_conf(p);
6369  /* Restore data mode */
6370  switch (p->sig) {
6372  case SIG_SS7:
6373  x = 0;
6374  ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
6375  break;
6376  default:
6377  break;
6378  }
6379  if (num_restart_pending == 0)
6380  restart_monitor();
6381  }
6382 
6383  p->callwaitingrepeat = 0;
6384  p->cidcwexpire = 0;
6385  p->cid_suppress_expire = 0;
6386  p->oprmode = 0;
6387 hangup_out:
6389  ast_free(p->cidspill);
6390  p->cidspill = NULL;
6391 
6392  ast_mutex_unlock(&p->lock);
6393  ast_verb(3, "Hungup '%s'\n", ast_channel_name(ast));
6394 
6396  if (p->restartpending) {
6398  }
6399 
6400  if (p->destroy) {
6401  destroy_channel(p, 0);
6402  }
6404 
6406  return 0;
6407 }
unsigned int outgoing
TRUE if we originated the call leg.
Definition: chan_dahdi.h:290
unsigned int digital
TRUE if the transfer capability of the call is digital.
Definition: chan_dahdi.h:236
static void swap_subs(struct dahdi_pvt *p, int a, int b)
Definition: chan_dahdi.c:4058
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
int dtmfrelax
Definition: chan_dahdi.h:665
char cid_subaddr[AST_MAX_EXTENSION]
Caller ID subaddress from an incoming call.
Definition: chan_dahdi.h:490
unsigned int permhidecallerid
TRUE if the outgoing caller ID is blocked/restricted/hidden.
Definition: chan_dahdi.h:301
unsigned int needflash
Definition: chan_dahdi.h:87
static int num_restart_pending
Definition: chan_dahdi.c:645
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
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:202
int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: chan_dahdi.h:575
#define POLARITY_IDLE
Definition: chan_dahdi.c:792
unsigned int dialing
TRUE if in the process of dialing digits or sending something.
Definition: chan_dahdi.h:234
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define SIG_FXOGS
Definition: chan_dahdi.h:735
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int dahdi_confmute(struct dahdi_pvt *p, int muted)
Definition: chan_dahdi.c:4939
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
int analog_hangup(struct analog_pvt *p, struct ast_channel *ast)
Definition: sig_analog.c:1251
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
unsigned int needanswer
Definition: chan_dahdi.h:86
int ringt
Ring timeout timer??
Definition: chan_dahdi.h:556
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
#define SUB_THREEWAY
Definition: chan_dahdi.h:59
#define LOG_WARNING
Definition: logger.h:274
struct ast_channel * owner
Definition: chan_dahdi.h:127
int law_default
Default call PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:507
static void destroy_channel(struct dahdi_pvt *cur, int now)
Definition: chan_dahdi.c:5649
#define SIG_FXOKS
Definition: chan_dahdi.h:736
ast_channel_state
ast_channel states
Definition: channelstate.h:35
void * sig_pvt
Definition: chan_dahdi.h:709
static int unalloc_sub(struct dahdi_pvt *p, int x)
Definition: chan_dahdi.c:4204
void dahdi_ec_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4710
#define ast_mutex_lock(a)
Definition: lock.h:187
char * origcid_num
Definition: chan_dahdi.h:491
#define AST_OPTION_TDD
int law
Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:509
#define NULL
Definition: resample.c:96
int callwaitingrepeat
Definition: chan_dahdi.h:546
void dahdi_conf_update(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4583
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:7522
unsigned int restartpending
Definition: chan_dahdi.h:319
#define ast_verb(level,...)
Definition: logger.h:463
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 oprmode
Definition: chan_dahdi.h:150
int sig_pri_hangup(struct sig_pri_chan *p, struct ast_channel *ast)
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
char cid_name[AST_MAX_EXTENSION]
Caller ID name from an incoming call.
Definition: chan_dahdi.h:488
static int restart_monitor(void)
Definition: chan_dahdi.c:11770
unsigned int didtdd
Definition: chan_dahdi.h:227
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int polarity
Current line interface polarity. POLARITY_IDLE, POLARITY_REV.
Definition: chan_dahdi.h:681
struct ast_module * self
Definition: module.h:342
static int reset_conf(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4569
ast_mutex_t lock
Definition: chan_dahdi.h:125
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
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:296
struct ast_channel * owner
Definition: chan_dahdi.h:79
static int restore_gains(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4909
unsigned int linear
Definition: chan_dahdi.h:90
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1191
char cid_tag[AST_MAX_EXTENSION]
Caller ID tag from incoming call.
Definition: chan_dahdi.h:484
#define SIG_SS7
Definition: chan_dahdi.h:750
unsigned int inthreeway
Definition: chan_dahdi.h:91
struct timeval waitingfordt
Definition: chan_dahdi.h:636
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
unsigned int destroy
TRUE if the channel is to be destroyed on hangup. (Used by pseudo channels.)
Definition: chan_dahdi.h:226
unsigned int faxhandled
TRUE if a fax tone has already been handled.
Definition: chan_dahdi.h:250
char cid_num[AST_MAX_EXTENSION]
Caller ID number from an incoming call.
Definition: chan_dahdi.h:479
int errno
unsigned int needringing
Definition: chan_dahdi.h:83
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SIG_FXSGS
Definition: chan_dahdi.h:732
char * origcid_name
Definition: chan_dahdi.h:492
char exten[AST_MAX_EXTENSION]
Extension to use in the dialplan.
Definition: chan_dahdi.h:455
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
int muting
TRUE if confrence is muted.
Definition: chan_dahdi.h:708
int distinctivering
Definition: chan_dahdi.h:664
#define ast_free(a)
Definition: astmm.h:182
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922
#define AST_OPTION_AUDIO_MODE
#define SIG_MFCR2
Definition: chan_dahdi.h:753
unsigned int ignoredtmf
TRUE if DTMF detection is disabled.
Definition: chan_dahdi.h:278
#define SIG_FXSKS
Definition: chan_dahdi.h:733
static int dahdi_setlinear(int dfd, int linear)
Definition: chan_dahdi.c:4161
unsigned int confirmanswer
TRUE if to wait for a DTMF digit to confirm answer.
Definition: chan_dahdi.h:221
int sig_ss7_hangup(struct sig_ss7_chan *p, struct ast_channel *ast)
int ast_channel_hangupcause(const struct ast_channel *chan)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
unsigned int needcongestion
Definition: chan_dahdi.h:85
const char * ast_channel_name(const struct ast_channel *chan)
unsigned int needbusy
Definition: chan_dahdi.h:84
int cidcwexpire
Definition: chan_dahdi.h:547
int cid_suppress_expire
Definition: chan_dahdi.h:548
#define SIG_FXSLS
Definition: chan_dahdi.h:731
unsigned int hidecallerid
TRUE if the outgoing caller ID is blocked/hidden.
Definition: chan_dahdi.h:270
int fxsoffhookstate
Definition: sig_analog.h:275
#define AST_OPTION_TONE_VERIFY
#define SIG_FXOLS
Definition: chan_dahdi.h:734
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
char rdnis[AST_MAX_EXTENSION]
Redirecting Directory Number Information Service (RDNIS) number.
Definition: chan_dahdi.h:498
time_t guardtime
Definition: chan_dahdi.h:540
static int revert_fax_buffers(struct dahdi_pvt *p, struct ast_channel *ast)
Definition: chan_dahdi.c:5970
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
int channel
Definition: chan_dahdi.h:538
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1844
unsigned int pulsedial
TRUE if a pulsed digit was detected. (Pulse dial phone detected)
Definition: chan_dahdi.h:318
char mohsuggest[MAX_MUSICCLASS]
Suggested music-on-hold class for peer channel to use for calls.
Definition: chan_dahdi.h:470
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define SUB_CALLWAIT
Definition: chan_dahdi.h:58

◆ dahdi_iflist_extract()

static void dahdi_iflist_extract ( struct dahdi_pvt pvt)
static

Definition at line 5332 of file chan_dahdi.c.

References ast_debug, ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, DAHDI_IFLIST_NONE, dahdi_pvt::lock, sig_ss7_linkset::lock, sig_pri_span::lock, dahdi_pvt::next, sig_pri_span::no_b_chan_end, sig_pri_span::no_b_chan_iflist, NULL, sig_ss7_linkset::numchans, sig_pri_span::numchans, dahdi_pvt::prev, sig_pri_span::pri, sig_ss7_linkset::pvts, sig_pri_span::pvts, dahdi_pvt::sig_pvt, sig_ss7_linkset::ss7, and dahdi_pvt::which_iflist.

Referenced by destroy_dahdi_pvt().

5333 {
5334  /* Extract from the forward chain. */
5335  if (pvt->prev) {
5336  pvt->prev->next = pvt->next;
5337  } else if (iflist == pvt) {
5338  /* Node is at the head of the list. */
5339  iflist = pvt->next;
5340  }
5341 
5342  /* Extract from the reverse chain. */
5343  if (pvt->next) {
5344  pvt->next->prev = pvt->prev;
5345  } else if (ifend == pvt) {
5346  /* Node is at the end of the list. */
5347  ifend = pvt->prev;
5348  }
5349 
5350  /* Node is no longer in the list. */
5352  pvt->prev = NULL;
5353  pvt->next = NULL;
5354 }
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
#define NULL
Definition: resample.c:96
static struct dahdi_pvt * ifend
Definition: chan_dahdi.c:802
struct dahdi_pvt * prev
Definition: chan_dahdi.h:169
enum DAHDI_IFLIST which_iflist
Definition: chan_dahdi.h:167
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801

◆ dahdi_iflist_insert()

static void dahdi_iflist_insert ( struct dahdi_pvt pvt)
static

Definition at line 5282 of file chan_dahdi.c.

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

Referenced by duplicate_pseudo(), and mkintf().

5283 {
5284  struct dahdi_pvt *cur;
5285 
5287 
5288  /* Find place in middle of list for the new interface. */
5289  for (cur = iflist; cur; cur = cur->next) {
5290  if (pvt->channel < cur->channel) {
5291  /* New interface goes before the current interface. */
5292  pvt->prev = cur->prev;
5293  pvt->next = cur;
5294  if (cur->prev) {
5295  /* Insert into the middle of the list. */
5296  cur->prev->next = pvt;
5297  } else {
5298  /* Insert at head of list. */
5299  iflist = pvt;
5300  }
5301  cur->prev = pvt;
5302  return;
5303  }
5304  }
5305 
5306  /* New interface goes onto the end of the list */
5307  pvt->prev = ifend;
5308  pvt->next = NULL;
5309  if (ifend) {
5310  ifend->next = pvt;
5311  }
5312  ifend = pvt;
5313  if (!iflist) {
5314  /* List was empty */
5315  iflist = pvt;
5316  }
5317 }
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
#define NULL
Definition: resample.c:96
static struct dahdi_pvt * ifend
Definition: chan_dahdi.c:802
struct dahdi_pvt * prev
Definition: chan_dahdi.h:169
enum DAHDI_IFLIST which_iflist
Definition: chan_dahdi.h:167
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
int channel
Definition: chan_dahdi.h:538

◆ dahdi_indicate()

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

Definition at line 8975 of file chan_dahdi.c.

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, create_channel_name(), 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_chan_conf_default(), and dahdi_fixup().

8976 {
8977  struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
8978  int res=-1;
8979  int idx;
8980  int func = DAHDI_FLASH;
8981 
8982  ast_mutex_lock(&p->lock);
8983  ast_debug(1, "Requested indication %d on channel %s\n", condition, ast_channel_name(chan));
8984  switch (p->sig) {
8985 #if defined(HAVE_PRI)
8987  res = sig_pri_indicate(p->sig_pvt, chan, condition, data, datalen);
8988  ast_mutex_unlock(&p->lock);
8989  return res;
8990 #endif /* defined(HAVE_PRI) */
8991 #if defined(HAVE_SS7)
8992  case SIG_SS7:
8993  res = sig_ss7_indicate(p->sig_pvt, chan, condition, data, datalen);
8994  ast_mutex_unlock(&p->lock);
8995  return res;
8996 #endif /* defined(HAVE_SS7) */
8997  default:
8998  break;
8999  }
9000 #ifdef HAVE_OPENR2
9001  if (p->mfcr2 && !p->mfcr2_call_accepted) {
9002  ast_mutex_unlock(&p->lock);
9003  /* if this is an R2 call and the call is not yet accepted, we don't want the
9004  tone indications to mess up with the MF tones */
9005  return 0;
9006  }
9007 #endif
9008  idx = dahdi_get_index(chan, p, 0);
9009  if (idx == SUB_REAL) {
9010  switch (condition) {
9011  case AST_CONTROL_BUSY:
9012  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_BUSY);
9013  break;
9014  case AST_CONTROL_RINGING:
9015  res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_RINGTONE);
9016 
9017  if (ast_channel_state(chan) != AST_STATE_UP) {
9018  if ((ast_channel_state(chan) != AST_STATE_RING) ||
9019  ((p->sig != SIG_FXSKS) &&
9020  (p->sig != SIG_FXSLS) &&
9021  (p->sig != SIG_FXSGS)))
9023  }
9024  break;
9026  ast_debug(1, "Received AST_CONTROL_INCOMPLETE on %s\n", ast_channel_name(chan));
9027  /* act as a progress or proceeding, allowing the caller to enter additional numbers */
9028  res = 0;
9029  break;
9031  ast_debug(1, "Received AST_CONTROL_PROCEEDING on %s\n", ast_channel_name(chan));
9032  /* don't continue in ast_indicate */
9033  res = 0;
9034  break;
9035  case AST_CONTROL_PROGRESS:
9036  ast_debug(1, "Received AST_CONTROL_PROGRESS on %s\n", ast_channel_name(chan));
9037  /* don't continue in ast_indicate */
9038  res = 0;
9039  break;
9041  /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
9042  switch (ast_channel_hangupcause(chan)) {
9043  case AST_CAUSE_USER_BUSY:
9045  case 0:/* Cause has not been set. */
9046  /* Supply a more appropriate cause. */
9048  break;
9049  default:
9050  break;
9051  }
9052  break;
9053  case AST_CONTROL_HOLD:
9054  ast_moh_start(chan, data, p->mohinterpret);
9055  break;
9056  case AST_CONTROL_UNHOLD:
9057  ast_moh_stop(chan);
9058  break;
9059  case AST_CONTROL_RADIO_KEY:
9060  if (p->radio)
9061  res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
9062  res = 0;
9063  break;
9065  if (p->radio)
9066  res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_RINGOFF);
9067  res = 0;
9068  break;
9069  case AST_CONTROL_FLASH:
9070  /* flash hookswitch */
9071  if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
9072  /* Clear out the dial buffer */
9073  p->dop.dialstr[0] = '\0';
9074  if ((ioctl(p->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
9075  ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
9076  ast_channel_name(chan), strerror(errno));
9077  } else
9078  res = 0;
9079  } else
9080  res = 0;
9081  break;
9082  case AST_CONTROL_SRCUPDATE:
9083  res = 0;
9084  break;
9085  case -1:
9086  res = tone_zone_play_tone(p->subs[idx].dfd, -1);
9087  break;
9088  }
9089  } else {
9090  res = 0;
9091  }
9092  ast_mutex_unlock(&p->lock);
9093  return res;
9094 }
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
struct dahdi_dialoperation dop
DAHDI dial operation command struct for ioctl() call.
Definition: chan_dahdi.h:641
int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
int sig_ss7_indicate(struct sig_ss7_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define LOG_WARNING
Definition: logger.h:274
ast_channel_state
ast_channel states
Definition: channelstate.h:35
void * sig_pvt
Definition: chan_dahdi.h:709
#define ast_mutex_lock(a)
Definition: lock.h:187
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ISTRUNK(p)
Definition: chan_dahdi.c:590
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
ast_mutex_t lock
Definition: chan_dahdi.h:125
#define SIG_PRI
Definition: chan_dahdi.h:745
#define SIG_SS7
Definition: chan_dahdi.h:750
char mohinterpret[MAX_MUSICCLASS]
The configured music-on-hold class to use for calls.
Definition: chan_dahdi.h:465
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
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:7866
#define SIG_FXSGS
Definition: chan_dahdi.h:732
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922
#define SIG_FXSKS
Definition: chan_dahdi.h:733
int ast_channel_hangupcause(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
#define SIG_FXSLS
Definition: chan_dahdi.h:731
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_lock_sub_owner()

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

Definition at line 3465 of file chan_dahdi.c.

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

Referenced by wakeup_sub().

3466 {
3467  for (;;) {
3468  if (!pvt->subs[sub_idx].owner) {
3469  /* No subchannel owner pointer */
3470  break;
3471  }
3472  if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) {
3473  /* Got subchannel owner lock */
3474  break;
3475  }
3476  /* We must unlock the private to avoid the possibility of a deadlock */
3477  DEADLOCK_AVOIDANCE(&pvt->lock);
3478  }
3479 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:374
ast_mutex_t lock
Definition: chan_dahdi.h:125
struct ast_channel * owner
Definition: chan_dahdi.h:79
#define ast_channel_trylock(chan)
Definition: channel.h:2947

◆ dahdi_master_slave_link()

void dahdi_master_slave_link ( struct dahdi_pvt slave,
struct dahdi_pvt master 
)

Definition at line 7037 of file chan_dahdi.c.

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

Referenced by native_start().

7038 {
7039  int x;
7040  if (!slave || !master) {
7041  ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
7042  return;
7043  }
7044  for (x = 0; x < MAX_SLAVES; x++) {
7045  if (!master->slaves[x]) {
7046  master->slaves[x] = slave;
7047  break;
7048  }
7049  }
7050  if (x >= MAX_SLAVES) {
7051  ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
7052  master->slaves[MAX_SLAVES - 1] = slave;
7053  }
7054  if (slave->master)
7055  ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
7056  slave->master = master;
7057 
7058  ast_debug(1, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
7059 }
#define MAX_SLAVES
Definition: chan_dahdi.h:95
struct dahdi_pvt * master
Definition: chan_dahdi.h:135
#define LOG_WARNING
Definition: logger.h:274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct dahdi_pvt * slaves[MAX_SLAVES]
Definition: chan_dahdi.h:134
int channel
Definition: chan_dahdi.h:538

◆ dahdi_master_slave_unlink()

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

Definition at line 6981 of file chan_dahdi.c.

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

6982 {
6983  /* Unlink a specific slave or all slaves/masters from a given master */
6984  int x;
6985  int hasslaves;
6986  if (!master)
6987  return;
6988  if (needlock) {
6989  ast_mutex_lock(&master->lock);
6990  if (slave) {
6991  while (ast_mutex_trylock(&slave->lock)) {
6992  DEADLOCK_AVOIDANCE(&master->lock);
6993  }
6994  }
6995  }
6996  hasslaves = 0;
6997  for (x = 0; x < MAX_SLAVES; x++) {
6998  if (master->slaves[x]) {
6999  if (!slave || (master->slaves[x] == slave)) {
7000  /* Take slave out of the conference */
7001  ast_debug(1, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
7002  conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
7003  conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
7004  master->slaves[x]->master = NULL;
7005  master->slaves[x] = NULL;
7006  } else
7007  hasslaves = 1;
7008  }
7009  if (!hasslaves)
7010  master->inconference = 0;
7011  }
7012  if (!slave) {
7013  if (master->master) {
7014  /* Take master out of the conference */
7015  conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
7016  conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
7017  hasslaves = 0;
7018  for (x = 0; x < MAX_SLAVES; x++) {
7019  if (master->master->slaves[x] == master)
7020  master->master->slaves[x] = NULL;
7021  else if (master->master->slaves[x])
7022  hasslaves = 1;
7023  }
7024  if (!hasslaves)
7025  master->master->inconference = 0;
7026  }
7027  master->master = NULL;
7028  }
7029  dahdi_conf_update(master);
7030  if (needlock) {
7031  if (slave)
7032  ast_mutex_unlock(&slave->lock);
7033  ast_mutex_unlock(&master->lock);
7034  }
7035 }
static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index)
Definition: chan_dahdi.c:4506
#define MAX_SLAVES
Definition: chan_dahdi.h:95
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:374
struct dahdi_pvt * master
Definition: chan_dahdi.h:135
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
void dahdi_conf_update(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4583
int inconference
Definition: chan_dahdi.h:136
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct dahdi_pvt * slaves[MAX_SLAVES]
Definition: chan_dahdi.h:134
#define ast_mutex_trylock(a)
Definition: lock.h:189
ast_mutex_t lock
Definition: chan_dahdi.h:125
#define SUB_REAL
Definition: chan_dahdi.h:57
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

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

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_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, DSP_PROGRESS_TALK, 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_variable::name, ast_party_id::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_clear_alarms(), handle_init_event(), mwi_thread(), and my_swap_subchannels().

9154 {
9155  struct ast_channel *tmp;
9156  struct ast_format_cap *caps;
9157  struct ast_format *deflaw;
9158  int x;
9159  int features;
9160  struct ast_str *chan_name;
9161  struct ast_variable *v;
9162  char *dashptr;
9163  char device_name[AST_CHANNEL_NAME];
9164 
9165  if (i->subs[idx].owner) {
9166  ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[idx]);
9167  return NULL;
9168  }
9169 
9170 #if defined(HAVE_PRI)
9171  /*
9172  * The dnid has been stuffed with the called-number[:subaddress]
9173  * by dahdi_request() for outgoing calls.
9174  */
9175  chan_name = create_channel_name(i, i->outgoing, i->dnid);
9176 #else
9177  chan_name = create_channel_name(i);
9178 #endif /* defined(HAVE_PRI) */
9179  if (!chan_name) {
9180  return NULL;
9181  }
9182 
9184  if (!caps) {
9185  ast_free(chan_name);
9186  return NULL;
9187  }
9188 
9189  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));
9190  ast_free(chan_name);
9191  if (!tmp) {
9192  ao2_ref(caps, -1);
9193  return NULL;
9194  }
9195 
9197 
9198  if (callid) {
9199  ast_channel_callid_set(tmp, callid);
9200  }
9201 
9203 #if defined(HAVE_PRI)
9204  if (i->pri) {
9206  }
9207 #endif /* defined(HAVE_PRI) */
9209  if (law) {
9210  i->law = law;
9211  if (law == DAHDI_LAW_ALAW) {
9212  deflaw = ast_format_alaw;
9213  } else {
9214  deflaw = ast_format_ulaw;
9215  }
9216  } else {
9217  switch (i->sig) {
9219  /* Make sure companding law is known. */
9220  i->law = (i->law_default == DAHDI_LAW_ALAW)
9221  ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW;
9222  break;
9223  default:
9224  i->law = i->law_default;
9225  break;
9226  }
9227  if (i->law_default == DAHDI_LAW_ALAW) {
9228  deflaw = ast_format_alaw;
9229  } else {
9230  deflaw = ast_format_ulaw;
9231  }
9232  }
9233  ast_channel_set_fd(tmp, 0, i->subs[idx].dfd);
9234  ast_format_cap_append(caps, deflaw, 0);
9235  ast_channel_nativeformats_set(tmp, caps);
9236  ao2_ref(caps, -1);
9237  /* Start out assuming ulaw since it's smaller :) */
9238  ast_channel_set_rawreadformat(tmp, deflaw);
9239  ast_channel_set_readformat(tmp, deflaw);
9240  ast_channel_set_rawwriteformat(tmp, deflaw);
9241  ast_channel_set_writeformat(tmp, deflaw);
9242  i->subs[idx].linear = 0;
9243  dahdi_setlinear(i->subs[idx].dfd, i->subs[idx].linear);
9244  features = 0;
9245  if (idx == SUB_REAL) {
9246  if (i->busydetect && CANBUSYDETECT(i))
9247  features |= DSP_FEATURE_BUSY_DETECT;
9249  features |= DSP_FEATURE_CALL_PROGRESS;
9250  if ((i->waitfordialtone || i->dialtone_detect) && CANPROGRESSDETECT(i))
9251  features |= DSP_FEATURE_WAITDIALTONE;
9252  if ((!i->outgoing && (i->callprogress & CALLPROGRESS_FAX_INCOMING)) ||
9254  features |= DSP_FEATURE_FAX_DETECT;
9255  }
9256  x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
9257  if (ioctl(i->subs[idx].dfd, DAHDI_TONEDETECT, &x)) {
9258  i->hardwaredtmf = 0;
9259  features |= DSP_FEATURE_DIGIT_DETECT;
9260  } else if (NEED_MFDETECT(i)) {
9261  i->hardwaredtmf = 1;
9262  features |= DSP_FEATURE_DIGIT_DETECT;
9263  }
9264  }
9265  if (features) {
9266  if (i->dsp) {
9267  ast_debug(1, "Already have a dsp on %s?\n", ast_channel_name(tmp));
9268  } else {
9269  if (i->channel != CHAN_PSEUDO)
9270  i->dsp = ast_dsp_new();
9271  else
9272  i->dsp = NULL;
9273  if (i->dsp) {
9274  i->dsp_features = features;
9275 #if defined(HAVE_PRI) || defined(HAVE_SS7)
9276  /* We cannot do progress detection until receive PROGRESS message */
9277  if (i->outgoing && (dahdi_sig_pri_lib_handles(i->sig) || (i->sig == SIG_SS7))) {
9278  /* Remember requested DSP features, don't treat
9279  talking as ANSWER */
9280  i->dsp_features = features & ~DSP_PROGRESS_TALK;
9281  features = 0;
9282  }
9283 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
9284  ast_dsp_set_features(i->dsp, features);
9286  if (!ast_strlen_zero(progzone))
9288  if (i->busydetect && CANBUSYDETECT(i)) {
9291  }
9292  }
9293  }
9294  }
9295 
9297 
9298  if (state == AST_STATE_RING)
9299  ast_channel_rings_set(tmp, 1);
9300  ast_channel_tech_pvt_set(tmp, i);
9301  if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
9302  /* Only FXO signalled stuff can be picked up */
9307  }
9308  if (!ast_strlen_zero(i->parkinglot))
9309  ast_channel_parkinglot_set(tmp, i->parkinglot);
9310  if (!ast_strlen_zero(i->language))
9311  ast_channel_language_set(tmp, i->language);
9312  if (!i->owner)
9313  i->owner = tmp;
9314  if (!ast_strlen_zero(i->accountcode))
9315  ast_channel_accountcode_set(tmp, i->accountcode);
9316  if (i->amaflags)
9318  i->subs[idx].owner = tmp;
9320  if (!dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
9321  ast_channel_call_forward_set(tmp, i->call_forward);
9322  }
9323  /* If we've been told "no ADSI" then enforce it */
9324  if (!i->adsi)
9326  if (!ast_strlen_zero(i->exten))
9327  ast_channel_exten_set(tmp, i->exten);
9328  if (!ast_strlen_zero(i->rdnis)) {
9331  }
9332  if (!ast_strlen_zero(i->dnid)) {
9334  }
9335 
9336  /* Don't use ast_set_callerid() here because it will
9337  * generate a needless NewCallerID event */
9338 #if defined(HAVE_PRI) || defined(HAVE_SS7)
9339  if (!ast_strlen_zero(i->cid_ani)) {
9340  ast_channel_caller(tmp)->ani.number.valid = 1;
9341  ast_channel_caller(tmp)->ani.number.str = ast_strdup(i->cid_ani);
9342  } else if (!ast_strlen_zero(i->cid_num)) {
9343  ast_channel_caller(tmp)->ani.number.valid = 1;
9345  }
9346 #else
9347  if (!ast_strlen_zero(i->cid_num)) {
9348  ast_channel_caller(tmp)->ani.number.valid = 1;
9350  }
9351 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
9355  ast_channel_caller(tmp)->ani2 = i->cid_ani2;
9357  /* clear the fake event in case we posted one before we had ast_channel */
9358  i->fake_event = 0;
9359  /* Assure there is no confmute on this channel */
9360  dahdi_confmute(i, 0);
9361  i->muting = 0;
9362  /* Configure the new channel jb */
9364 
9365  /* Set initial device state */
9366  ast_copy_string(device_name, ast_channel_name(tmp), sizeof(device_name));
9367  dashptr = strrchr(device_name, '-');
9368  if (dashptr) {
9369  *dashptr = '\0';
9370  }
9373 
9374  for (v = i->vars ; v ; v = v->next)
9375  pbx_builtin_setvar_helper(tmp, v->name, v->value);
9376 
9378 
9379  ast_channel_unlock(tmp);
9380 
9382 
9383  dahdi_ami_channel_event(i, tmp);
9384  if (startpbx) {
9385 #ifdef HAVE_OPENR2
9386  if (i->mfcr2call) {
9387  pbx_builtin_setvar_helper(tmp, "MFCR2_CATEGORY", openr2_proto_get_category_string(i->mfcr2_recvd_category));
9388  }
9389 #endif
9390  if (ast_pbx_start(tmp)) {
9391  ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
9392  ast_hangup(tmp);
9393  return NULL;
9394  }
9395  }
9396  return tmp;
9397 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
unsigned int outgoing
TRUE if we originated the call leg.
Definition: chan_dahdi.h:290
struct ast_variable * next
int dialtone_scanning_time_elapsed
Definition: chan_dahdi.h:615
int dtmfrelax
Definition: chan_dahdi.h:665
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:278
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
Main Channel structure associated with a channel.
struct ast_party_dialed::@246 number
Dialed/Called number.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
int cid_ton
Caller ID Q.931 TON/NPI field values. Set by PRI. Zero otherwise.
Definition: chan_dahdi.h:486
struct ast_namedgroups * named_pickupgroups
Named pickup groups this belongs to.
Definition: chan_dahdi.h:532
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
char * str
Subscriber phone number (Malloced)
Definition: channel.h:387
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:296
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
#define SIG_FXOGS
Definition: chan_dahdi.h:735
static int dahdi_confmute(struct dahdi_pvt *p, int muted)
Definition: chan_dahdi.c:4939
char parkinglot[AST_MAX_EXTENSION]
Definition: chan_dahdi.h:471
unsigned int hardwaredtmf
TRUE if DTMF detection needs to be done by hardware.
Definition: chan_dahdi.h:263
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:528
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
static struct ast_channel_tech dahdi_tech
Definition: chan_dahdi.c:1030
char dnid[AST_MAX_EXTENSION]
Dialed Number Identifier.
Definition: chan_dahdi.h:500
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
#define LOG_WARNING
Definition: logger.h:274
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4712
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define DSP_PROGRESS_TALK
Definition: dsp.h:39
#define DSP_FEATURE_CALL_PROGRESS
Definition: dsp.h:43
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
struct ast_channel * owner
Definition: chan_dahdi.h:127
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
int dsp_features
DSP feature flags: DSP_FEATURE_xxx.
Definition: chan_dahdi.h:683
int law_default
Default call PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:507
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
#define SIG_FXOKS
Definition: chan_dahdi.h:736
#define CHAN_PSEUDO
Definition: chan_dahdi.c:556
int callingpres
Definition: chan_dahdi.h:545
Definition of a media format.
Definition: format.c:43
struct ast_dsp_busy_pattern busy_cadence
Busy cadence pattern description.
Definition: chan_dahdi.h:599
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
#define CANBUSYDETECT(p)
Definition: chan_dahdi.c:593
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define CALLPROGRESS_PROGRESS
Definition: chan_dahdi.c:558
int law
Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:509
#define NULL
Definition: resample.c:96
unsigned int adsi
TRUE if ADSI (Analog Display Services Interface) available.
Definition: chan_dahdi.h:177
const char *const subnames[]
Definition: chan_dahdi.c:795
int oprmode
Definition: chan_dahdi.h:150
#define ast_strlen_zero(foo)
Definition: strings.h:52
ast_group_t pickupgroup
Bitmapped pickup groups this belongs to.
Definition: chan_dahdi.h:522
char cid_name[AST_MAX_EXTENSION]
Caller ID name from an incoming call.
Definition: chan_dahdi.h:488
void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
Set number of required cadences for busy.
Definition: dsp.c:1780
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
static char progzone[10]
Definition: chan_dahdi.c:605
#define CALLPROGRESS_FAX_OUTGOING
Definition: chan_dahdi.c:559
#define NEED_MFDETECT(p)
Signaling types that need to use MF detection should be placed in this macro.
Definition: chan_dahdi.c:525
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
struct ast_cc_config_params * cc_params
Definition: chan_dahdi.h:710
struct ast_module * self
Definition: module.h:342
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:428
int amaflags
Definition: chan_dahdi.h:646
void ast_channel_rings_set(struct ast_channel *chan, int value)
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
int cid_ani2
Automatic Number Identification code from PRI.
Definition: chan_dahdi.h:477
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
struct ast_channel * owner
Definition: chan_dahdi.h:79
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
unsigned int busydetect
TRUE if busy detection is enabled. (Listens for the beep-beep busy pattern.)
Definition: chan_dahdi.h:189
unsigned int linear
Definition: chan_dahdi.h:90
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
char cid_tag[AST_MAX_EXTENSION]
Caller ID tag from incoming call.
Definition: chan_dahdi.h:484
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
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:10652
#define SIG_SS7
Definition: chan_dahdi.h:750
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
int busycount
Number of times to see "busy" tone before hanging up.
Definition: chan_dahdi.h:594
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
char cid_num[AST_MAX_EXTENSION]
Caller ID number from an incoming call.
Definition: chan_dahdi.h:479
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:294
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:434
#define SUB_REAL
Definition: chan_dahdi.h:57
static void dahdi_ami_channel_event(struct dahdi_pvt *p, struct ast_channel *chan)
Definition: chan_dahdi.c:1801
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:1791
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
char exten[AST_MAX_EXTENSION]
Extension to use in the dialplan.
Definition: chan_dahdi.h:455
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
int muting
TRUE if confrence is muted.
Definition: chan_dahdi.h:708
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
char call_forward[AST_MAX_EXTENSION]
Accumulated call forwarding number.
Definition: chan_dahdi.h:649
#define ast_free(a)
Definition: astmm.h:182
static struct ast_jb_conf global_jbconf
Definition: chan_dahdi.c:505
#define AST_CHANNEL_NAME
Definition: channel.h:172
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
char context[AST_MAX_CONTEXT]
The configured context for incoming calls.
Definition: chan_dahdi.h:444
#define DSP_FEATURE_BUSY_DETECT
Definition: dsp.h:27
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:861
struct ast_namedgroups * named_callgroups
Named call groups this belongs to.
Definition: chan_dahdi.h:527
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
void ast_channel_callid_set(struct ast_channel *chan, ast_callid value)
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
int fake_event
Holding place for event injected from outside normal operation.
Definition: chan_dahdi.h:667
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
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...
static int dahdi_setlinear(int dfd, int linear)
Definition: chan_dahdi.c:4161
char * tag
User-set "tag".
Definition: channel.h:355
int waitfordialtone
Number of milliseconds to wait for dialtone.
Definition: chan_dahdi.h:609
#define CALLPROGRESS_FAX_INCOMING
Definition: chan_dahdi.c:560
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
const char * ast_channel_name(const struct ast_channel *chan)
static struct ast_str * create_channel_name(struct dahdi_pvt *i)
Definition: chan_dahdi.c:9099
struct ast_variable * vars
Channel variable list with associated values to set when a channel is created.
Definition: chan_dahdi.h:537
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
#define SIG_FXOLS
Definition: chan_dahdi.h:734
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
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
char rdnis[AST_MAX_EXTENSION]
Redirecting Directory Number Information Service (RDNIS) number.
Definition: chan_dahdi.h:498
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1259
int callprogress
Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
Definition: chan_dahdi.h:604
char language[MAX_LANGUAGE]
Language configured for calls.
Definition: chan_dahdi.h:460
int dialtone_detect
Number of frames to watch for dialtone in incoming calls.
Definition: chan_dahdi.h:614
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
int channel
Definition: chan_dahdi.h:538
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
Set zone for doing progress detection.
Definition: dsp.c:1879
ast_group_t callgroup
Bitmapped call groups this belongs to.
Definition: chan_dahdi.h:517
#define CANPROGRESSDETECT(p)
Definition: chan_dahdi.c:594
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1844
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_dahdi.h:645
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443

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

References ast_callid_threadstorage_auto_clean(), and dahdi_new().

Referenced by my_new_analog_ast_channel(), my_on_hook(), and my_swap_subchannels().

9145 {
9146  struct ast_channel *new_channel = dahdi_new(i, state, startpbx, idx, law, assignedids, requestor, callid);
9147 
9149 
9150  return new_channel;
9151 }
Main Channel structure associated with a channel.
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:2042
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:9153

◆ dahdi_open()

static int dahdi_open ( char *  fn)
static

Definition at line 4086 of file chan_dahdi.c.

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

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

4087 {
4088  int fd;
4089  int isnum;
4090  int chan = 0;
4091  int bs;
4092  int x;
4093  isnum = 1;
4094  for (x = 0; x < strlen(fn); x++) {
4095  if (!isdigit(fn[x])) {
4096  isnum = 0;
4097  break;
4098  }
4099  }
4100  if (isnum) {
4101  chan = atoi(fn);
4102  if (chan < 1) {
4103  ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
4104  return -1;
4105  }
4106  fn = "/dev/dahdi/channel";
4107  }
4108  fd = open(fn, O_RDWR | O_NONBLOCK);
4109  if (fd < 0) {
4110  ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
4111  return -1;
4112  }
4113  if (chan) {
4114  if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
4115  x = errno;
4116  close(fd);
4117  errno = x;
4118  ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
4119  return -1;
4120  }
4121  }
4122  bs = READ_SIZE;
4123  if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) {
4124  ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno));
4125  x = errno;
4126  close(fd);
4127  errno = x;
4128  return -1;
4129  }
4130  return fd;
4131 }
#define LOG_WARNING
Definition: logger.h:274
char * bs
Definition: eagi_proxy.c:73
#define ast_log
Definition: astobj2.c:42
int errno
#define READ_SIZE
Definition: chan_dahdi.c:673
char x
Definition: extconf.c:81

◆ dahdi_queryoption()

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

Definition at line 6504 of file chan_dahdi.c.

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, dahdi_sig_pri_lib_handles(), DSP_FEATURE_FAX_DETECT, dahdi_pvt::dsp_features, errno, dahdi_pvt::ignoredtmf, and dahdi_pvt::sig.

Referenced by dahdi_chan_conf_default().

6505 {
6506  char *cp;
6507  struct dahdi_pvt *p = ast_channel_tech_pvt(chan);
6508 
6509  /* all supported options require data */
6510  if (!p || !data || (*datalen < 1)) {
6511  errno = EINVAL;
6512  return -1;
6513  }
6514 
6515  switch (option) {
6517  cp = (char *) data;
6518  *cp = p->ignoredtmf ? 0 : 1;
6519  ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", ast_channel_name(chan));
6520  break;
6521  case AST_OPTION_FAX_DETECT:
6522  cp = (char *) data;
6523  *cp = (p->dsp_features & DSP_FEATURE_FAX_DETECT) ? 0 : 1;
6524  ast_debug(1, "Reporting fax tone detection %sabled on %s\n", *cp ? "en" : "dis", ast_channel_name(chan));
6525  break;
6527 #if defined(HAVE_PRI)
6528 #if defined(HAVE_PRI_CCSS)
6529  if (dahdi_sig_pri_lib_handles(p->sig)) {
6530  ast_copy_string((char *) data, dahdi_pri_cc_type, *datalen);
6531  break;
6532  }
6533 #endif /* defined(HAVE_PRI_CCSS) */
6534 #endif /* defined(HAVE_PRI) */
6535  return -1;
6536  default:
6537  return -1;
6538  }
6539 
6540  errno = 0;
6541 
6542  return 0;
6543 }
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
void * ast_channel_tech_pvt(const struct ast_channel *chan)
int dsp_features
DSP feature flags: DSP_FEATURE_xxx.
Definition: chan_dahdi.h:683
#define AST_OPTION_CC_AGENT_TYPE
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
#define AST_OPTION_DIGIT_DETECT
int errno
unsigned int ignoredtmf
TRUE if DTMF detection is disabled.
Definition: chan_dahdi.h:278
#define AST_OPTION_FAX_DETECT
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)

◆ dahdi_queue_frame()

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

Definition at line 3490 of file chan_dahdi.c.

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

Referenced by action_dahdidialoffhook().

3491 {
3492  for (;;) {
3493  if (p->owner) {
3494  if (ast_channel_trylock(p->owner)) {
3495  DEADLOCK_AVOIDANCE(&p->lock);
3496  } else {
3497  ast_queue_frame(p->owner, f);
3499  break;
3500  }
3501  } else
3502  break;
3503  }
3504 }
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:374
struct ast_channel * owner
Definition: chan_dahdi.h:127
ast_mutex_t lock
Definition: chan_dahdi.h:125
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_channel_trylock(chan)
Definition: channel.h:2947

◆ dahdi_read()

static struct ast_frame * dahdi_read ( struct ast_channel ast)
static

Definition at line 8418 of file chan_dahdi.c.

References __dahdi_exception(), 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::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_WARNING, ast_frame::mallocd, mute, 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::waitfordialtone, and dahdi_pvt::waitingfordt.

Referenced by dahdi_chan_conf_default().

8419 {
8420  struct dahdi_pvt *p;
8421  int res;
8422  int idx;
8423  void *readbuf;
8424  struct ast_frame *f;
8425 
8426  /*
8427  * For analog channels, we must do deadlock avoidance because
8428  * analog ports can have more than one Asterisk channel using
8429  * the same private structure.
8430  */
8431  p = ast_channel_tech_pvt(ast);
8432  while (ast_mutex_trylock(&p->lock)) {
8434 
8435  /*
8436  * Check to see if the channel is still associated with the same
8437  * private structure. While the Asterisk channel was unlocked
8438  * the following events may have occured:
8439  *
8440  * 1) A masquerade may have associated the channel with another
8441  * technology or private structure.
8442  *
8443  * 2) For PRI calls, call signaling could change the channel
8444  * association to another B channel (private structure).
8445  */
8446  if (ast_channel_tech_pvt(ast) != p) {
8447  /* The channel is no longer associated. Quit gracefully. */
8448  return &ast_null_frame;
8449  }
8450  }
8451 
8452  idx = dahdi_get_index(ast, p, 0);
8453 
8454  /* Hang up if we don't really exist */
8455  if (idx < 0) {
8456  ast_log(LOG_WARNING, "We don't exist?\n");
8457  ast_mutex_unlock(&p->lock);
8458  return NULL;
8459  }
8460 
8461  if ((p->radio || (p->oprmode < 0)) && p->inalarm) {
8462  ast_mutex_unlock(&p->lock);
8463  return NULL;
8464  }
8465 
8466  p->subs[idx].f.frametype = AST_FRAME_NULL;
8467  p->subs[idx].f.datalen = 0;
8468  p->subs[idx].f.samples = 0;
8469  p->subs[idx].f.mallocd = 0;
8470  p->subs[idx].f.offset = 0;
8471  p->subs[idx].f.subclass.integer = 0;
8472  p->subs[idx].f.delivery = ast_tv(0,0);
8473  p->subs[idx].f.src = "dahdi_read";
8474  p->subs[idx].f.data.ptr = NULL;
8475 
8476  /* make sure it sends initial key state as first frame */
8477  if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
8478  {
8479  struct dahdi_params ps;
8480 
8481  memset(&ps, 0, sizeof(ps));
8482  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
8483  ast_mutex_unlock(&p->lock);
8484  return NULL;
8485  }
8486  p->firstradio = 1;
8487  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
8488  if (ps.rxisoffhook)
8489  {
8491  }
8492  else
8493  {
8495  }
8496  ast_mutex_unlock(&p->lock);
8497  return &p->subs[idx].f;
8498  }
8499  if (p->ringt > 0) {
8500  if (!(--p->ringt)) {
8501  ast_mutex_unlock(&p->lock);
8502  return NULL;
8503  }
8504  }
8505 
8506 #ifdef HAVE_OPENR2
8507  if (p->mfcr2) {
8508  openr2_chan_process_event(p->r2chan);
8509  if (OR2_DIR_FORWARD == openr2_chan_get_direction(p->r2chan)) {
8510  struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_PROGRESS } };
8511  /* if the call is already accepted and we already delivered AST_CONTROL_RINGING
8512  * now enqueue a progress frame to bridge the media up */
8513  if (p->mfcr2_call_accepted &&
8514  !p->mfcr2_progress_sent &&
8516  ast_debug(1, "Enqueuing progress frame after R2 accept in chan %d\n", p->channel);
8517  ast_queue_frame(p->owner, &fr);
8518  p->mfcr2_progress_sent = 1;
8519  }
8520  }
8521  }
8522 #endif
8523 
8524  if (p->subs[idx].needringing) {
8525  /* Send ringing frame if requested */
8526  p->subs[idx].needringing = 0;
8527  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
8530  ast_mutex_unlock(&p->lock);
8531  return &p->subs[idx].f;
8532  }
8533 
8534  if (p->subs[idx].needbusy) {
8535  /* Send busy frame if requested */
8536  p->subs[idx].needbusy = 0;
8537  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
8539  ast_mutex_unlock(&p->lock);
8540  return &p->subs[idx].f;
8541  }
8542 
8543  if (p->subs[idx].needcongestion) {
8544  /* Send congestion frame if requested */
8545  p->subs[idx].needcongestion = 0;
8546  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
8548  ast_mutex_unlock(&p->lock);
8549  return &p->subs[idx].f;
8550  }
8551 
8552  if (p->subs[idx].needanswer) {
8553  /* Send answer frame if requested */
8554  p->subs[idx].needanswer = 0;
8555  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
8557  ast_mutex_unlock(&p->lock);
8558  return &p->subs[idx].f;
8559  }
8560 #ifdef HAVE_OPENR2
8561  if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) {
8562  /* openr2 took care of reading and handling any event
8563  (needanswer, needbusy etc), if we continue we will read()
8564  twice, lets just return a null frame. This should only
8565  happen when openr2 is dialing out */
8566  ast_mutex_unlock(&p->lock);
8567  return &ast_null_frame;
8568  }
8569 #endif
8570 
8571  if (p->subs[idx].needflash) {
8572  /* Send answer frame if requested */
8573  p->subs[idx].needflash = 0;
8574  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
8576  ast_mutex_unlock(&p->lock);
8577  return &p->subs[idx].f;
8578  }
8579 
8580  if (p->subs[idx].needhold) {
8581  /* Send answer frame if requested */
8582  p->subs[idx].needhold = 0;
8583  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
8585  ast_mutex_unlock(&p->lock);
8586  ast_debug(1, "Sending hold on '%s'\n", ast_channel_name(ast));
8587  return &p->subs[idx].f;
8588  }
8589 
8590  if (p->subs[idx].needunhold) {
8591  /* Send answer frame if requested */
8592  p->subs[idx].needunhold = 0;
8593  p->subs[idx].f.frametype = AST_FRAME_CONTROL;
8595  ast_mutex_unlock(&p->lock);
8596  ast_debug(1, "Sending unhold on '%s'\n", ast_channel_name(ast));
8597  return &p->subs[idx].f;
8598  }
8599 
8600  /*
8601  * If we have a fake_event, fake an exception to handle it only
8602  * if this channel owns the private.
8603  */
8604  if (p->fake_event && p->owner == ast) {
8605  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
8606  struct analog_pvt *analog_p = p->sig_pvt;
8607 
8608  f = analog_exception(analog_p, ast);
8609  } else {
8610  f = __dahdi_exception(ast);
8611  }
8612  ast_mutex_unlock(&p->lock);
8613  return f;
8614  }
8615 
8617  if (!p->subs[idx].linear) {
8618  p->subs[idx].linear = 1;
8619  res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8620  if (res)
8621  ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, idx);
8622  }
8623  } else {
8624  if (p->subs[idx].linear) {
8625  p->subs[idx].linear = 0;
8626  res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8627  if (res)
8628  ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, idx);
8629  }
8630  }
8631  readbuf = ((unsigned char *)p->subs[idx].buffer) + AST_FRIENDLY_OFFSET;
8632  CHECK_BLOCKING(ast);
8633  res = read(p->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
8635  /* Check for hangup */
8636  if (res < 0) {
8637  f = NULL;
8638  if (res == -1) {
8639  if (errno == EAGAIN) {
8640  /* Return "NULL" frame if there is nobody there */
8641  ast_mutex_unlock(&p->lock);
8642  return &p->subs[idx].f;
8643  } else if (errno == ELAST) {
8644  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
8645  struct analog_pvt *analog_p = p->sig_pvt;
8646  f = analog_exception(analog_p, ast);
8647  } else {
8648  f = __dahdi_exception(ast);
8649  }
8650  } else
8651  ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno));
8652  }
8653  ast_mutex_unlock(&p->lock);
8654  return f;
8655  }
8656  if (res != (p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE)) {
8657  ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
8658  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
8659  struct analog_pvt *analog_p = p->sig_pvt;
8660  f = analog_exception(analog_p, ast);
8661  } else {
8662  f = __dahdi_exception(ast);
8663  }
8664  ast_mutex_unlock(&p->lock);
8665  return f;
8666  }
8667  if (p->tdd) { /* if in TDD mode, see if we receive that */
8668  int c;
8669 
8670  c = tdd_feed(p->tdd,readbuf,READ_SIZE);
8671  if (c < 0) {
8672  ast_debug(1,"tdd_feed failed\n");
8673  ast_mutex_unlock(&p->lock);
8674  return NULL;
8675  }
8676  if (c) { /* if a char to return */
8677  p->subs[idx].f.subclass.integer = 0;
8678  p->subs[idx].f.frametype = AST_FRAME_TEXT;
8679  p->subs[idx].f.mallocd = 0;
8680  p->subs[idx].f.offset = AST_FRIENDLY_OFFSET;
8681  p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET;
8682  p->subs[idx].f.datalen = 1;
8683  *((char *) p->subs[idx].f.data.ptr) = c;
8684  ast_mutex_unlock(&p->lock);
8685  return &p->subs[idx].f;
8686  }
8687  }
8688  if (idx == SUB_REAL) {
8689  /* Ensure the CW timers decrement only on a single subchannel */
8690  if (p->cidcwexpire) {
8691  if (!--p->cidcwexpire) {
8692  /* Expired CID/CW */
8693  ast_verb(3, "CPE does not support Call Waiting Caller*ID.\n");
8694  restore_conference(p);
8695  }
8696  }
8697  if (p->cid_suppress_expire) {
8698  --p->cid_suppress_expire;
8699  }
8700  if (p->callwaitingrepeat) {
8701  if (!--p->callwaitingrepeat) {
8702  /* Expired, Repeat callwaiting tone */
8703  ++p->callwaitrings;
8704  dahdi_callwait(ast);
8705  }
8706  }
8707  }
8708  if (p->subs[idx].linear) {
8709  p->subs[idx].f.datalen = READ_SIZE * 2;
8710  } else
8711  p->subs[idx].f.datalen = READ_SIZE;
8712 
8713  /* Handle CallerID Transmission */
8714  if ((p->owner == ast) && p->cidspill) {
8715  send_callerid(p);
8716  }
8717 
8718  p->subs[idx].f.frametype = AST_FRAME_VOICE;
8720  p->subs[idx].f.samples = READ_SIZE;
8721  p->subs[idx].f.mallocd = 0;
8722  p->subs[idx].f.offset = AST_FRIENDLY_OFFSET;
8723  p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[idx].buffer[0]);
8724 #if 0
8725  ast_debug(1, "Read %d of voice on %s\n", p->subs[idx].f.datalen, ast->name);
8726 #endif
8727  if ((p->dialing && !p->waitingfordt.tv_sec) || p->radio || /* Transmitting something */
8728  (idx && (ast_channel_state(ast) != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
8729  ((idx == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
8730  ) {
8731  /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
8732  don't send anything */
8733  p->subs[idx].f.frametype = AST_FRAME_NULL;
8734  p->subs[idx].f.subclass.integer = 0;
8735  p->subs[idx].f.samples = 0;
8736  p->subs[idx].f.mallocd = 0;
8737  p->subs[idx].f.offset = 0;
8738  p->subs[idx].f.data.ptr = NULL;
8739  p->subs[idx].f.datalen= 0;
8740  }
8741  if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress || p->waitingfordt.tv_sec || p->dialtone_detect) && !idx) {
8742  /* Perform busy detection etc on the dahdi line */
8743  int mute;
8744 
8746  && p->faxdetect_timeout
8750  ast_debug(1, "Channel driver fax CNG detection timeout on %s\n",
8751  ast_channel_name(ast));
8752  }
8753 
8754  f = ast_dsp_process(ast, p->dsp, &p->subs[idx].f);
8755 
8756  /* Check if DSP code thinks we should be muting this frame and mute the conference if so */
8757  mute = ast_dsp_was_muted(p->dsp);
8758  if (p->muting != mute) {
8759  p->muting = mute;
8760  dahdi_confmute(p, mute);
8761  }
8762 
8763  if (f) {
8765  && !p->outgoing && ast_channel_state(ast) == AST_STATE_UP) {
8769  }
8770  }
8771  if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_BUSY)) {
8772  if ((ast_channel_state(ast) == AST_STATE_UP) && !p->outgoing) {
8773  /*
8774  * Treat this as a "hangup" instead of a "busy" on the
8775  * assumption that a busy means the incoming call went away.
8776  */
8777  ast_frfree(f);
8778  f = NULL;
8779  }
8780  } else if (p->dialtone_detect && !p->outgoing && f->frametype == AST_FRAME_VOICE) {
8782  /* Dialtone detected on inbound call; hangup the channel */
8783  ast_frfree(f);
8784  f = NULL;
8785  }
8786  } else if (f->frametype == AST_FRAME_DTMF_BEGIN
8787  || f->frametype == AST_FRAME_DTMF_END) {
8788 #ifdef HAVE_PRI
8790  && ((struct sig_pri_chan *) p->sig_pvt)->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING
8791  && p->pri
8792  && ((!p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING))
8793  || (p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)))) {
8794  /* Don't accept in-band DTMF when in overlap dial mode */
8795  ast_debug(1, "Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n",
8796  f->frametype == AST_FRAME_DTMF_BEGIN ? "begin" : "end",
8797  (unsigned)f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
8798 
8800  f->subclass.integer = 0;
8801  }
8802 #endif
8803  /* DSP clears us of being pulse */
8804  p->pulsedial = 0;
8805  } else if (p->waitingfordt.tv_sec) {
8807  p->waitingfordt.tv_sec = 0;
8808  ast_log(LOG_WARNING, "Never saw dialtone on channel %d\n", p->channel);
8809  ast_frfree(f);
8810  f = NULL;
8811  } else if (f->frametype == AST_FRAME_VOICE) {
8813  f->subclass.integer = 0;
8815  p->waitingfordt.tv_sec = 0;
8818  ast_debug(1, "Got 10 samples of dialtone!\n");
8819  if (!ast_strlen_zero(p->dop.dialstr)) { /* Dial deferred digits */
8820  res = dahdi_dial_str(p, p->dop.op, p->dop.dialstr);
8821  if (res) {
8822  p->dop.dialstr[0] = '\0';
8823  ast_mutex_unlock(&p->lock);
8824  ast_frfree(f);
8825  return NULL;
8826  } else {
8827  ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
8828  p->dialing = 1;
8829  p->dop.dialstr[0] = '\0';
8830  p->dop.op = DAHDI_DIAL_OP_REPLACE;
8832  }
8833  }
8834  }
8835  }
8836  }
8837  }
8838  } else
8839  f = &p->subs[idx].f;
8840 
8841  if (f) {
8842  switch (f->frametype) {
8843  case AST_FRAME_DTMF_BEGIN:
8844  case AST_FRAME_DTMF_END:
8845  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
8846  analog_handle_dtmf(p->sig_pvt, ast, idx, &f);
8847  } else {
8848  dahdi_handle_dtmf(ast, idx, &f);
8849  }
8850  break;
8851  case AST_FRAME_VOICE:
8852  if (p->cidspill || p->cid_suppress_expire) {
8853  /* We are/were sending a caller id spill. Suppress any echo. */
8854  p->subs[idx].f.frametype = AST_FRAME_NULL;
8855  p->subs[idx].f.subclass.integer = 0;
8856  p->subs[idx].f.samples = 0;
8857  p->subs[idx].f.mallocd = 0;
8858  p->subs[idx].f.offset = 0;
8859  p->subs[idx].f.data.ptr = NULL;
8860  p->subs[idx].f.datalen= 0;
8861  }
8862  break;
8863  default:
8864  break;
8865  }
8866  }
8867 
8868  ast_mutex_unlock(&p->lock);
8869  return f;
8870 }
unsigned int outgoing
TRUE if we originated the call leg.
Definition: chan_dahdi.h:290
int dialtone_scanning_time_elapsed
Definition: chan_dahdi.h:615
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
static void dahdi_handle_dtmf(struct ast_channel *ast, int idx, struct ast_frame **dest)
Definition: chan_dahdi.c:7231
#define DAHDI_OVERLAPDIAL_INCOMING
Definition: sig_pri.h:255
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:1494
struct dahdi_dialoperation dop
DAHDI dial operation command struct for ioctl() call.
Definition: chan_dahdi.h:641
unsigned int needflash
Definition: chan_dahdi.h:87
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: chan_dahdi.h:575
static int dahdi_dial_str(struct dahdi_pvt *pvt, int operation, const char *dial_str)
Definition: chan_dahdi.c:1223
unsigned int dialing
TRUE if in the process of dialing digits or sending something.
Definition: chan_dahdi.h:234
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
int callwaitrings
Number of call waiting rings.
Definition: chan_dahdi.h:577
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int dahdi_confmute(struct dahdi_pvt *p, int muted)
Definition: chan_dahdi.c:4939
int ast_dsp_get_tcount(struct ast_dsp *dsp)
Get tcount (Threshold counter)
Definition: dsp.c:1903
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
unsigned int needanswer
Definition: chan_dahdi.h:86
int ringt
Ring timeout timer??
Definition: chan_dahdi.h:556
unsigned int firstradio
TRUE if over a radio and dahdi_read() has been called.
Definition: chan_dahdi.h:256
#define LOG_WARNING
Definition: logger.h:274
struct ast_channel * owner
Definition: chan_dahdi.h:127
#define DSP_TONE_STATE_DIALTONE
Definition: dsp.h:54
static struct ast_frame * __dahdi_exception(struct ast_channel *ast)
Definition: chan_dahdi.c:8281
int dsp_features
DSP feature flags: DSP_FEATURE_xxx.
Definition: chan_dahdi.h:683
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:1893
ast_channel_state
ast_channel states
Definition: channelstate.h:35
void analog_handle_dtmf(struct analog_pvt *p, struct ast_channel *ast, enum analog_sub idx, struct ast_frame **dest)
Definition: sig_analog.c:1564
void * sig_pvt
Definition: chan_dahdi.h:709
#define DAHDI_OVERLAPDIAL_OUTGOING
Definition: sig_pri.h:254
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
Definition: channel.c:2854
static struct test_val c
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
int callwaitingrepeat
Definition: chan_dahdi.h:546
struct ast_frame f
Definition: chan_dahdi.h:82
#define ast_verb(level,...)
Definition: logger.h:463
unsigned int needhold
Definition: chan_dahdi.h:88
struct ast_frame_subclass subclass
static int mute
Definition: chan_alsa.c:144
static int dahdi_callwait(struct ast_channel *ast)
Definition: chan_dahdi.c:5087
int oprmode
Definition: chan_dahdi.h:150
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
const char * src
#define ast_mutex_trylock(a)
Definition: lock.h:189
unsigned int needunhold
Definition: chan_dahdi.h:89
#define DSP_TONE_STATE_RINGING
Definition: dsp.h:53
ast_mutex_t lock
Definition: chan_dahdi.h:125
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
unsigned int busydetect
TRUE if busy detection is enabled. (Listens for the beep-beep busy pattern.)
Definition: chan_dahdi.h:189
int ast_dsp_get_tstate(struct ast_dsp *dsp)
Get tstate (Tone State)
Definition: dsp.c:1898
unsigned int linear
Definition: chan_dahdi.h:90
struct ast_frame * analog_exception(struct analog_pvt *p, struct ast_channel *ast)
Definition: sig_analog.c:3555
short buffer[AST_FRIENDLY_OFFSET/2+READ_SIZE]
Definition: chan_dahdi.h:81
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
unsigned int inthreeway
Definition: chan_dahdi.h:91
struct timeval waitingfordt
Definition: chan_dahdi.h:636
struct ast_format * ast_channel_rawreadformat(struct ast_channel *chan)
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
int errno
unsigned int needringing
Definition: chan_dahdi.h:83
#define SUB_REAL
Definition: chan_dahdi.h:57
const ast_string_field name
#define READ_SIZE
Definition: chan_dahdi.c:673
static int restore_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5002
int muting
TRUE if confrence is muted.
Definition: chan_dahdi.h:708
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
unsigned int faxdetect_timeout
The number of seconds into call to disable fax detection. (0 = disabled)
Definition: chan_dahdi.h:620
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
Definition: lock.h:352
static int send_callerid(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5051
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct timeval delivery
unsigned int ignoredtmf
TRUE if DTMF detection is disabled.
Definition: chan_dahdi.h:278
#define CHECK_BLOCKING(c)
Set the blocking indication on the channel.
Definition: channel.h:2894
int fake_event
Holding place for event injected from outside normal operation.
Definition: chan_dahdi.h:667
static int dahdi_setlinear(int dfd, int linear)
Definition: chan_dahdi.c:4161
struct ast_frame ast_null_frame
Definition: main/frame.c:79
int waitfordialtone
Number of milliseconds to wait for dialtone.
Definition: chan_dahdi.h:609
struct tdd_state * tdd
Definition: chan_dahdi.h:647
unsigned int needcongestion
Definition: chan_dahdi.h:85
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
const char * ast_channel_name(const struct ast_channel *chan)
unsigned int needbusy
Definition: chan_dahdi.h:84
int cidcwexpire
Definition: chan_dahdi.h:547
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
#define ast_frfree(fr)
int cid_suppress_expire
Definition: chan_dahdi.h:548
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
struct ast_format * format
#define DSP_FEATURE_WAITDIALTONE
Definition: dsp.h:44
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
int callprogress
Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
Definition: chan_dahdi.h:604
int dialtone_detect
Number of frames to watch for dialtone in incoming calls.
Definition: chan_dahdi.h:614
unsigned int inalarm
TRUE if in an alarm condition.
Definition: chan_dahdi.h:286
int channel
Definition: chan_dahdi.h:538
unsigned int pulsedial
TRUE if a pulsed digit was detected. (Pulse dial phone detected)
Definition: chan_dahdi.h:318
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define SUB_CALLWAIT
Definition: chan_dahdi.h:58
int tdd_feed(struct tdd_state *tdd, unsigned char *ubuf, int samples)
Definition: tdd.c:161

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

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::cadance, 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(), 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().

Referenced by dahdi_chan_conf_default().

13494 {
13495  int callwait = 0;
13496  struct dahdi_pvt *p;
13497  struct ast_channel *tmp = NULL;
13498  struct dahdi_pvt *exitpvt;
13499  int channelmatched = 0;
13500  int groupmatched = 0;
13501 #if defined(HAVE_PRI) || defined(HAVE_SS7)
13502  int transcapdigital = 0;
13503 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
13504  struct dahdi_starting_point start;
13505  ast_callid callid = 0;
13506  int callid_created = ast_callid_threadstorage_auto(&callid);
13507 
13509  p = determine_starting_point(data, &start);
13510  if (!p) {
13511  /* We couldn't determine a starting point, which likely means badly-formatted channel name. Abort! */
13513  ast_callid_threadstorage_auto_clean(callid, callid_created);
13514  return NULL;
13515  }
13516 
13517  /* Search for an unowned channel */
13518  exitpvt = p;
13519  while (p && !tmp) {
13520  if (start.roundrobin)
13521  round_robin[start.rr_starting_point] = p;
13522 
13523  if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)
13524  && available(&p, channelmatched)) {
13525  ast_debug(1, "Using channel %d\n", p->channel);
13526 
13527  callwait = (p->owner != NULL);
13528 #ifdef HAVE_OPENR2
13529  if (p->mfcr2) {
13530  ast_mutex_lock(&p->lock);
13531  if (p->mfcr2call) {
13532  ast_mutex_unlock(&p->lock);
13533  ast_debug(1, "Yay!, someone just beat us in the race for channel %d.\n", p->channel);
13534  goto next;
13535  }
13536  p->mfcr2call = 1;
13537  ast_mutex_unlock(&p->lock);
13538  }
13539 #endif
13540  if (p->channel == CHAN_PSEUDO) {
13541  p = duplicate_pseudo(p);
13542  if (!p) {
13543  break;
13544  }
13545  }
13546 
13547  p->distinctivering = 0;
13548  /* Make special notes */
13549  switch (start.opt) {
13550  case '\0':
13551  /* No option present. */
13552  break;
13553  case 'c':
13554  /* Confirm answer */
13555  p->confirmanswer = 1;
13556  break;
13557  case 'r':
13558  /* Distinctive ring */
13559  p->distinctivering = start.cadance;
13560  break;
13561  case 'd':
13562 #if defined(HAVE_PRI) || defined(HAVE_SS7)
13563  /* If this is an ISDN call, make it digital */
13564  transcapdigital = AST_TRANS_CAP_DIGITAL;
13565 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
13566  break;
13567  default:
13568  ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", start.opt, data);
13569  break;
13570  }
13571 
13572  p->outgoing = 1;
13573  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
13574  tmp = analog_request(p->sig_pvt, &callwait, requestor);
13575 #ifdef HAVE_PRI
13576  } else if (dahdi_sig_pri_lib_handles(p->sig)) {
13577  /*
13578  * We already have the B channel reserved for this call. We
13579  * just need to make sure that dahdi_hangup() has completed
13580  * cleaning up before continuing.
13581  */
13582  ast_mutex_lock(&p->lock);
13583  ast_mutex_unlock(&p->lock);
13584 
13586  sizeof(p->dnid));
13587  tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW, assignedids, requestor, transcapdigital);
13588 #endif
13589 #if defined(HAVE_SS7)
13590  } else if (p->sig == SIG_SS7) {
13591  tmp = sig_ss7_request(p->sig_pvt, SIG_SS7_DEFLAW, assignedids, requestor, transcapdigital);
13592 #endif /* defined(HAVE_SS7) */
13593  } else {
13594  tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, assignedids, requestor, callid);
13595  }
13596  if (!tmp) {
13597  p->outgoing = 0;
13598 #if defined(HAVE_PRI)
13599  switch (p->sig) {
13601 #if defined(HAVE_PRI_CALL_WAITING)
13602  if (((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting) {
13603  ((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting = 0;
13604  ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1);
13605  }
13606 #endif /* defined(HAVE_PRI_CALL_WAITING) */
13607  /*
13608  * This should be the last thing to clear when we are done with
13609  * the channel.
13610  */
13611  ((struct sig_pri_chan *) p->sig_pvt)->allocated = 0;
13612  break;
13613  default:
13614  break;
13615  }
13616 #endif /* defined(HAVE_PRI) */
13617  } else {
13618  snprintf(p->dialstring, sizeof(p->dialstring), "DAHDI/%s", data);
13619  }
13620  break;
13621  }
13622 #ifdef HAVE_OPENR2
13623 next:
13624 #endif
13625  if (start.backwards) {
13626  p = p->prev;
13627  if (!p)
13628  p = ifend;
13629  } else {
13630  p = p->next;
13631  if (!p)
13632  p = iflist;
13633  }
13634  /* stop when you roll to the one that we started from */
13635  if (p == exitpvt)
13636  break;
13637  }
13639  restart_monitor();
13640  if (cause && !tmp) {
13641  if (callwait || channelmatched) {
13642  *cause = AST_CAUSE_BUSY;
13643  } else if (groupmatched) {
13644  *cause = AST_CAUSE_CONGESTION;
13645  } else {
13646  /*
13647  * We did not match any channel requested.
13648  * Dialplan error requesting non-existant channel?
13649  */
13650  }
13651  }
13652 
13653  ast_callid_threadstorage_auto_clean(callid, callid_created);
13654  return tmp;
13655 }
unsigned int outgoing
TRUE if we originated the call leg.
Definition: chan_dahdi.h:290
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)
Main Channel structure associated with a channel.
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
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:13025
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
char dnid[AST_MAX_EXTENSION]
Dialed Number Identifier.
Definition: chan_dahdi.h:500
#define LOG_WARNING
Definition: logger.h:274
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:2042
struct ast_channel * owner
Definition: chan_dahdi.h:127
static int tmp()
Definition: bt_open.c:389
static struct dahdi_pvt * determine_starting_point(const char *data, struct dahdi_starting_point *param)
Definition: chan_dahdi.c:13330
void * sig_pvt
Definition: chan_dahdi.h:709
#define CHAN_PSEUDO
Definition: chan_dahdi.c:556
unsigned int ast_callid
Definition: logger.h:87
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct dahdi_pvt * ifend
Definition: chan_dahdi.c:802
void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size)
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:755
int oprmode
Definition: chan_dahdi.h:150
static int restart_monitor(void)
Definition: chan_dahdi.c:11770
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
ast_mutex_t lock
Definition: chan_dahdi.h:125
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
#define SIG_SS7
Definition: chan_dahdi.h:750
struct dahdi_pvt * prev
Definition: chan_dahdi.h:169
static struct dahdi_pvt * duplicate_pseudo(struct dahdi_pvt *src)
Definition: chan_dahdi.c:13266
#define SUB_REAL
Definition: chan_dahdi.h:57
char dialstring[AST_CHANNEL_NAME]
Definition: chan_dahdi.h:717
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
int distinctivering
Definition: chan_dahdi.h:664
unsigned int confirmanswer
TRUE if to wait for a DTMF digit to confirm answer.
Definition: chan_dahdi.h:221
static int available(struct dahdi_pvt **pvt, int is_specific_channel)
Definition: chan_dahdi.c:13058
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)
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
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:2020
#define AST_CAUSE_BUSY
Definition: causes.h:148
static struct dahdi_pvt * round_robin[32]
Definition: chan_dahdi.c:3429
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
int channel
Definition: chan_dahdi.h:538
struct ast_channel * analog_request(struct analog_pvt *p, int *callwait, const struct ast_channel *requestor)
Definition: sig_analog.c:772
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:9153
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
#define AST_TRANS_CAP_DIGITAL
Definition: transcap.h:35
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define SUB_CALLWAIT
Definition: chan_dahdi.h:58

◆ dahdi_restart()

static int dahdi_restart ( void  )
static

Definition at line 15424 of file chan_dahdi.c.

References ast_active_channels(), ast_cond_wait, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_verb, dahdi_softhangup_all(), destroy_all_channels(), dahdi_subchannel::dfd, iflock, LOG_WARNING, sig_pri_span::master, monitor_thread, monlock, dahdi_pvt::next, NULL, NUM_SPANS, dahdi_pvt::owner, restart_lock, 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().

15425 {
15426 #if defined(HAVE_PRI) || defined(HAVE_SS7)
15427  int i, j;
15428 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
15429  int cancel_code;
15430  struct dahdi_pvt *p;
15431 
15433  ast_verb(1, "Destroying channels and reloading DAHDI configuration.\n");
15435  ast_verb(4, "Initial softhangup of all DAHDI channels complete.\n");
15436 #ifdef HAVE_OPENR2
15437  dahdi_r2_destroy_links();
15438 #endif
15439 
15440 #if defined(HAVE_PRI)
15441  for (i = 0; i < NUM_SPANS; i++) {
15442  if (pris[i].pri.master && (pris[i].pri.master != AST_PTHREADT_NULL)) {
15443  cancel_code = pthread_cancel(pris[i].pri.master);
15444  pthread_kill(pris[i].pri.master, SIGURG);
15445  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);
15446  pthread_join(pris[i].pri.master, NULL);
15447  ast_debug(4, "Joined thread of span %d\n", i);
15448  }
15449  }
15450 #endif
15451 
15452 #if defined(HAVE_SS7)
15453  for (i = 0; i < NUM_SPANS; i++) {
15454  if (linksets[i].ss7.master && (linksets[i].ss7.master != AST_PTHREADT_NULL)) {
15455  cancel_code = pthread_cancel(linksets[i].ss7.master);
15456  pthread_kill(linksets[i].ss7.master, SIGURG);
15457  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);
15458  pthread_join(linksets[i].ss7.master, NULL);
15459  ast_debug(4, "Joined thread of span %d\n", i);
15460  }
15461  }
15462 #endif /* defined(HAVE_SS7) */
15463 
15466  cancel_code = pthread_cancel(monitor_thread);
15467  pthread_kill(monitor_thread, SIGURG);
15468  ast_debug(4, "Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (void *) monitor_thread, cancel_code);
15469  pthread_join(monitor_thread, NULL);
15470  ast_debug(4, "Joined monitor thread\n");
15471  }
15472  monitor_thread = AST_PTHREADT_NULL; /* prepare to restart thread in setup_dahdi once channels are reconfigured */
15473 
15475  while (ss_thread_count > 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */
15476  int x = DAHDI_FLASH;
15477  ast_debug(3, "Waiting on %d analog_ss_thread(s) to finish\n", ss_thread_count);
15478 
15480  for (p = iflist; p; p = p->next) {
15481  if (p->owner) {
15482  /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */
15483  ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
15484  }
15485  }
15488  }
15489 
15490  /* ensure any created channels before monitor threads were stopped are hungup */
15492  ast_verb(4, "Final softhangup of all DAHDI channels complete.\n");
15494  memset(round_robin, 0, sizeof(round_robin));
15495  ast_debug(1, "Channels destroyed. Now re-reading config. %d active channels remaining.\n", ast_active_channels());
15496 
15498 
15499 #ifdef HAVE_PRI
15500  for (i = 0; i < NUM_SPANS; i++) {
15501  for (j = 0; j < SIG_PRI_NUM_DCHANS; j++)
15502  dahdi_close_pri_fd(&(pris[i]), j);
15503  }
15504 
15505  memset(pris, 0, sizeof(pris));
15506  for (i = 0; i < NUM_SPANS; i++) {
15507  sig_pri_init_pri(&pris[i].pri);
15508  }
15509  pri_set_error(dahdi_pri_error);
15510  pri_set_message(dahdi_pri_message);
15511 #endif
15512 #if defined(HAVE_SS7)
15513  for (i = 0; i < NUM_SPANS; i++) {
15514  for (j = 0; j < SIG_SS7_NUM_DCHANS; j++)
15515  dahdi_close_ss7_fd(&(linksets[i]), j);
15516  }
15517 
15518  memset(linksets, 0, sizeof(linksets));
15519  for (i = 0; i < NUM_SPANS; i++) {
15520  sig_ss7_init_linkset(&linksets[i].ss7);
15521  }
15522  ss7_set_error(dahdi_ss7_error);
15523  ss7_set_message(dahdi_ss7_message);
15524  ss7_set_hangup(sig_ss7_cb_hangup);
15525  ss7_set_notinservice(sig_ss7_cb_notinservice);
15526  ss7_set_call_null(sig_ss7_cb_call_null);
15527 #endif /* defined(HAVE_SS7) */
15528 
15529  if (setup_dahdi(2) != 0) {
15530  ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n");
15532  return 1;
15533  }
15536  return 0;
15537 }
static ast_mutex_t restart_lock
Definition: chan_dahdi.c:643
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static ast_mutex_t ss_thread_lock
Definition: chan_dahdi.c:642
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
#define LOG_WARNING
Definition: logger.h:274
struct ast_channel * owner
Definition: chan_dahdi.h:127
static ast_cond_t ss_thread_complete
Definition: chan_dahdi.c:641
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_mutex_lock(a)
Definition: lock.h:187
static int setup_dahdi(int reload)
Definition: chan_dahdi.c:19642
void sig_ss7_cb_notinservice(struct ss7 *ss7, int cic, unsigned int dpc)
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
void sig_pri_init_pri(struct sig_pri_span *pri)
static void destroy_all_channels(void)
Definition: chan_dahdi.c:5667
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static ast_mutex_t monlock
Protect the monitoring thread, so only one process can kill or start it, and not when it&#39;s doing some...
Definition: chan_dahdi.c:636
#define ast_log
Definition: astobj2.c:42
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:640
static int ss_thread_count
Definition: chan_dahdi.c:644
#define AST_PTHREADT_NULL
Definition: lock.h:66
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
static void dahdi_softhangup_all(void)
Definition: chan_dahdi.c:15396
#define SIG_SS7_NUM_DCHANS
Definition: sig_ss7.h:56
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:241
void sig_ss7_init_linkset(struct sig_ss7_linkset *ss7)
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
#define AST_PTHREADT_STOP
Definition: lock.h:67
static struct dahdi_pvt * round_robin[32]
Definition: chan_dahdi.c:3429
#define NUM_SPANS
Definition: chan_dahdi.c:553
int sig_ss7_cb_hangup(struct ss7 *ss7, int cic, unsigned int dpc, int cause, int do_hangup)
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:499
#define ast_mutex_unlock(a)
Definition: lock.h:188
void sig_ss7_cb_call_null(struct ss7 *ss7, struct isup_call *c, int lock)

◆ dahdi_restart_cmd()

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

Definition at line 15539 of file chan_dahdi.c.

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

15540 {
15541  switch (cmd) {
15542  case CLI_INIT:
15543  e->command = "dahdi restart";
15544  e->usage =
15545  "Usage: dahdi restart\n"
15546  " Restarts the DAHDI channels: destroys them all and then\n"
15547  " re-reads them from chan_dahdi.conf.\n"
15548  " Note that this will STOP any running CALL on DAHDI channels.\n"
15549  "";
15550  return NULL;
15551  case CLI_GENERATE:
15552  return NULL;
15553  }
15554  if (a->argc != 2)
15555  return CLI_SHOWUSAGE;
15556 
15557  if (dahdi_restart() != 0)
15558  return CLI_FAILURE;
15559  return CLI_SUCCESS;
15560 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
static int dahdi_restart(void)
Definition: chan_dahdi.c:15424
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ dahdi_ring_phone()

static int dahdi_ring_phone ( struct dahdi_pvt p)
static

Definition at line 7101 of file chan_dahdi.c.

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

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

7102 {
7103  int x;
7104  int res;
7105  /* Make sure our transmit state is on hook */
7106  x = 0;
7107  x = DAHDI_ONHOOK;
7108  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
7109  do {
7110  x = DAHDI_RING;
7111  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
7112  if (res) {
7113  switch (errno) {
7114  case EBUSY:
7115  case EINTR:
7116  /* Wait just in case */
7117  usleep(10000);
7118  continue;
7119  case EINPROGRESS:
7120  res = 0;
7121  break;
7122  default:
7123  ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
7124  res = 0;
7125  }
7126  }
7127  } while (res);
7128  return res;
7129 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57

◆ dahdi_sendtext()

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

Definition at line 19777 of file chan_dahdi.c.

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, 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(), and TRAILER_MS.

Referenced by dahdi_chan_conf_default().

19778 {
19779 #define END_SILENCE_LEN 400
19780 #define HEADER_MS 50
19781 #define TRAILER_MS 5
19782 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
19783 #define ASCII_BYTES_PER_CHAR 80
19784 
19785  unsigned char *buf,*mybuf;
19786  struct dahdi_pvt *p = ast_channel_tech_pvt(c);
19787  struct pollfd fds[1];
19788  int size,res,fd,len,x;
19789  int bytes=0;
19790  int idx;
19791 
19792  /*
19793  * Initial carrier (imaginary)
19794  *
19795  * Note: The following float variables are used by the
19796  * PUT_CLID_MARKMS and PUT_CLID() macros.
19797  */
19798  float cr = 1.0;
19799  float ci = 0.0;
19800  float scont = 0.0;
19801 
19802  if (!text[0]) {
19803  return(0); /* if nothing to send, don't */
19804  }
19805  idx = dahdi_get_index(c, p, 0);
19806  if (idx < 0) {
19807  ast_log(LOG_WARNING, "Huh? I don't exist?\n");
19808  return -1;
19809  }
19810  if ((!p->tdd) && (!p->mate)) {
19811 #if defined(HAVE_PRI)
19812 #if defined(HAVE_PRI_DISPLAY_TEXT)
19813  ast_mutex_lock(&p->lock);
19814  if (dahdi_sig_pri_lib_handles(p->sig)) {
19815  sig_pri_sendtext(p->sig_pvt, text);
19816  }
19817  ast_mutex_unlock(&p->lock);
19818 #endif /* defined(HAVE_PRI_DISPLAY_TEXT) */
19819 #endif /* defined(HAVE_PRI) */
19820  return(0); /* if not in TDD mode, just return */
19821  }
19822  if (p->mate)
19823  buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
19824  else
19825  buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
19826  if (!buf)
19827  return -1;
19828  mybuf = buf;
19829  if (p->mate) {
19830  /* PUT_CLI_MARKMS is a macro and requires a format ptr called codec to be present */
19831  struct ast_format *codec = AST_LAW(p);
19832 
19833  for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */
19835  }
19836  /* Put actual message */
19837  for (x = 0; text[x]; x++) {
19838  PUT_CLID(text[x]);
19839  }
19840  for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */
19842  }
19843  len = bytes;
19844  buf = mybuf;
19845  } else {
19846  len = tdd_generate(p->tdd, buf, text);
19847  if (len < 1) {
19848  ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
19849  ast_free(mybuf);
19850  return -1;
19851  }
19852  }
19853  memset(buf + len, 0x7f, END_SILENCE_LEN);
19854  len += END_SILENCE_LEN;
19855  fd = p->subs[idx].dfd;
19856  while (len) {
19857  if (ast_check_hangup(c)) {
19858  ast_free(mybuf);
19859  return -1;
19860  }
19861  size = len;
19862  if (size > READ_SIZE)
19863  size = READ_SIZE;
19864  fds[0].fd = fd;
19865  fds[0].events = POLLOUT | POLLPRI;
19866  fds[0].revents = 0;
19867  res = poll(fds, 1, -1);
19868  if (!res) {
19869  ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel);
19870  continue;
19871  }
19872  /* if got exception */
19873  if (fds[0].revents & POLLPRI) {
19874  ast_free(mybuf);
19875  return -1;
19876  }
19877  if (!(fds[0].revents & POLLOUT)) {
19878  ast_debug(1, "write fd not ready on channel %d\n", p->channel);
19879  continue;
19880  }
19881  res = write(fd, buf, size);
19882  if (res != size) {
19883  if (res == -1) {
19884  ast_free(mybuf);
19885  return -1;
19886  }
19887  ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
19888  break;
19889  }
19890  len -= size;
19891  buf += size;
19892  }
19893  ast_free(mybuf);
19894  return(0);
19895 }
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define HEADER_MS
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define TDD_BYTES_PER_CHAR
Definition: tdd.h:27
#define LOG_WARNING
Definition: logger.h:274
#define ASCII_BYTES_PER_CHAR
#define HEADER_LEN
void * sig_pvt
Definition: chan_dahdi.h:709
Definition of a media format.
Definition: format.c:43
#define TRAILER_MS
#define ast_mutex_lock(a)
Definition: lock.h:187
char * text
Definition: app_queue.c:1508
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
ast_mutex_t lock
Definition: chan_dahdi.h:125
#define AST_LAW(p)
Definition: chan_dahdi.c:521
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
struct ast_codec * codec
Pointer to the codec in use for this format.
Definition: format.c:47
#define READ_SIZE
Definition: chan_dahdi.c:673
#define ast_free(a)
Definition: astmm.h:182
#define END_SILENCE_LEN
#define PUT_CLID(byte)
Definition: callerid.h:304
struct tdd_state * tdd
Definition: chan_dahdi.h:647
#define PUT_CLID_MARKMS
Definition: callerid.h:289
int tdd_generate(struct tdd_state *tdd, unsigned char *buf, const char *string)
Definition: tdd.c:297
int channel
Definition: chan_dahdi.h:538
unsigned int mate
TRUE if TDD in MATE mode.
Definition: chan_dahdi.h:288
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_set_dnd()

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

Definition at line 16163 of file chan_dahdi.c.

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

16164 {
16165  int channel;
16166  int on;
16167  struct dahdi_pvt *dahdi_chan = NULL;
16168 
16169  switch (cmd) {
16170  case CLI_INIT:
16171  e->command = "dahdi set dnd";
16172  e->usage =
16173  "Usage: dahdi set dnd <chan#> <on|off>\n"
16174  " Sets/resets DND (Do Not Disturb) mode on a channel.\n"
16175  " Changes take effect immediately.\n"
16176  " <chan num> is the channel number\n"
16177  " <on|off> Enable or disable DND mode?\n"
16178  ;
16179  return NULL;
16180  case CLI_GENERATE:
16181  return NULL;
16182  }
16183 
16184  if (a->argc != 5)
16185  return CLI_SHOWUSAGE;
16186 
16187  if ((channel = atoi(a->argv[3])) <= 0) {
16188  ast_cli(a->fd, "Expected channel number, got '%s'\n", a->argv[3]);
16189  return CLI_SHOWUSAGE;
16190  }
16191 
16192  if (ast_true(a->argv[4]))
16193  on = 1;
16194  else if (ast_false(a->argv[4]))
16195  on = 0;
16196  else {
16197  ast_cli(a->fd, "Expected 'on' or 'off', got '%s'\n", a->argv[4]);
16198  return CLI_SHOWUSAGE;
16199  }
16200 
16202  for (dahdi_chan = iflist; dahdi_chan; dahdi_chan = dahdi_chan->next) {
16203  if (dahdi_chan->channel != channel)
16204  continue;
16205 
16206  /* Found the channel. Actually set it */
16207  dahdi_dnd(dahdi_chan, on);
16208  break;
16209  }
16211 
16212  if (!dahdi_chan) {
16213  ast_cli(a->fd, "Unable to find given channel %d\n", channel);
16214  return CLI_FAILURE;
16215  }
16216 
16217  return CLI_SUCCESS;
16218 }
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
Definition: muted.c:95
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
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:9466
const int fd
Definition: cli.h:159
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
const char *const * argv
Definition: cli.h:161
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: main/utils.c:1968
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_set_hook()

static int dahdi_set_hook ( int  fd,
int  hs 
)
inlinestatic

Definition at line 4922 of file chan_dahdi.c.

References ast_log, errno, and LOG_WARNING.

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

4923 {
4924  int x, res;
4925 
4926  x = hs;
4927  res = ioctl(fd, DAHDI_HOOK, &x);
4928 
4929  if (res < 0) {
4930  if (errno == EINPROGRESS)
4931  return 0;
4932  ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno));
4933  /* will expectedly fail if phone is off hook during operation, such as during a restart */
4934  }
4935 
4936  return res;
4937 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
int errno

◆ dahdi_set_hwgain()

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

Definition at line 16006 of file chan_dahdi.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_subchannel::dfd, errno, ast_cli_args::fd, dahdi_pvt::hwrxgain, dahdi_pvt::hwrxgain_enabled, dahdi_pvt::hwtxgain, dahdi_pvt::hwtxgain_enabled, iflock, dahdi_pvt::next, NULL, set_hwgain(), SUB_REAL, dahdi_pvt::subs, tmp(), and ast_cli_entry::usage.

16007 {
16008  int channel;
16009  float gain;
16010  int tx;
16011  struct dahdi_pvt *tmp = NULL;
16012 
16013  switch (cmd) {
16014  case CLI_INIT:
16015  e->command = "dahdi set hwgain {rx|tx}";
16016  e->usage =
16017  "Usage: dahdi set hwgain <rx|tx> <chan#> <gain>\n"
16018  " Sets the hardware gain on a given channel and overrides the\n"
16019  " value provided at module loadtime. Changes take effect\n"
16020  " immediately whether the channel is in use or not.\n"
16021  "\n"
16022  " <rx|tx> which direction do you want to change (relative to our module)\n"
16023  " <chan num> is the channel number relative to the device\n"
16024  " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"
16025  "\n"
16026  " Please note:\n"
16027  " * hwgain is only supportable by hardware with analog ports because\n"
16028  " hwgain works on the analog side of an analog-digital conversion.\n";
16029  return NULL;
16030  case CLI_GENERATE:
16031  return NULL;
16032  }
16033 
16034  if (a->argc != 6)
16035  return CLI_SHOWUSAGE;
16036 
16037  if (!strcasecmp("rx", a->argv[3]))
16038  tx = 0; /* rx */
16039  else if (!strcasecmp("tx", a->argv[3]))
16040  tx = 1; /* tx */
16041  else
16042  return CLI_SHOWUSAGE;
16043 
16044  channel = atoi(a->argv[4]);
16045  gain = atof(a->argv[5]);
16046 
16048 
16049  for (tmp = iflist; tmp; tmp = tmp->next) {
16050 
16051  if (tmp->channel != channel)
16052  continue;
16053 
16054  if (tmp->subs[SUB_REAL].dfd == -1)
16055  break;
16056 
16057  if (set_hwgain(tmp->subs[SUB_REAL].dfd, gain, tx)) {
16058  ast_cli(a->fd, "Unable to set the hardware gain for channel %d: %s\n", channel, strerror(errno));
16060  return CLI_FAILURE;
16061  }
16062  ast_cli(a->fd, "Hardware %s gain set to %.1f dB on channel %d.\n",
16063  tx ? "tx" : "rx", gain, channel);
16064 
16065  if (tx) {
16066  tmp->hwtxgain_enabled = 1;
16067  tmp->hwtxgain = gain;
16068  } else {
16069  tmp->hwrxgain_enabled = 1;
16070  tmp->hwrxgain = gain;
16071  }
16072  break;
16073  }
16074 
16076 
16077  if (tmp)
16078  return CLI_SUCCESS;
16079 
16080  ast_cli(a->fd, "Unable to find given channel %d\n", channel);
16081  return CLI_FAILURE;
16082 
16083 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
const int argc
Definition: cli.h:160
static int tmp()
Definition: bt_open.c:389
Definition: cli.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
unsigned int hwtxgain_enabled
TRUE if hardware Tx gain set by Asterisk.
Definition: chan_dahdi.h:422
static int set_hwgain(int fd, float gain, int tx_direction)
Definition: chan_dahdi.c:4728
const int fd
Definition: cli.h:159
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
float hwtxgain
Hardware Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:155
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
float hwrxgain
Hardware Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:153
unsigned int hwrxgain_enabled
TRUE if hardware Rx gain set by Asterisk.
Definition: chan_dahdi.h:420
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_set_swgain()

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

Definition at line 16085 of file chan_dahdi.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_subchannel::dfd, ast_cli_args::fd, iflock, dahdi_pvt::law, dahdi_pvt::next, NULL, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, set_actual_rxgain(), set_actual_txgain(), SUB_REAL, dahdi_pvt::subs, tmp(), dahdi_pvt::txdrc, dahdi_pvt::txgain, and ast_cli_entry::usage.

16086 {
16087  int channel;
16088  float gain;
16089  int tx;
16090  int res;
16091  struct dahdi_pvt *tmp = NULL;
16092 
16093  switch (cmd) {
16094  case CLI_INIT:
16095  e->command = "dahdi set swgain {rx|tx}";
16096  e->usage =
16097  "Usage: dahdi set swgain <rx|tx> <chan#> <gain>\n"
16098  " Sets the software gain on a given channel and overrides the\n"
16099  " value provided at module loadtime. Changes take effect\n"
16100  " immediately whether the channel is in use or not.\n"
16101  "\n"
16102  " <rx|tx> which direction do you want to change (relative to our module)\n"
16103  " <chan num> is the channel number relative to the device\n"
16104  " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n";
16105  return NULL;
16106  case CLI_GENERATE:
16107  return NULL;
16108  }
16109 
16110  if (a->argc != 6)
16111  return CLI_SHOWUSAGE;
16112 
16113  if (!strcasecmp("rx", a->argv[3]))
16114  tx = 0; /* rx */
16115  else if (!strcasecmp("tx", a->argv[3]))
16116  tx = 1; /* tx */
16117  else
16118  return CLI_SHOWUSAGE;
16119 
16120  channel = atoi(a->argv[4]);
16121  gain = atof(a->argv[5]);
16122 
16124  for (tmp = iflist; tmp; tmp = tmp->next) {
16125 
16126  if (tmp->channel != channel)
16127  continue;
16128 
16129  if (tmp->subs[SUB_REAL].dfd == -1)
16130  break;
16131 
16132  if (tx)
16133  res = set_actual_txgain(tmp->subs[SUB_REAL].dfd, gain, tmp->txdrc, tmp->law);
16134  else
16135  res = set_actual_rxgain(tmp->subs[SUB_REAL].dfd, gain, tmp->rxdrc, tmp->law);
16136 
16137  if (res) {
16138  ast_cli(a->fd, "Unable to set the software gain for channel %d\n", channel);
16140  return CLI_FAILURE;
16141  }
16142 
16143  ast_cli(a->fd, "Software %s gain set to %.2f dB on channel %d.\n",
16144  tx ? "tx" : "rx", gain, channel);
16145 
16146  if (tx) {
16147  tmp->txgain = gain;
16148  } else {
16149  tmp->rxgain = gain;
16150  }
16151  break;
16152  }
16154 
16155  if (tmp)
16156  return CLI_SUCCESS;
16157 
16158  ast_cli(a->fd, "Unable to find given channel %d\n", channel);
16159  return CLI_FAILURE;
16160 
16161 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
const int argc
Definition: cli.h:160
float txdrc
Definition: chan_dahdi.h:163
static int tmp()
Definition: bt_open.c:389
Definition: cli.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
int law
Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:509
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
float txgain
Software Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:161
const int fd
Definition: cli.h:159
float rxdrc
Definition: chan_dahdi.h:164
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define SUB_REAL
Definition: chan_dahdi.h:57
static int set_actual_txgain(int fd, float gain, float drc, int law)
Definition: chan_dahdi.c:4856
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
static int set_actual_rxgain(int fd, float gain, float drc, int law)
Definition: chan_dahdi.c:4873
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
float rxgain
Software Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:159
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_setlinear()

static int dahdi_setlinear ( int  dfd,
int  linear 
)
static

Definition at line 4161 of file chan_dahdi.c.

Referenced by analog_ss_thread(), dahdi_dial_str(), 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().

4162 {
4163  return ioctl(dfd, DAHDI_SETLINEAR, &linear);
4164 }

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

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.

Referenced by dahdi_chan_conf_default().

6546 {
6547  char *cp;
6548  signed char *scp;
6549  int x;
6550  int idx;
6551  struct dahdi_pvt *p = ast_channel_tech_pvt(chan), *pp;
6552  struct oprmode *oprmode;
6553 
6554 
6555  /* all supported options require data */
6556  if (!p || !data || (datalen < 1)) {
6557  errno = EINVAL;
6558  return -1;
6559  }
6560 
6561  switch (option) {
6562  case AST_OPTION_TXGAIN:
6563  scp = (signed char *) data;
6564  idx = dahdi_get_index(chan, p, 0);
6565  if (idx < 0) {
6566  ast_log(LOG_WARNING, "No index in TXGAIN?\n");
6567  return -1;
6568  }
6569  ast_debug(1, "Setting actual tx gain on %s to %f\n", ast_channel_name(chan), p->txgain + (float) *scp);
6570  return set_actual_txgain(p->subs[idx].dfd, p->txgain + (float) *scp, p->txdrc, p->law);
6571  case AST_OPTION_RXGAIN:
6572  scp = (signed char *) data;
6573  idx = dahdi_get_index(chan, p, 0);
6574  if (idx < 0) {
6575  ast_log(LOG_WARNING, "No index in RXGAIN?\n");
6576  return -1;
6577  }
6578  ast_debug(1, "Setting actual rx gain on %s to %f\n", ast_channel_name(chan), p->rxgain + (float) *scp);
6579  return set_actual_rxgain(p->subs[idx].dfd, p->rxgain + (float) *scp, p->rxdrc, p->law);
6581  if (!p->dsp)
6582  break;
6583  cp = (char *) data;
6584  switch (*cp) {
6585  case 1:
6586  ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",ast_channel_name(chan));
6587  ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */
6588  break;
6589  case 2:
6590  ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",ast_channel_name(chan));
6591  ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */
6592  break;
6593  default:
6594  ast_debug(1, "Set option TONE VERIFY, mode: OFF(0) on %s\n",ast_channel_name(chan));
6595  ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */
6596  break;
6597  }
6598  break;
6599  case AST_OPTION_TDD:
6600  /* turn on or off TDD */
6601  cp = (char *) data;
6602  p->mate = 0;
6603  if (!*cp) { /* turn it off */
6604  ast_debug(1, "Set option TDD MODE, value: OFF(0) on %s\n",ast_channel_name(chan));
6605  if (p->tdd)
6606  tdd_free(p->tdd);
6607  p->tdd = 0;
6608  break;
6609  }
6610  ast_debug(1, "Set option TDD MODE, value: %s(%d) on %s\n",
6611  (*cp == 2) ? "MATE" : "ON", (int) *cp, ast_channel_name(chan));
6612  dahdi_ec_disable(p);
6613  /* otherwise, turn it on */
6614  if (!p->didtdd) { /* if havent done it yet */
6615  unsigned char mybuf[41000];/*! \todo XXX This is an abuse of the stack!! */
6616  unsigned char *buf;
6617  int size, res, fd, len;
6618  struct pollfd fds[1];
6619 
6620  buf = mybuf;
6621  memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
6622  ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */
6623  len = 40000;
6624  idx = dahdi_get_index(chan, p, 0);
6625  if (idx < 0) {
6626  ast_log(LOG_WARNING, "No index in TDD?\n");
6627  return -1;
6628  }
6629  fd = p->subs[idx].dfd;
6630  while (len) {
6631  if (ast_check_hangup(chan))
6632  return -1;
6633  size = len;
6634  if (size > READ_SIZE)
6635  size = READ_SIZE;
6636  fds[0].fd = fd;
6637  fds[0].events = POLLPRI | POLLOUT;
6638  fds[0].revents = 0;
6639  res = poll(fds, 1, -1);
6640  if (!res) {
6641  ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel);
6642  continue;
6643  }
6644  /* if got exception */
6645  if (fds[0].revents & POLLPRI)
6646  return -1;
6647  if (!(fds[0].revents & POLLOUT)) {
6648  ast_debug(1, "write fd not ready on channel %d\n", p->channel);
6649  continue;
6650  }
6651  res = write(fd, buf, size);
6652  if (res != size) {
6653  if (res == -1) return -1;
6654  ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
6655  break;
6656  }
6657  len -= size;
6658  buf += size;
6659  }
6660  p->didtdd = 1; /* set to have done it now */
6661  }
6662  if (*cp == 2) { /* Mate mode */
6663  if (p->tdd)
6664  tdd_free(p->tdd);
6665  p->tdd = 0;
6666  p->mate = 1;
6667  break;
6668  }
6669  if (!p->tdd) { /* if we don't have one yet */
6670  p->tdd = tdd_new(); /* allocate one */
6671  }
6672  break;
6673  case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */
6674  if (!p->dsp)
6675  break;
6676  cp = (char *) data;
6677  ast_debug(1, "Set option RELAX DTMF, value: %s(%d) on %s\n",
6678  *cp ? "ON" : "OFF", (int) *cp, ast_channel_name(chan));
6680  break;
6681  case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */
6682 #if defined(HAVE_PRI)
6684  && ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
6685  /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */
6686  break;
6687  }
6688 #endif /* defined(HAVE_PRI) */
6689 
6690  cp = (char *) data;
6691  if (!*cp) {
6692  ast_debug(1, "Set option AUDIO MODE, value: OFF(0) on %s\n", ast_channel_name(chan));
6693  x = 0;
6694  dahdi_ec_disable(p);
6695  } else {
6696  ast_debug(1, "Set option AUDIO MODE, value: ON(1) on %s\n", ast_channel_name(chan));
6697  x = 1;
6698  }
6699  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x) == -1)
6700  ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, x, strerror(errno));
6701  break;
6702  case AST_OPTION_OPRMODE: /* Operator services mode */
6703  oprmode = (struct oprmode *) data;
6704  /* We don't support operator mode across technologies */
6705  if (strcasecmp(ast_channel_tech(chan)->type, ast_channel_tech(oprmode->peer)->type)) {
6706  ast_log(LOG_NOTICE, "Operator mode not supported on %s to %s calls.\n",
6707  ast_channel_tech(chan)->type, ast_channel_tech(oprmode->peer)->type);
6708  errno = EINVAL;
6709  return -1;
6710  }
6711  pp = ast_channel_tech_pvt(oprmode->peer);
6712  p->oprmode = pp->oprmode = 0;
6713  /* setup peers */
6714  p->oprpeer = pp;
6715  pp->oprpeer = p;
6716  /* setup modes, if any */
6717  if (oprmode->mode)
6718  {
6719  pp->oprmode = oprmode->mode;
6720  p->oprmode = -oprmode->mode;
6721  }
6722  ast_debug(1, "Set Operator Services mode, value: %d on %s/%s\n",
6723  oprmode->mode, ast_channel_name(chan),ast_channel_name(oprmode->peer));
6724  break;
6725  case AST_OPTION_ECHOCAN:
6726  cp = (char *) data;
6727  if (*cp) {
6728  ast_debug(1, "Enabling echo cancellation on %s\n", ast_channel_name(chan));
6729  dahdi_ec_enable(p);
6730  } else {
6731  ast_debug(1, "Disabling echo cancellation on %s\n", ast_channel_name(chan));
6732  dahdi_ec_disable(p);
6733  }
6734  break;
6736  cp = (char *) data;
6737  ast_debug(1, "%sabling digit detection on %s\n", *cp ? "En" : "Dis", ast_channel_name(chan));
6738  if (*cp) {
6740  } else {
6742  }
6743  break;
6744  case AST_OPTION_FAX_DETECT:
6745  cp = (char *) data;
6746  if (p->dsp) {
6747  ast_debug(1, "%sabling fax tone detection on %s\n", *cp ? "En" : "Dis", ast_channel_name(chan));
6748  if (*cp) {
6750  } else {
6752  }
6754  }
6755  break;
6756  default:
6757  return -1;
6758  }
6759  errno = 0;
6760 
6761  return 0;
6762 }
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
static const char type[]
Definition: chan_ooh323.c:109
int dtmfrelax
Definition: chan_dahdi.h:665
void dahdi_dtmf_detect_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:6473
const char *const type
Definition: channel.h:630
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
#define AST_OPTION_TXGAIN
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void dahdi_ec_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4638
#define DSP_DIGITMODE_MUTECONF
Definition: dsp.h:35
#define AST_OPTION_OPRMODE
#define LOG_WARNING
Definition: logger.h:274
float txdrc
Definition: chan_dahdi.h:163
int dsp_features
DSP feature flags: DSP_FEATURE_xxx.
Definition: chan_dahdi.h:683
void * sig_pvt
Definition: chan_dahdi.h:709
void dahdi_ec_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4710
#define AST_OPTION_TDD
int law
Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:509
struct dahdi_pvt * oprpeer
Definition: chan_dahdi.h:151
float txgain
Software Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:161
int oprmode
Definition: chan_dahdi.h:150
#define DSP_DIGITMODE_RELAXDTMF
Definition: dsp.h:37
unsigned int didtdd
Definition: chan_dahdi.h:227
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_tdd_gen_ecdisa(unsigned char *outbuf, int len)
Definition: tdd.c:148
#define AST_OPTION_RELAXDTMF
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
float rxdrc
Definition: chan_dahdi.h:164
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
#define AST_OPTION_ECHOCAN
#define AST_OPTION_DIGIT_DETECT
#define DSP_DIGITMODE_MUTEMAX
Definition: dsp.h:36
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
#define AST_OPTION_RXGAIN
struct tdd_state * tdd_new(void)
Definition: tdd.c:103
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define READ_SIZE
Definition: chan_dahdi.c:673
#define LOG_NOTICE
Definition: logger.h:263
static int set_actual_txgain(int fd, float gain, float drc, int law)
Definition: chan_dahdi.c:4856
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
#define AST_OPTION_AUDIO_MODE
void dahdi_dtmf_detect_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:6487
struct ast_channel * peer
static int set_actual_rxgain(int fd, float gain, float drc, int law)
Definition: chan_dahdi.c:4873
struct tdd_state * tdd
Definition: chan_dahdi.h:647
#define AST_OPTION_FAX_DETECT
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_OPTION_TONE_VERIFY
float rxgain
Software Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:159
void tdd_free(struct tdd_state *tdd)
Definition: tdd.c:218
int channel
Definition: chan_dahdi.h:538
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
unsigned int mate
TRUE if TDD in MATE mode.
Definition: chan_dahdi.h:288
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1844

◆ dahdi_show_channel()

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

Definition at line 15650 of file chan_dahdi.c.

References sig_pri_chan::allocated, ast_cli_args::argc, ast_cli_args::argv, ast_channel_name(), ast_cli(), ast_copy_string(), ast_log, ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::busy_cadence, dahdi_pvt::busycount, dahdi_pvt::busydetect, sig_pri_chan::call, dahdi_pvt::callwaitcas, dahdi_pvt::channel, sig_ss7_chan::cic, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_subaddr, dahdi_pvt::cid_ton, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_pvt::confno, dahdi_pvt::context, dahdi_dnd(), dahdi_pvt::description, dahdi_pvt::destroy, dahdi_subchannel::dfd, dahdi_pvt::dialing, dahdi_pvt::dsp, dahdi_pvt::dtmfrelax, dahdi_pvt::echocanbridged, dahdi_pvt::echocancel, dahdi_pvt::echocanon, errno, dahdi_pvt::exten, dahdi_pvt::faxhandled, ast_cli_args::fd, dahdi_pvt::head, dahdi_pvt::hwrxgain, dahdi_pvt::hwrxgain_enabled, dahdi_pvt::hwtxgain, dahdi_pvt::hwtxgain_enabled, iflock, dahdi_pvt::inalarm, dahdi_pvt::inconference, dahdi_subchannel::inthreeway, dahdi_pvt::law_default, ast_dsp_busy_pattern::length, dahdi_subchannel::linear, LOG_WARNING, dahdi_pvt::mailbox, dahdi_pvt::master, MAX_SLAVES, ast_variable::name, ast_variable::next, dahdi_pvt::next, NULL, dahdi_subchannel::owner, dahdi_pvt::owner, dahdi_pvt::params, ast_dsp_busy_pattern::pattern, dahdi_pvt::propconfno, dahdi_pvt::pulsedial, dahdi_pvt::radio, sig_pri_chan::resetting, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, S_OR, dahdi_pvt::sig, sig2str, SIG_PRI_RESET_IDLE, dahdi_pvt::sig_pvt, dahdi_pvt::slaves, dahdi_pvt::span, SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, dahdi_pvt::subs, dahdi_pvt::tdd, tmp(), dahdi_pvt::txdrc, dahdi_pvt::txgain, ast_cli_entry::usage, ast_variable::value, dahdi_pvt::vars, and dahdi_pvt::waitfordialtone.

15651 {
15652  int channel;
15653  struct dahdi_pvt *tmp = NULL;
15654  struct dahdi_confinfo ci;
15655  struct dahdi_params ps;
15656  int x;
15657  char hwrxgain[15];
15658  char hwtxgain[15];
15659 
15660  switch (cmd) {
15661  case CLI_INIT:
15662  e->command = "dahdi show channel";
15663  e->usage =
15664  "Usage: dahdi show channel <chan num>\n"
15665  " Detailed information about a given channel\n";
15666  return NULL;
15667  case CLI_GENERATE:
15668  return NULL;
15669  }
15670 
15671  if (a->argc != 4)
15672  return CLI_SHOWUSAGE;
15673 
15674  channel = atoi(a->argv[3]);
15675 
15677  for (tmp = iflist; tmp; tmp = tmp->next) {
15678  if (tmp->channel == channel) {
15679  ast_cli(a->fd, "Channel: %d\n", tmp->channel);
15680  ast_cli(a->fd, "Description: %s\n", tmp->description);
15681  ast_cli(a->fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].dfd);
15682  ast_cli(a->fd, "Span: %d\n", tmp->span);
15683  ast_cli(a->fd, "Extension: %s\n", tmp->exten);
15684  ast_cli(a->fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
15685  ast_cli(a->fd, "Context: %s\n", tmp->context);
15686  ast_cli(a->fd, "Caller ID: %s\n", tmp->cid_num);
15687  ast_cli(a->fd, "Calling TON: %d\n", tmp->cid_ton);
15688 #if defined(HAVE_PRI)
15689 #if defined(HAVE_PRI_SUBADDR)
15690  ast_cli(a->fd, "Caller ID subaddress: %s\n", tmp->cid_subaddr);
15691 #endif /* defined(HAVE_PRI_SUBADDR) */
15692 #endif /* defined(HAVE_PRI) */
15693  ast_cli(a->fd, "Caller ID name: %s\n", tmp->cid_name);
15694  ast_cli(a->fd, "Mailbox: %s\n", S_OR(tmp->mailbox, "none"));
15695  if (tmp->vars) {
15696  struct ast_variable *v;
15697  ast_cli(a->fd, "Variables:\n");
15698  for (v = tmp->vars ; v ; v = v->next)
15699  ast_cli(a->fd, " %s = %s\n", v->name, v->value);
15700  }
15701  ast_cli(a->fd, "Destroy: %d\n", tmp->destroy);
15702  ast_cli(a->fd, "InAlarm: %d\n", tmp->inalarm);
15703  ast_cli(a->fd, "Signalling Type: %s\n", sig2str(tmp->sig));
15704  ast_cli(a->fd, "Radio: %d\n", tmp->radio);
15705  ast_cli(a->fd, "Owner: %s\n", tmp->owner ? ast_channel_name(tmp->owner) : "<None>");
15706  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)" : "");
15707  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)" : "");
15708  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)" : "");
15709  ast_cli(a->fd, "Confno: %d\n", tmp->confno);
15710  ast_cli(a->fd, "Propagated Conference: %d\n", tmp->propconfno);
15711  ast_cli(a->fd, "Real in conference: %d\n", tmp->inconference);
15712  ast_cli(a->fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
15713  ast_cli(a->fd, "Busy Detection: %s\n", tmp->busydetect ? "yes" : "no");
15714  if (tmp->busydetect) {
15715 #if defined(BUSYDETECT_TONEONLY)
15716  ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_TONEONLY\n");
15717 #elif defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
15718  ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_COMPARE_TONE_AND_SILENCE\n");
15719 #endif
15720 #ifdef BUSYDETECT_DEBUG
15721  ast_cli(a->fd, " Busy Detector Debug: Enabled\n");
15722 #endif
15723  ast_cli(a->fd, " Busy Count: %d\n", tmp->busycount);
15724  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);
15725  }
15726  ast_cli(a->fd, "TDD: %s\n", tmp->tdd ? "yes" : "no");
15727  ast_cli(a->fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
15728  ast_cli(a->fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
15729  ast_cli(a->fd, "Default law: %s\n", tmp->law_default == DAHDI_LAW_MULAW ? "ulaw" : tmp->law_default == DAHDI_LAW_ALAW ? "alaw" : "unknown");
15730  ast_cli(a->fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
15731  ast_cli(a->fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
15732  if (tmp->hwrxgain_enabled) {
15733  snprintf(hwrxgain, sizeof(hwrxgain), "%.1f", tmp->hwrxgain);
15734  } else {
15735  ast_copy_string(hwrxgain, "Disabled", sizeof(hwrxgain));
15736  }
15737  if (tmp->hwtxgain_enabled) {
15738  snprintf(hwtxgain, sizeof(hwtxgain), "%.1f", tmp->hwtxgain);
15739  } else {
15740  ast_copy_string(hwtxgain, "Disabled", sizeof(hwtxgain));
15741  }
15742  ast_cli(a->fd, "HW Gains (RX/TX): %s/%s\n", hwrxgain, hwtxgain);
15743  ast_cli(a->fd, "SW Gains (RX/TX): %.2f/%.2f\n", tmp->rxgain, tmp->txgain);
15744  ast_cli(a->fd, "Dynamic Range Compression (RX/TX): %.2f/%.2f\n", tmp->rxdrc, tmp->txdrc);
15745  ast_cli(a->fd, "DND: %s\n", dahdi_dnd(tmp, -1) ? "yes" : "no");
15746  ast_cli(a->fd, "Echo Cancellation:\n");
15747 
15748  if (tmp->echocancel.head.tap_length) {
15749  ast_cli(a->fd, "\t%u taps\n", tmp->echocancel.head.tap_length);
15750  for (x = 0; x < tmp->echocancel.head.param_count; x++) {
15751  ast_cli(a->fd, "\t\t%s: %dd\n", tmp->echocancel.params[x].name, tmp->echocancel.params[x].value);
15752  }
15753  ast_cli(a->fd, "\t%scurrently %s\n", tmp->echocanbridged ? "" : "(unless TDM bridged) ", tmp->echocanon ? "ON" : "OFF");
15754  } else {
15755  ast_cli(a->fd, "\tnone\n");
15756  }
15757  ast_cli(a->fd, "Wait for dialtone: %dms\n", tmp->waitfordialtone);
15758  if (tmp->master)
15759  ast_cli(a->fd, "Master Channel: %d\n", tmp->master->channel);
15760  for (x = 0; x < MAX_SLAVES; x++) {
15761  if (tmp->slaves[x])
15762  ast_cli(a->fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
15763  }
15764 #ifdef HAVE_OPENR2
15765  if (tmp->mfcr2) {
15766  char calldir[OR2_MAX_PATH];
15767  openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan);
15768  openr2_variant_t r2variant = openr2_context_get_variant(r2context);
15769  ast_cli(a->fd, "MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan));
15770  ast_cli(a->fd, "MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan));
15771  ast_cli(a->fd, "MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan));
15772  ast_cli(a->fd, "MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan));
15773  ast_cli(a->fd, "MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ? "Yes" : "No");
15774  ast_cli(a->fd, "MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant));
15775  ast_cli(a->fd, "MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context));
15776  ast_cli(a->fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context));
15777 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
15778  ast_cli(a->fd, "MFC/R2 DTMF Dialing: %s\n", openr2_context_get_dtmf_dialing(r2context, NULL, NULL) ? "Yes" : "No");
15779  ast_cli(a->fd, "MFC/R2 DTMF Detection: %s\n", openr2_context_get_dtmf_detection(r2context) ? "Yes" : "No");
15780 #endif
15781  ast_cli(a->fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No");
15782 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
15783  ast_cli(a->fd, "MFC/R2 Skip Category Request: %s\n", openr2_context_get_skip_category_request(r2context) ? "Yes" : "No");
15784 #endif
15785  ast_cli(a->fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No");
15786  ast_cli(a->fd, "MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No");
15787  ast_cli(a->fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No");
15788  ast_cli(a->fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No");
15789  ast_cli(a->fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No");
15790  ast_cli(a->fd, "MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context));
15791  ast_cli(a->fd, "MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context));
15792  ast_cli(a->fd, "MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan));
15793  ast_cli(a->fd, "MFC/R2 Tx CAS: %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan));
15794  ast_cli(a->fd, "MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan));
15795  ast_cli(a->fd, "MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan));
15796  ast_cli(a->fd, "MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir, sizeof(calldir)));
15797  }
15798 #endif
15799 #if defined(HAVE_SS7)
15800  if (tmp->ss7) {
15801  struct sig_ss7_chan *chan = tmp->sig_pvt;
15802 
15803  ast_cli(a->fd, "CIC: %d\n", chan->cic);
15804  }
15805 #endif /* defined(HAVE_SS7) */
15806 #ifdef HAVE_PRI
15807  if (tmp->pri) {
15808  struct sig_pri_chan *chan = tmp->sig_pvt;
15809 
15810  ast_cli(a->fd, "PRI Flags: ");
15811  if (chan->resetting != SIG_PRI_RESET_IDLE) {
15812  ast_cli(a->fd, "Resetting=%u ", chan->resetting);
15813  }
15814  if (chan->call)
15815  ast_cli(a->fd, "Call ");
15816  if (chan->allocated) {
15817  ast_cli(a->fd, "Allocated ");
15818  }
15819  ast_cli(a->fd, "\n");
15820  if (tmp->logicalspan)
15821  ast_cli(a->fd, "PRI Logical Span: %d\n", tmp->logicalspan);
15822  else
15823  ast_cli(a->fd, "PRI Logical Span: Implicit\n");
15824  }
15825 #endif
15826  memset(&ci, 0, sizeof(ci));
15827  ps.channo = tmp->channel;
15828  if (tmp->subs[SUB_REAL].dfd > -1) {
15829  memset(&ci, 0, sizeof(ci));
15830  if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
15831  ast_cli(a->fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, (unsigned)ci.confmode);
15832  }
15833  if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONFMUTE, &x)) {
15834  ast_cli(a->fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
15835  }
15836  memset(&ps, 0, sizeof(ps));
15837  if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
15838  ast_log(LOG_WARNING, "Failed to get parameters on channel %d: %s\n", tmp->channel, strerror(errno));
15839  } else {
15840  ast_cli(a->fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
15841  }
15842  }
15844  return CLI_SUCCESS;
15845  }
15846  }
15848 
15849  ast_cli(a->fd, "Unable to find given channel %d\n", channel);
15850  return CLI_FAILURE;
15851 }
struct ast_variable * next
char description[32]
A description for the channel configuration.
Definition: chan_dahdi.h:449
#define MAX_SLAVES
Definition: chan_dahdi.h:95
int dtmfrelax
Definition: chan_dahdi.h:665
char cid_subaddr[AST_MAX_EXTENSION]
Caller ID subaddress from an incoming call.
Definition: chan_dahdi.h:490
int cid_ton
Caller ID Q.931 TON/NPI field values. Set by PRI. Zero otherwise.
Definition: chan_dahdi.h:486
int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: chan_dahdi.h:575
unsigned int dialing
TRUE if in the process of dialing digits or sending something.
Definition: chan_dahdi.h:234
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
int pattern[4]
Definition: dsp.h:68
#define SUB_THREEWAY
Definition: chan_dahdi.h:59
struct dahdi_pvt * master
Definition: chan_dahdi.h:135
const int argc
Definition: cli.h:160
#define LOG_WARNING
Definition: logger.h:274
q931_call * call
Definition: sig_pri.h:358
float txdrc
Definition: chan_dahdi.h:163
struct ast_channel * owner
Definition: chan_dahdi.h:127
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
int law_default
Default call PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:507
Definition: cli.h:152
void * sig_pvt
Definition: chan_dahdi.h:709
enum sig_pri_reset_state resetting
Channel reset/restart state.
Definition: sig_pri.h:363
struct ast_dsp_busy_pattern busy_cadence
Busy cadence pattern description.
Definition: chan_dahdi.h:599
The channel is not being RESTARTed.
Definition: sig_pri.h:154
#define ast_mutex_lock(a)
Definition: lock.h:187
Definition: muted.c:95
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
float txgain
Software Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:161
int inconference
Definition: chan_dahdi.h:136
char cid_name[AST_MAX_EXTENSION]
Caller ID name from an incoming call.
Definition: chan_dahdi.h:488
unsigned int hwtxgain_enabled
TRUE if hardware Tx gain set by Asterisk.
Definition: chan_dahdi.h:422
#define ast_log
Definition: astobj2.c:42
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:9466
struct dahdi_pvt * slaves[MAX_SLAVES]
Definition: chan_dahdi.h:134
char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Voice mailbox location.
Definition: chan_dahdi.h:654
const int fd
Definition: cli.h:159
float rxdrc
Definition: chan_dahdi.h:164
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
struct ast_channel * owner
Definition: chan_dahdi.h:79
unsigned int busydetect
TRUE if busy detection is enabled. (Listens for the beep-beep busy pattern.)
Definition: chan_dahdi.h:189
unsigned int linear
Definition: chan_dahdi.h:90
const char *const * argv
Definition: cli.h:161
unsigned int inthreeway
Definition: chan_dahdi.h:91
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
int busycount
Number of times to see "busy" tone before hanging up.
Definition: chan_dahdi.h:594
unsigned int destroy
TRUE if the channel is to be destroyed on hangup. (Used by pseudo channels.)
Definition: chan_dahdi.h:226
unsigned int faxhandled
TRUE if a fax tone has already been handled.
Definition: chan_dahdi.h:250
struct dahdi_pvt::@110 echocancel
Echo cancel parameters.
char cid_num[AST_MAX_EXTENSION]
Caller ID number from an incoming call.
Definition: chan_dahdi.h:479
#define CLI_SHOWUSAGE
Definition: cli.h:45
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
int confno
Definition: chan_dahdi.h:510
int propconfno
Definition: chan_dahdi.h:512
char exten[AST_MAX_EXTENSION]
Extension to use in the dialplan.
Definition: chan_dahdi.h:455
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
char context[AST_MAX_CONTEXT]
The configured context for incoming calls.
Definition: chan_dahdi.h:444
struct dahdi_echocanparam params[DAHDI_MAX_ECHOCANPARAMS]
Definition: chan_dahdi.h:581
struct dahdi_echocanparams head
Definition: chan_dahdi.h:580
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
int waitfordialtone
Number of milliseconds to wait for dialtone.
Definition: chan_dahdi.h:609
struct tdd_state * tdd
Definition: chan_dahdi.h:647
float hwtxgain
Hardware Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:155
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
unsigned int echocanon
TRUE if echo cancellation is turned on.
Definition: chan_dahdi.h:248
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_variable * vars
Channel variable list with associated values to set when a channel is created.
Definition: chan_dahdi.h:537
unsigned int echocanbridged
TRUE if echo cancellation enabled when bridged.
Definition: chan_dahdi.h:246
float rxgain
Software Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:159
#define sig2str
Definition: chan_dahdi.c:4455
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
unsigned int allocated
TRUE when this channel is allocated.
Definition: sig_pri.h:341
float hwrxgain
Hardware Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:153
unsigned int hwrxgain_enabled
TRUE if hardware Rx gain set by Asterisk.
Definition: chan_dahdi.h:420
unsigned int inalarm
TRUE if in an alarm condition.
Definition: chan_dahdi.h:286
int channel
Definition: chan_dahdi.h:538
unsigned int pulsedial
TRUE if a pulsed digit was detected. (Pulse dial phone detected)
Definition: chan_dahdi.h:318
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define SUB_CALLWAIT
Definition: chan_dahdi.h:58

◆ dahdi_show_channels()

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

Definition at line 15572 of file chan_dahdi.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, dahdi_pvt::channel, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dahdi_pvt::context, dahdi_pvt::description, dahdi_pvt::exten, ast_cli_args::fd, FORMAT, FORMAT2, dahdi_pvt::group, iflock, dahdi_pvt::inservice, dahdi_pvt::language, dahdi_pvt::locallyblocked, dahdi_pvt::mohinterpret, dahdi_pvt::next, NULL, dahdi_pvt::remotelyblocked, tmp(), and ast_cli_entry::usage.

15573 {
15574 #define FORMAT "%7s %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n"
15575 #define FORMAT2 "%7s %-15.15s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n"
15576  ast_group_t targetnum = 0;
15577  int filtertype = 0;
15578  struct dahdi_pvt *tmp = NULL;
15579  char tmps[20];
15580  char blockstr[20];
15581 
15582  switch (cmd) {
15583  case CLI_INIT:
15584  e->command = "dahdi show channels [group|context]";
15585  e->usage =
15586  "Usage: dahdi show channels [ group <group> | context <context> ]\n"
15587  " Shows a list of available channels with optional filtering\n"
15588  " <group> must be a number between 0 and 63\n";
15589  return NULL;
15590  case CLI_GENERATE:
15591  return NULL;
15592  }
15593 
15594  /* syntax: dahdi show channels [ group <group> | context <context> ] */
15595 
15596  if (!((a->argc == 3) || (a->argc == 5))) {
15597  return CLI_SHOWUSAGE;
15598  }
15599 
15600  if (a->argc == 5) {
15601  if (!strcasecmp(a->argv[3], "group")) {
15602  targetnum = atoi(a->argv[4]);
15603  if (63 < targetnum) {
15604  return CLI_SHOWUSAGE;
15605  }
15606  targetnum = ((ast_group_t) 1) << targetnum;
15607  filtertype = 1;
15608  } else if (!strcasecmp(a->argv[3], "context")) {
15609  filtertype = 2;
15610  }
15611  }
15612 
15613  ast_cli(a->fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret", "Blocked", "In Service", "Description");
15615  for (tmp = iflist; tmp; tmp = tmp->next) {
15616  if (filtertype) {
15617  switch(filtertype) {
15618  case 1: /* dahdi show channels group <group> */
15619  if (!(tmp->group & targetnum)) {
15620  continue;
15621  }
15622  break;
15623  case 2: /* dahdi show channels context <context> */
15624  if (strcasecmp(tmp->context, a->argv[4])) {
15625  continue;
15626  }
15627  break;
15628  default:
15629  break;
15630  }
15631  }
15632  if (tmp->channel > 0) {
15633  snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
15634  } else {
15635  ast_copy_string(tmps, "pseudo", sizeof(tmps));
15636  }
15637 
15638  blockstr[0] = tmp->locallyblocked ? 'L' : ' ';
15639  blockstr[1] = tmp->remotelyblocked ? 'R' : ' ';
15640  blockstr[2] = '\0';
15641 
15642  ast_cli(a->fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret, blockstr, tmp->inservice ? "Yes" : "No", tmp->description);
15643  }
15645  return CLI_SUCCESS;
15646 #undef FORMAT
15647 #undef FORMAT2
15648 }
unsigned long long ast_group_t
Definition: channel.h:214
char description[32]
A description for the channel configuration.
Definition: chan_dahdi.h:449
#define FORMAT
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
const int argc
Definition: cli.h:160
unsigned int locallyblocked
Bitmask for the channel being locally blocked.
Definition: chan_dahdi.h:404
unsigned int inservice
TRUE if channel is out of reset and ready.
Definition: chan_dahdi.h:395
static int tmp()
Definition: bt_open.c:389
Definition: cli.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
const char *const * argv
Definition: cli.h:161
char mohinterpret[MAX_MUSICCLASS]
The configured music-on-hold class to use for calls.
Definition: chan_dahdi.h:465
#define CLI_SHOWUSAGE
Definition: cli.h:45
char exten[AST_MAX_EXTENSION]
Extension to use in the dialplan.
Definition: chan_dahdi.h:455
char * command
Definition: cli.h:186
char context[AST_MAX_CONTEXT]
The configured context for incoming calls.
Definition: chan_dahdi.h:444
unsigned int remotelyblocked
Bitmask for the channel being remotely blocked. 1 maintenance, 2 blocked in hardware.
Definition: chan_dahdi.h:413
#define FORMAT2
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
char language[MAX_LANGUAGE]
Language configured for calls.
Definition: chan_dahdi.h:460
ast_group_t group
Bitmapped groups this belongs to.
Definition: chan_dahdi.h:505
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_show_status()

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

Definition at line 15890 of file chan_dahdi.c.

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

15891 {
15892  #define FORMAT "%-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n"
15893  #define FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n"
15894  int span;
15895  int res;
15896  char alarmstr[50];
15897 
15898  int ctl;
15899  struct dahdi_spaninfo s;
15900 
15901  switch (cmd) {
15902  case CLI_INIT:
15903  e->command = "dahdi show status";
15904  e->usage =
15905  "Usage: dahdi show status\n"
15906  " Shows a list of DAHDI cards with status\n";
15907  return NULL;
15908  case CLI_GENERATE:
15909  return NULL;
15910  }
15911  ctl = open("/dev/dahdi/ctl", O_RDWR);
15912  if (ctl < 0) {
15913  ast_cli(a->fd, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno));
15914  return CLI_FAILURE;
15915  }
15916  ast_cli(a->fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC", "Framing", "Coding", "Options", "LBO");
15917 
15918  for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
15919  s.spanno = span;
15920  res = ioctl(ctl, DAHDI_SPANSTAT, &s);
15921  if (res) {
15922  continue;
15923  }
15924  alarmstr[0] = '\0';
15925  if (s.alarms > 0) {
15926  if (s.alarms & DAHDI_ALARM_BLUE)
15927  strcat(alarmstr, "BLU/");
15928  if (s.alarms & DAHDI_ALARM_YELLOW)
15929  strcat(alarmstr, "YEL/");
15930  if (s.alarms & DAHDI_ALARM_RED)
15931  strcat(alarmstr, "RED/");
15932  if (s.alarms & DAHDI_ALARM_LOOPBACK)
15933  strcat(alarmstr, "LB/");
15934  if (s.alarms & DAHDI_ALARM_RECOVER)
15935  strcat(alarmstr, "REC/");
15936  if (s.alarms & DAHDI_ALARM_NOTOPEN)
15937  strcat(alarmstr, "NOP/");
15938  if (!strlen(alarmstr))
15939  strcat(alarmstr, "UUU/");
15940  if (strlen(alarmstr)) {
15941  /* Strip trailing / */
15942  alarmstr[strlen(alarmstr) - 1] = '\0';
15943  }
15944  } else {
15945  if (s.numchans)
15946  strcpy(alarmstr, "OK");
15947  else
15948  strcpy(alarmstr, "UNCONFIGURED");
15949  }
15950 
15951  ast_cli(a->fd, FORMAT, s.desc, alarmstr, s.irqmisses, s.bpvcount, s.crc4count,
15952  s.lineconfig & DAHDI_CONFIG_D4 ? "D4" :
15953  s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" :
15954  s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" :
15955  "CAS",
15956  s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" :
15957  s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" :
15958  s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" :
15959  "Unk",
15960  s.lineconfig & DAHDI_CONFIG_CRC4 ?
15961  s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" :
15962  s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "YEL" : "",
15963  lbostr[s.lbo]
15964  );
15965  }
15966  close(ctl);
15967 
15968  return CLI_SUCCESS;
15969 #undef FORMAT
15970 #undef FORMAT2
15971 }
#define FORMAT
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static const char *const lbostr[]
Definition: chan_dahdi.c:484
const int fd
Definition: cli.h:159
int errno
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
#define FORMAT2
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ dahdi_show_version()

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

Definition at line 15973 of file chan_dahdi.c.

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

15974 {
15975  int pseudo_fd = -1;
15976  struct dahdi_versioninfo vi;
15977 
15978  switch (cmd) {
15979  case CLI_INIT:
15980  e->command = "dahdi show version";
15981  e->usage =
15982  "Usage: dahdi show version\n"
15983  " Shows the DAHDI version in use\n";
15984  return NULL;
15985  case CLI_GENERATE:
15986  return NULL;
15987  }
15988  if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) {
15989  ast_cli(a->fd, "Failed to open control file to get version.\n");
15990  return CLI_SUCCESS;
15991  }
15992 
15993  strcpy(vi.version, "Unknown");
15994  strcpy(vi.echo_canceller, "Unknown");
15995 
15996  if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi))
15997  ast_cli(a->fd, "Failed to get DAHDI version: %s\n", strerror(errno));
15998  else
15999  ast_cli(a->fd, "DAHDI Version: %s Echo Canceller: %s\n", vi.version, vi.echo_canceller);
16000 
16001  close(pseudo_fd);
16002 
16003  return CLI_SUCCESS;
16004 }
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
int errno
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ dahdi_sig2str()

static char* dahdi_sig2str ( int  sig)
static

Definition at line 4391 of file chan_dahdi.c.

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

4392 {
4393  static char buf[256];
4394  switch (sig) {
4395  case SIG_EM:
4396  return "E & M Immediate";
4397  case SIG_EMWINK:
4398  return "E & M Wink";
4399  case SIG_EM_E1:
4400  return "E & M E1";
4401  case SIG_FEATD:
4402  return "Feature Group D (DTMF)";
4403  case SIG_FEATDMF:
4404  return "Feature Group D (MF)";
4405  case SIG_FEATDMF_TA:
4406  return "Feature Groud D (MF) Tandem Access";
4407  case SIG_FEATB:
4408  return "Feature Group B (MF)";
4409  case SIG_E911:
4410  return "E911 (MF)";
4411  case SIG_FGC_CAMA:
4412  return "FGC/CAMA (Dialpulse)";
4413  case SIG_FGC_CAMAMF:
4414  return "FGC/CAMA (MF)";
4415  case SIG_FXSLS:
4416  return "FXS Loopstart";
4417  case SIG_FXSGS:
4418  return "FXS Groundstart";
4419  case SIG_FXSKS:
4420  return "FXS Kewlstart";
4421  case SIG_FXOLS:
4422  return "FXO Loopstart";
4423  case SIG_FXOGS:
4424  return "FXO Groundstart";
4425  case SIG_FXOKS:
4426  return "FXO Kewlstart";
4427  case SIG_PRI:
4428  return "ISDN PRI";
4429  case SIG_BRI:
4430  return "ISDN BRI Point to Point";
4431  case SIG_BRI_PTMP:
4432  return "ISDN BRI Point to MultiPoint";
4433  case SIG_SS7:
4434  return "SS7";
4435  case SIG_MFCR2:
4436  return "MFC/R2";
4437  case SIG_SF:
4438  return "SF (Tone) Immediate";
4439  case SIG_SFWINK:
4440  return "SF (Tone) Wink";
4441  case SIG_SF_FEATD:
4442  return "SF (Tone) with Feature Group D (DTMF)";
4443  case SIG_SF_FEATDMF:
4444  return "SF (Tone) with Feature Group D (MF)";
4445  case SIG_SF_FEATB:
4446  return "SF (Tone) with Feature Group B (MF)";
4447  case 0:
4448  return "Pseudo";
4449  default:
4450  snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
4451  return buf;
4452  }
4453 }
#define SIG_FXOGS
Definition: chan_dahdi.h:735
#define SIG_SF_FEATDMF
Definition: chan_dahdi.h:740
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define SIG_EM
Definition: chan_dahdi.h:722
#define SIG_FXOKS
Definition: chan_dahdi.h:736
#define SIG_FEATB
Definition: chan_dahdi.h:726
#define SIG_BRI_PTMP
Definition: chan_dahdi.h:747
#define SIG_FEATDMF_TA
Definition: chan_dahdi.h:728
#define SIG_SF
Definition: chan_dahdi.h:737
#define SIG_EMWINK
Definition: chan_dahdi.h:723
#define SIG_FGC_CAMAMF
Definition: chan_dahdi.h:730
#define SIG_BRI
Definition: chan_dahdi.h:746
#define SIG_FEATD
Definition: chan_dahdi.h:724
#define SIG_PRI
Definition: chan_dahdi.h:745
#define SIG_SS7
Definition: chan_dahdi.h:750
#define SIG_E911
Definition: chan_dahdi.h:727
#define SIG_FXSGS
Definition: chan_dahdi.h:732
#define SIG_SF_FEATD
Definition: chan_dahdi.h:739
#define SIG_SFWINK
Definition: chan_dahdi.h:738
#define SIG_FGC_CAMA
Definition: chan_dahdi.h:729
#define SIG_SF_FEATB
Definition: chan_dahdi.h:741
#define SIG_MFCR2
Definition: chan_dahdi.h:753
#define SIG_FXSKS
Definition: chan_dahdi.h:733
#define SIG_FXSLS
Definition: chan_dahdi.h:731
#define SIG_FXOLS
Definition: chan_dahdi.h:734
#define SIG_FEATDMF
Definition: chan_dahdi.h:725
#define SIG_EM_E1
Definition: chan_dahdi.h:742

◆ dahdi_softhangup_all()

static void dahdi_softhangup_all ( void  )
static

Definition at line 15396 of file chan_dahdi.c.

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

Referenced by dahdi_restart().

15397 {
15398  struct dahdi_pvt *p;
15399 retry:
15401  for (p = iflist; p; p = p->next) {
15402  ast_mutex_lock(&p->lock);
15403  if (p->owner && !p->restartpending) {
15404  if (ast_channel_trylock(p->owner)) {
15405  if (DEBUG_ATLEAST(3))
15406  ast_verbose("Avoiding deadlock\n");
15407  /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */
15408  ast_mutex_unlock(&p->lock);
15410  goto retry;
15411  }
15412  if (DEBUG_ATLEAST(3))
15413  ast_verbose("Softhanging up on %s\n", ast_channel_name(p->owner));
15415  p->restartpending = 1;
15418  }
15419  ast_mutex_unlock(&p->lock);
15420  }
15422 }
static int num_restart_pending
Definition: chan_dahdi.c:645
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
struct ast_channel * owner
Definition: chan_dahdi.h:127
#define ast_mutex_lock(a)
Definition: lock.h:187
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
unsigned int restartpending
Definition: chan_dahdi.h:319
ast_mutex_t lock
Definition: chan_dahdi.h:125
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2463
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_channel_trylock(chan)
Definition: channel.h:2947
#define DEBUG_ATLEAST(level)
Definition: logger.h:441
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdi_train_ec()

static void dahdi_train_ec ( struct dahdi_pvt p)
static

Definition at line 4693 of file chan_dahdi.c.

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

Referenced by dahdi_handle_event(), my_dial_digits(), and my_train_echocanceller().

4694 {
4695  int x;
4696  int res;
4697 
4698  if (p && p->echocanon && p->echotraining) {
4699  x = p->echotraining;
4700  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x);
4701  if (res)
4702  ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno));
4703  else
4704  ast_debug(1, "Engaged echo training on channel %d\n", p->channel);
4705  } else {
4706  ast_debug(1, "No echo training requested\n");
4707  }
4708 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int echotraining
Echo training time. 0 = disabled.
Definition: chan_dahdi.h:587
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
unsigned int echocanon
TRUE if echo cancellation is turned on.
Definition: chan_dahdi.h:248
int channel
Definition: chan_dahdi.h:538

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

Referenced by analog_ss_thread(), dahdievent_to_analogevent(), and my_wait_event().

662 {
663  int i, j = 0;
664  i = DAHDI_IOMUX_SIGEVENT;
665  if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
666  return -1;
667  if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
668  return -1;
669  return j;
670 }

◆ dahdi_wink()

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

Definition at line 9419 of file chan_dahdi.c.

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

Referenced by analog_ss_thread(), my_dsp_set_digitmode(), and my_wink().

9420 {
9421  int j;
9422  dahdi_set_hook(p->subs[idx].dfd, DAHDI_WINK);
9423  for (;;)
9424  {
9425  /* set bits of interest */
9426  j = DAHDI_IOMUX_SIGEVENT;
9427  /* wait for some happening */
9428  if (ioctl(p->subs[idx].dfd,DAHDI_IOMUX,&j) == -1) return(-1);
9429  /* exit loop if we have it */
9430  if (j & DAHDI_IOMUX_SIGEVENT) break;
9431  }
9432  /* get the event info */
9433  if (ioctl(p->subs[idx].dfd,DAHDI_GETEVENT,&j) == -1) return(-1);
9434  return 0;
9435 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922

◆ dahdi_write()

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

Definition at line 8894 of file chan_dahdi.c.

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.

Referenced by dahdi_chan_conf_default().

8895 {
8896  struct dahdi_pvt *p;
8897  int res;
8898  int idx;
8899 
8900  /* Write a frame of (presumably voice) data */
8901  if (frame->frametype != AST_FRAME_VOICE) {
8902  if (frame->frametype != AST_FRAME_IMAGE) {
8903  ast_log(LOG_WARNING, "Don't know what to do with frame type '%u'\n",
8904  frame->frametype);
8905  }
8906  return 0;
8907  }
8908 
8909  /* Return if it's not valid data */
8910  if (!frame->data.ptr || !frame->datalen) {
8911  return 0;
8912  }
8913 
8914  p = ast_channel_tech_pvt(ast);
8915  ast_mutex_lock(&p->lock);
8916 
8917  idx = dahdi_get_index(ast, p, 0);
8918  if (idx < 0) {
8919  ast_mutex_unlock(&p->lock);
8920  ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast_channel_name(ast));
8921  return -1;
8922  }
8923 
8924  if (p->dialing) {
8925  ast_mutex_unlock(&p->lock);
8926  ast_debug(5, "Dropping frame since I'm still dialing on %s...\n",
8927  ast_channel_name(ast));
8928  return 0;
8929  }
8930  if (!p->owner) {
8931  ast_mutex_unlock(&p->lock);
8932  ast_debug(5, "Dropping frame since there is no active owner on %s...\n",
8933  ast_channel_name(ast));
8934  return 0;
8935  }
8936  if (p->cidspill) {
8937  ast_mutex_unlock(&p->lock);
8938  ast_debug(5, "Dropping frame since I've still got a callerid spill on %s...\n",
8939  ast_channel_name(ast));
8940  return 0;
8941  }
8942 
8944  if (!p->subs[idx].linear) {
8945  p->subs[idx].linear = 1;
8946  res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8947  if (res)
8948  ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
8949  }
8950  res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 1);
8953  /* x-law already */
8954  if (p->subs[idx].linear) {
8955  p->subs[idx].linear = 0;
8956  res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8957  if (res)
8958  ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
8959  }
8960  res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 0);
8961  } else {
8962  ast_mutex_unlock(&p->lock);
8963  ast_log(LOG_WARNING, "Cannot handle frames in %s format\n",
8965  return -1;
8966  }
8967  ast_mutex_unlock(&p->lock);
8968  if (res < 0) {
8969  ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
8970  return -1;
8971  }
8972  return 0;
8973 }
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:827
unsigned int dialing
TRUE if in the process of dialing digits or sending something.
Definition: chan_dahdi.h:234
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
#define LOG_WARNING
Definition: logger.h:274
struct ast_channel * owner
Definition: chan_dahdi.h:127
static int my_dahdi_write(struct dahdi_pvt *p, unsigned char *buf, int len, int idx, int linear)
Definition: chan_dahdi.c:8872
#define ast_mutex_lock(a)
Definition: lock.h:187
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
struct ast_frame_subclass subclass
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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_mutex_t lock
Definition: chan_dahdi.h:125
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
unsigned int linear
Definition: chan_dahdi.h:90
int errno
static int dahdi_setlinear(int dfd, int linear)
Definition: chan_dahdi.c:4161
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
const char * ast_channel_name(const struct ast_channel *chan)
union ast_frame::@263 data
enum ast_frame_type frametype
struct ast_format * format
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dahdichannel_to_ami()

static struct ast_manager_event_blob* dahdichannel_to_ami ( struct stasis_message msg)
static

Definition at line 1741 of file chan_dahdi.c.

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, stasis_message_data(), STASIS_MESSAGE_TYPE_DEFN_LOCAL(), and to_ami().

1742 {
1743  RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
1744  struct ast_channel_blob *obj = stasis_message_data(msg);
1745  struct ast_json *group, *span, *channel;
1746 
1747  channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1748  if (!channel_string) {
1749  return NULL;
1750  }
1751 
1752  group = ast_json_object_get(obj->blob, "group");
1753  span = ast_json_object_get(obj->blob, "span");
1754  channel = ast_json_object_get(obj->blob, "channel");
1755 
1756  return ast_manager_event_blob_create(EVENT_FLAG_CALL, "DAHDIChannel",
1757  "%s"
1758  "DAHDIGroup: %llu\r\n"
1759  "DAHDISpan: %u\r\n"
1760  "DAHDIChannel: %s\r\n",
1761  ast_str_buffer(channel_string),
1763  (unsigned int)ast_json_integer_get(span),
1764  ast_json_string_get(channel));
1765 }
unsigned long long ast_group_t
Definition: channel.h:214
struct ast_json * blob
struct ast_channel_snapshot * snapshot
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define EVENT_FLAG_CALL
Definition: manager.h:72
Definition: muted.c:95
#define NULL
Definition: resample.c:96
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:9727
Blob of data associated with a channel.
#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:911
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
#define ast_free(a)
Definition: astmm.h:182
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
Abstract JSON element (object, array, string, int, ...).
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition: json.c:322

◆ dahdievent_to_analogevent()

static enum analog_event dahdievent_to_analogevent ( int  event)
static

Definition at line 2412 of file chan_dahdi.c.

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

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

2413 {
2414  enum analog_event res;
2415 
2416  switch (event) {
2417  case DAHDI_EVENT_ONHOOK:
2418  res = ANALOG_EVENT_ONHOOK;
2419  break;
2420  case DAHDI_EVENT_RINGOFFHOOK:
2422  break;
2423  case DAHDI_EVENT_WINKFLASH:
2424  res = ANALOG_EVENT_WINKFLASH;
2425  break;
2426  case DAHDI_EVENT_ALARM:
2427  res = ANALOG_EVENT_ALARM;
2428  break;
2429  case DAHDI_EVENT_NOALARM:
2430  res = ANALOG_EVENT_NOALARM;
2431  break;
2432  case DAHDI_EVENT_DIALCOMPLETE:
2434  break;
2435  case DAHDI_EVENT_RINGERON:
2436  res = ANALOG_EVENT_RINGERON;
2437  break;
2438  case DAHDI_EVENT_RINGEROFF:
2439  res = ANALOG_EVENT_RINGEROFF;
2440  break;
2441  case DAHDI_EVENT_HOOKCOMPLETE:
2443  break;
2444  case DAHDI_EVENT_PULSE_START:
2446  break;
2447  case DAHDI_EVENT_POLARITY:
2448  res = ANALOG_EVENT_POLARITY;
2449  break;
2450  case DAHDI_EVENT_RINGBEGIN:
2451  res = ANALOG_EVENT_RINGBEGIN;
2452  break;
2453  case DAHDI_EVENT_EC_DISABLED:
2455  break;
2456  case DAHDI_EVENT_REMOVED:
2457  res = ANALOG_EVENT_REMOVED;
2458  break;
2459  case DAHDI_EVENT_NEONMWI_ACTIVE:
2461  break;
2462  case DAHDI_EVENT_NEONMWI_INACTIVE:
2464  break;
2465 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2466  case DAHDI_EVENT_TX_CED_DETECTED:
2468  break;
2469  case DAHDI_EVENT_RX_CED_DETECTED:
2471  break;
2472  case DAHDI_EVENT_EC_NLP_DISABLED:
2474  break;
2475  case DAHDI_EVENT_EC_NLP_ENABLED:
2477  break;
2478 #endif
2479  case DAHDI_EVENT_PULSEDIGIT:
2481  break;
2482  case DAHDI_EVENT_DTMFDOWN:
2483  res = ANALOG_EVENT_DTMFDOWN;
2484  break;
2485  case DAHDI_EVENT_DTMFUP:
2486  res = ANALOG_EVENT_DTMFUP;
2487  break;
2488  default:
2489  switch(event & 0xFFFF0000) {
2490  case DAHDI_EVENT_PULSEDIGIT:
2491  case DAHDI_EVENT_DTMFDOWN:
2492  case DAHDI_EVENT_DTMFUP:
2493  /* The event includes a digit number in the low word.
2494  * Converting it to a 'enum analog_event' would remove
2495  * that information. Thus it is returned as-is.
2496  */
2497  return event;
2498  }
2499 
2500  res = ANALOG_EVENT_ERROR;
2501  break;
2502  }
2503 
2504  return res;
2505 }
analog_event
Definition: sig_analog.h:79
Definition: astman.c:222

◆ dahdisig_to_analogsig()

static enum analog_sigtype dahdisig_to_analogsig ( int  sig)
static

Definition at line 1055 of file chan_dahdi.c.

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

Referenced by mkintf().

1056 {
1057  switch (sig) {
1058  case SIG_FXOLS:
1059  return ANALOG_SIG_FXOLS;
1060  case SIG_FXOGS:
1061  return ANALOG_SIG_FXOGS;
1062  case SIG_FXOKS:
1063  return ANALOG_SIG_FXOKS;
1064  case SIG_FXSLS:
1065  return ANALOG_SIG_FXSLS;
1066  case SIG_FXSGS:
1067  return ANALOG_SIG_FXSGS;
1068  case SIG_FXSKS:
1069  return ANALOG_SIG_FXSKS;
1070  case SIG_EMWINK:
1071  return ANALOG_SIG_EMWINK;
1072  case SIG_EM:
1073  return ANALOG_SIG_EM;
1074  case SIG_EM_E1:
1075  return ANALOG_SIG_EM_E1;
1076  case SIG_FEATD:
1077  return ANALOG_SIG_FEATD;
1078  case SIG_FEATDMF:
1079  return ANALOG_SIG_FEATDMF;
1080  case SIG_E911:
1081  return SIG_E911;
1082  case SIG_FGC_CAMA:
1083  return ANALOG_SIG_FGC_CAMA;
1084  case SIG_FGC_CAMAMF:
1085  return ANALOG_SIG_FGC_CAMAMF;
1086  case SIG_FEATB:
1087  return ANALOG_SIG_FEATB;
1088  case SIG_SFWINK:
1089  return ANALOG_SIG_SFWINK;
1090  case SIG_SF:
1091  return ANALOG_SIG_SF;
1092  case SIG_SF_FEATD:
1093  return ANALOG_SIG_SF_FEATD;
1094  case SIG_SF_FEATDMF:
1095  return ANALOG_SIG_SF_FEATDMF;
1096  case SIG_FEATDMF_TA:
1097  return ANALOG_SIG_FEATDMF_TA;
1098  case SIG_SF_FEATB:
1099  return ANALOG_SIG_FEATB;
1100  default:
1101  return -1;
1102  }
1103 }
#define SIG_FXOGS
Definition: chan_dahdi.h:735
#define SIG_SF_FEATDMF
Definition: chan_dahdi.h:740
#define SIG_EM
Definition: chan_dahdi.h:722
#define SIG_FXOKS
Definition: chan_dahdi.h:736
#define SIG_FEATB
Definition: chan_dahdi.h:726
#define SIG_FEATDMF_TA
Definition: chan_dahdi.h:728
#define SIG_SF
Definition: chan_dahdi.h:737
#define SIG_EMWINK
Definition: chan_dahdi.h:723
#define SIG_FGC_CAMAMF
Definition: chan_dahdi.h:730
#define SIG_FEATD
Definition: chan_dahdi.h:724
#define SIG_E911
Definition: chan_dahdi.h:727
#define SIG_FXSGS
Definition: chan_dahdi.h:732
#define SIG_SF_FEATD
Definition: chan_dahdi.h:739
#define SIG_SFWINK
Definition: chan_dahdi.h:738
#define SIG_FGC_CAMA
Definition: chan_dahdi.h:729
#define SIG_SF_FEATB
Definition: chan_dahdi.h:741
#define SIG_FXSKS
Definition: chan_dahdi.h:733
#define SIG_FXSLS
Definition: chan_dahdi.h:731
#define SIG_FXOLS
Definition: chan_dahdi.h:734
#define SIG_FEATDMF
Definition: chan_dahdi.h:725
#define SIG_EM_E1
Definition: chan_dahdi.h:742

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

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

Referenced by setup_dahdi_int().

19327 {
19328  struct ast_cc_config_params *cc_params;
19329 
19330  cc_params = dest->chan.cc_params;
19331  *dest = *src;
19332  dest->chan.cc_params = cc_params;
19334 }
struct ast_cc_config_params * cc_params
Definition: chan_dahdi.h:710
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:861
struct dahdi_pvt chan
Definition: chan_dahdi.c:832

◆ destroy_all_channels()

static void destroy_all_channels ( void  )
static

Definition at line 5667 of file chan_dahdi.c.

References args, AST_APP_ARG, AST_CAUSE_CALL_REJECTED, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_INTERWORKING, AST_CAUSE_NETWORK_OUT_OF_ORDER, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, ast_channel_name(), ast_channel_tech(), ast_channel_tech_pvt(), ast_check_hangup(), AST_CONTROL_HANGUP, ast_db_del(), ast_db_get(), ast_debug, AST_DECLARE_APP_ARGS, AST_FRAME_CONTROL, ast_frfree, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_read(), ast_safe_sleep(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_true(), ast_verb, ast_waitfor(), dahdi_pvt::channel, destroy_dahdi_pvt(), ast_frame::frametype, ifcount, iflist, iflock, ast_frame_subclass::integer, dahdi_pvt::lock, sig_pri_span::lock, LOG_NOTICE, LOG_WARNING, sig_pri_span::no_b_chan_iflist, NULL, num_restart_pending, NUM_SPANS, parse(), sig_pri_span::pri, pri_send_callrerouting_facility_exec(), pri_send_keypad_facility_exec(), dahdi_pvt::sig, SIG_PRI_LIB_HANDLE_CASES, dahdi_pvt::sig_pvt, dahdi_pvt::span, state, ast_frame::subclass, and timeout.

Referenced by __unload_module(), and dahdi_restart().

5668 {
5669  int chan;
5670 #if defined(HAVE_PRI)
5671  unsigned span;
5672  struct sig_pri_span *pri;
5673 #endif /* defined(HAVE_PRI) */
5674  struct dahdi_pvt *p;
5675 
5676  while (num_restart_pending) {
5677  usleep(1);
5678  }
5679 
5681  /* Destroy all the interfaces and free their memory */
5682  while (iflist) {
5683  p = iflist;
5684 
5685  chan = p->channel;
5686 #if defined(HAVE_PRI_SERVICE_MESSAGES)
5687  {
5688  char db_chan_name[20];
5689  char db_answer[5];
5690  char state;
5691  int why = -1;
5692 
5693  snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, p->span, chan);
5694  if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) {
5695  sscanf(db_answer, "%1c:%30d", &state, &why);
5696  }
5697  if (!why) {
5698  /* SRVST persistence is not required */
5699  ast_db_del(db_chan_name, SRVST_DBKEY);
5700  }
5701  }
5702 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
5703  /* Free associated memory */
5704  destroy_dahdi_pvt(p);
5705  ast_verb(3, "Unregistered channel %d\n", chan);
5706  }
5707  ifcount = 0;
5709 
5710 #if defined(HAVE_PRI)
5711  /* Destroy all of the no B channel interface lists */
5712  for (span = 0; span < NUM_SPANS; ++span) {
5713  if (!pris[span].dchannels[0]) {
5714  break;
5715  }
5716  pri = &pris[span].pri;
5717  ast_mutex_lock(&pri->lock);
5718  while (pri->no_b_chan_iflist) {
5719  p = pri->no_b_chan_iflist;
5720 
5721  /* Free associated memory */
5722  destroy_dahdi_pvt(p);
5723  }
5724  ast_mutex_unlock(&pri->lock);
5725  }
5726 #endif /* defined(HAVE_PRI) */
5727 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
static int num_restart_pending
Definition: chan_dahdi.c:645
#define ast_mutex_lock(a)
Definition: lock.h:187
static int ifcount
Definition: chan_dahdi.c:628
#define ast_verb(level,...)
Definition: logger.h:463
ast_mutex_t lock
Definition: sig_pri.h:618
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
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:412
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: main/db.c:429
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
void * no_b_chan_iflist
Definition: sig_pri.h:609
static void destroy_dahdi_pvt(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:5569
#define NUM_SPANS
Definition: chan_dahdi.c:553
int channel
Definition: chan_dahdi.h:538
struct pri * pri
Definition: sig_pri.h:604
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ destroy_channel()

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

Definition at line 5649 of file chan_dahdi.c.

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

Referenced by dahdi_destroy_channel_range(), and dahdi_hangup().

5650 {
5651  int i;
5652 
5653  if (!now) {
5654  /* Do not destroy the channel now if it is owned by someone. */
5655  if (cur->owner) {
5656  return;
5657  }
5658  for (i = 0; i < 3; i++) {
5659  if (cur->subs[i].owner) {
5660  return;
5661  }
5662  }
5663  }
5664  destroy_dahdi_pvt(cur);
5665 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct ast_channel * owner
Definition: chan_dahdi.h:127
struct ast_channel * owner
Definition: chan_dahdi.h:79
static void destroy_dahdi_pvt(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:5569

◆ destroy_dahdi_pvt()

static void destroy_dahdi_pvt ( struct dahdi_pvt pvt)
static

Definition at line 5569 of file chan_dahdi.c.

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 available(), destroy_all_channels(), destroy_channel(), duplicate_pseudo(), and mkintf().

5570 {
5571  struct dahdi_pvt *p = pvt;
5572 
5573  if (p->manages_span_alarms) {
5574  struct dahdi_pvt *next = find_next_iface_in_span(p);
5575  if (next) {
5576  next->manages_span_alarms = 1;
5577  }
5578  }
5579 
5580  /* Remove channel from the list */
5581 #if defined(HAVE_PRI)
5582  dahdi_unlink_pri_pvt(p);
5583 #endif /* defined(HAVE_PRI) */
5584 #if defined(HAVE_SS7)
5585  dahdi_unlink_ss7_pvt(p);
5586 #endif /* defined(HAVE_SS7) */
5587 #if defined(HAVE_OPENR2)
5588  dahdi_unlink_mfcr2_pvt(p);
5589 #endif /* defined(HAVE_SS7) */
5590  switch (pvt->which_iflist) {
5591  case DAHDI_IFLIST_NONE:
5592  break;
5593  case DAHDI_IFLIST_MAIN:
5595  break;
5596 #if defined(HAVE_PRI)
5597  case DAHDI_IFLIST_NO_B_CHAN:
5598  if (p->pri) {
5599  dahdi_nobch_extract(p->pri, p);
5600  }
5601  break;
5602 #endif /* defined(HAVE_PRI) */
5603  }
5604 
5605  if (p->sig_pvt) {
5606  if (dahdi_analog_lib_handles(p->sig, 0, 0)) {
5607  analog_delete(p->sig_pvt);
5608  }
5609  switch (p->sig) {
5610 #if defined(HAVE_PRI)
5613  break;
5614 #endif /* defined(HAVE_PRI) */
5615 #if defined(HAVE_SS7)
5616  case SIG_SS7:
5618  break;
5619 #endif /* defined(HAVE_SS7) */
5620  default:
5621  break;
5622  }
5623  }
5624  ast_free(p->cidspill);
5625  if (p->use_smdi) {
5626  ao2_cleanup(p->smdi_iface);
5627  }
5628  if (p->mwi_event_sub) {
5630  }
5631  if (p->vars) {
5633  }
5634  if (p->cc_params) {
5636  }
5637 
5640 
5641  ast_mutex_destroy(&p->lock);
5643  if (p->owner) {
5645  }
5646  ast_free(p);
5647 }
struct ast_namedgroups * named_pickupgroups
Named pickup groups this belongs to.
Definition: chan_dahdi.h:532
void * ast_mwi_unsubscribe(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic and MWI.
Definition: mwi.c:249
static void dahdi_iflist_extract(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:5332
void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
Free memory from CCSS configuration params.
Definition: ccss.c:693
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
struct ast_mwi_subscriber * mwi_event_sub
Opaque event subscription parameters for message waiting indication support.
Definition: chan_dahdi.h:656
struct ast_channel * owner
Definition: chan_dahdi.h:127
void * sig_pvt
Definition: chan_dahdi.h:709
#define NULL
Definition: resample.c:96
static void dahdi_close_sub(struct dahdi_pvt *chan_pvt, int sub_num)
Definition: chan_dahdi.c:4139
struct ast_cc_config_params * cc_params
Definition: chan_dahdi.h:710
ast_mutex_t lock
Definition: chan_dahdi.h:125
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
void sig_pri_chan_delete(struct sig_pri_chan *doomed)
unsigned int use_smdi
TRUE if SMDI (Simplified Message Desk Interface) is enabled.
Definition: chan_dahdi.h:432
#define SIG_SS7
Definition: chan_dahdi.h:750
enum DAHDI_IFLIST which_iflist
Definition: chan_dahdi.h:167
#define SUB_REAL
Definition: chan_dahdi.h:57
static struct dahdi_pvt * find_next_iface_in_span(struct dahdi_pvt *cur)
Definition: chan_dahdi.c:5558
void analog_delete(struct analog_pvt *doomed)
Delete the analog private structure.
Definition: sig_analog.c:3958
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
#define ast_free(a)
Definition: astmm.h:182
struct ast_namedgroups * named_callgroups
Named call groups this belongs to.
Definition: chan_dahdi.h:527
struct ast_smdi_interface * smdi_iface
The SMDI interface to get SMDI messages from.
Definition: chan_dahdi.h:435
void sig_ss7_chan_delete(struct sig_ss7_chan *doomed)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_variable * vars
Channel variable list with associated values to set when a channel is created.
Definition: chan_dahdi.h:537
unsigned int manages_span_alarms
TRUE if the channel alarms will be managed also as Span ones.
Definition: chan_dahdi.h:418
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7832
#define ast_mutex_destroy(a)
Definition: lock.h:186
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)

◆ determine_starting_point()

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

Definition at line 13330 of file chan_dahdi.c.

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

Referenced by dahdi_cc_callback(), and dahdi_request().

13331 {
13332  char *dest;
13333  char *s;
13334  int x;
13335  int res = 0;
13336  struct dahdi_pvt *p;
13337  char *subdir = NULL;
13339  AST_APP_ARG(group); /* channel/group token */
13340  //AST_APP_ARG(ext); /* extension token */
13341  //AST_APP_ARG(opts); /* options token */
13342  AST_APP_ARG(other); /* Any remining unused arguments */
13343  );
13344 
13345  /*
13346  * data is ---v
13347  * Dial(DAHDI/pseudo[/extension[/options]])
13348  * Dial(DAHDI/<channel#>[c|r<cadance#>|d][/extension[/options]])
13349  * Dial(DAHDI/<subdir>!<channel#>[c|r<cadance#>|d][/extension[/options]])
13350  * Dial(DAHDI/i<span>[/extension[/options]])
13351  * Dial(DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]])
13352  *
13353  * i - ISDN span channel restriction.
13354  * Used by CC to ensure that the CC recall goes out the same span.
13355  * Also to make ISDN channel names dialable when the sequence number
13356  * is stripped off. (Used by DTMF attended transfer feature.)
13357  *
13358  * g - channel group allocation search forward
13359  * G - channel group allocation search backward
13360  * r - channel group allocation round robin search forward
13361  * R - channel group allocation round robin search backward
13362  *
13363  * c - Wait for DTMF digit to confirm answer
13364  * r<cadance#> - Set distintive ring cadance number
13365  * d - Force bearer capability for ISDN/SS7 call to digital.
13366  */
13367 
13368  if (data) {
13369  dest = ast_strdupa(data);
13370  } else {
13371  ast_log(LOG_WARNING, "Channel requested with no data\n");
13372  return NULL;
13373  }
13374  AST_NONSTANDARD_APP_ARGS(args, dest, '/');
13375  if (!args.argc || ast_strlen_zero(args.group)) {
13376  ast_log(LOG_WARNING, "No channel/group specified\n");
13377  return NULL;
13378  }
13379 
13380  /* Initialize the output parameters */
13381  memset(param, 0, sizeof(*param));
13382  param->channelmatch = -1;
13383 
13384  if (strchr(args.group, '!') != NULL) {
13385  char *prev = args.group;
13386  while ((s = strchr(prev, '!')) != NULL) {
13387  *s++ = '/';
13388  prev = s;
13389  }
13390  *(prev - 1) = '\0';
13391  subdir = args.group;
13392  args.group = prev;
13393  } else if (args.group[0] == 'i') {
13394  /* Extract the ISDN span channel restriction specifier. */
13395  res = sscanf(args.group + 1, "%30d", &x);
13396  if (res < 1) {
13397  ast_log(LOG_WARNING, "Unable to determine ISDN span for data %s\n", data);
13398  return NULL;
13399  }
13400  param->span = x;
13401 
13402  /* Remove the ISDN span channel restriction specifier. */
13403  s = strchr(args.group, '-');
13404  if (!s) {
13405  /* Search all groups since we are ISDN span restricted. */
13406  return iflist;
13407  }
13408  args.group = s + 1;
13409  res = 0;
13410  }
13411  if (toupper(args.group[0]) == 'G' || toupper(args.group[0])=='R') {
13412  /* Retrieve the group number */
13413  s = args.group + 1;
13414  res = sscanf(s, "%30d%1c%30d", &x, &param->opt, &param->cadance);
13415  if (res < 1) {
13416  ast_log(LOG_WARNING, "Unable to determine group for data %s\n", data);
13417  return NULL;
13418  }
13419  param->groupmatch = ((ast_group_t) 1 << x);
13420 
13421  if (toupper(args.group[0]) == 'G') {
13422  if (args.group[0] == 'G') {
13423  param->backwards = 1;
13424  p = ifend;
13425  } else
13426  p = iflist;
13427  } else {
13428  if (ARRAY_LEN(round_robin) <= x) {
13429  ast_log(LOG_WARNING, "Round robin index %d out of range for data %s\n",
13430  x, data);
13431  return NULL;
13432  }
13433  if (args.group[0] == 'R') {
13434  param->backwards = 1;
13435  p = round_robin[x] ? round_robin[x]->prev : ifend;
13436  if (!p)
13437  p = ifend;
13438  } else {
13439  p = round_robin[x] ? round_robin[x]->next : iflist;
13440  if (!p)
13441  p = iflist;
13442  }
13443  param->roundrobin = 1;
13444  param->rr_starting_point = x;
13445  }
13446  } else {
13447  s = args.group;
13448  if (!strcasecmp(s, "pseudo")) {
13449  /* Special case for pseudo */
13450  x = CHAN_PSEUDO;
13451  param->channelmatch = x;
13452  } else {
13453  res = sscanf(s, "%30d%1c%30d", &x, &param->opt, &param->cadance);
13454  if (res < 1) {
13455  ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", data);
13456  return NULL;
13457  } else {
13458  param->channelmatch = x;
13459  }
13460  }
13461  if (subdir) {
13462  char path[PATH_MAX];
13463  struct stat stbuf;
13464 
13465  snprintf(path, sizeof(path), "/dev/dahdi/%s/%d",
13466  subdir, param->channelmatch);
13467  if (stat(path, &stbuf) < 0) {
13468  ast_log(LOG_WARNING, "stat(%s) failed: %s\n",
13469  path, strerror(errno));
13470  return NULL;
13471  }
13472  if (!S_ISCHR(stbuf.st_mode)) {
13473  ast_log(LOG_ERROR, "%s: Not a character device file\n",
13474  path);
13475  return NULL;
13476  }
13477  param->channelmatch = minor(stbuf.st_rdev);
13478  }
13479 
13480  p = iflist;
13481  }
13482 
13483  if (param->opt == 'r' && res < 3) {
13484  ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", data);
13485  param->opt = '\0';
13486  }
13487 
13488  return p;
13489 }
unsigned long long ast_group_t
Definition: channel.h:214
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
#define LOG_WARNING
Definition: logger.h:274
#define CHAN_PSEUDO
Definition: chan_dahdi.c:556
const char * args
#define NULL
Definition: resample.c:96
static struct dahdi_pvt * ifend
Definition: chan_dahdi.c:802
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct dahdi_pvt * prev
Definition: chan_dahdi.h:169
#define LOG_ERROR
Definition: logger.h:285
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
int errno
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
ast_group_t groupmatch
Definition: chan_dahdi.c:13314
static struct dahdi_pvt * round_robin[32]
Definition: chan_dahdi.c:3429
#define PATH_MAX
Definition: asterisk.h:40
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ digit_to_dtmfindex()

static int digit_to_dtmfindex ( char  digit)
static

Definition at line 4221 of file chan_dahdi.c.

Referenced by dahdi_digit_begin().

4222 {
4223  if (isdigit(digit))
4224  return DAHDI_TONE_DTMF_BASE + (digit - '0');
4225  else if (digit >= 'A' && digit <= 'D')
4226  return DAHDI_TONE_DTMF_A + (digit - 'A');
4227  else if (digit >= 'a' && digit <= 'd')
4228  return DAHDI_TONE_DTMF_A + (digit - 'a');
4229  else if (digit == '*')
4230  return DAHDI_TONE_DTMF_s;
4231  else if (digit == '#')
4232  return DAHDI_TONE_DTMF_p;
4233  else
4234  return -1;
4235 }
char digit

◆ do_monitor()

static void* do_monitor ( void *  data)
static

Definition at line 11482 of file chan_dahdi.c.

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, 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::dtmfcid_delay, dahdi_pvt::dtmfcid_holdoff_state, dtmfcid_level, errno, event2str(), analog_pvt::fxsoffhookstate, handle_init_event(), has_voicemail(), ifcount, iflock, last, mwi_thread_data::len, dahdi_pvt::lock, LOG_ERROR, LOG_WARNING, dahdi_pvt::mailbox, monitor_pfds_clean(), analog_pvt::msgstate, mwi_send_init(), mwi_send_process_buffer(), mwi_send_process_event(), mwi_thread(), mwilevel, dahdi_pvt::mwimonitor_fsk, dahdi_pvt::mwimonitoractive, dahdi_pvt::mwisendactive, 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().

11483 {
11484  int count, res, res2, spoint, pollres=0;
11485  struct dahdi_pvt *i;
11486  struct dahdi_pvt *last = NULL;
11487  struct dahdi_pvt *doomed;
11488  time_t thispass = 0, lastpass = 0;
11489  int found;
11490  char buf[1024];
11491  struct pollfd *pfds=NULL;
11492  int lastalloc = -1;
11493  /* This thread monitors all the frame relay interfaces which are not yet in use
11494  (and thus do not have a separate thread) indefinitely */
11495  /* From here on out, we die whenever asked */
11496 #if 0
11497  if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
11498  ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
11499  return NULL;
11500  }
11501  ast_debug(1, "Monitor starting...\n");
11502 #endif
11503  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
11504 
11505  pthread_cleanup_push(monitor_pfds_clean, &pfds);
11506  for (;;) {
11507  /* Lock the interface list */
11509  if (!pfds || (lastalloc != ifcount)) {
11510  if (pfds) {
11511  ast_free(pfds);
11512  pfds = NULL;
11513  }
11514  if (ifcount) {
11515  if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
11517  return NULL;
11518  }
11519  }
11520  lastalloc = ifcount;
11521  }
11522  /* Build the stuff we're going to poll on, that is the socket of every
11523  dahdi_pvt that does not have an associated owner channel */
11524  count = 0;
11525  for (i = iflist; i; i = i->next) {
11526  ast_mutex_lock(&i->lock);
11527  if (pfds && (i->subs[SUB_REAL].dfd > -1) && i->sig && (!i->radio) && !(i->sig & SIG_MFCR2)) {
11528  if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
11529  struct analog_pvt *p = i->sig_pvt;
11530 
11531  if (!p) {
11532  ast_log(LOG_ERROR, "No sig_pvt?\n");
11533  } else if (!p->owner && !p->subs[SUB_REAL].owner) {
11534  /* This needs to be watched, as it lacks an owner */
11535  pfds[count].fd = i->subs[SUB_REAL].dfd;
11536  pfds[count].events = POLLPRI;
11537  pfds[count].revents = 0;
11538  /* Message waiting or r2 channels also get watched for reading */
11539  if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk ||
11540  (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) {
11541  pfds[count].events |= POLLIN;
11542  }
11543  count++;
11544  }
11545  } else {
11546  if (!i->owner && !i->subs[SUB_REAL].owner && !i->mwimonitoractive ) {
11547  /* This needs to be watched, as it lacks an owner */
11548  pfds[count].fd = i->subs[SUB_REAL].dfd;
11549  pfds[count].events = POLLPRI;
11550  pfds[count].revents = 0;
11551  /* If we are monitoring for VMWI or sending CID, we need to
11552  read from the channel as well */
11553  if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk ||
11554  (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) {
11555  pfds[count].events |= POLLIN;
11556  }
11557  count++;
11558  }
11559  }
11560  }
11561  ast_mutex_unlock(&i->lock);
11562  }
11563  /* Okay, now that we know what to do, release the interface lock */
11565 
11566  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
11567  pthread_testcancel();
11568  /* Wait at least a second for something to happen */
11569  res = poll(pfds, count, 1000);
11570  pthread_testcancel();
11571  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
11572 
11573  /* Okay, poll has finished. Let's see what happened. */
11574  if (res < 0) {
11575  if ((errno != EAGAIN) && (errno != EINTR))
11576  ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
11577  continue;
11578  }
11579  /* Alright, lock the interface list again, and let's look and see what has
11580  happened */
11582  found = 0;
11583  spoint = 0;
11584  lastpass = thispass;
11585  thispass = time(NULL);
11586  doomed = NULL;
11587  for (i = iflist;; i = i->next) {
11588  if (doomed) {
11589  dahdi_destroy_channel_range(doomed->channel, doomed->channel);
11590  doomed = NULL;
11591  }
11592  if (!i) {
11593  break;
11594  }
11595 
11596  if (thispass != lastpass) {
11597  if (!found && ((i == last) || ((i == iflist) && !last))) {
11598  last = i;
11599  if (last) {
11600  struct analog_pvt *analog_p = last->sig_pvt;
11601  /* Only allow MWI to be initiated on a quiescent fxs port */
11602  if (analog_p
11603  && !last->mwisendactive
11604  && (last->sig & __DAHDI_SIG_FXO)
11605  && !analog_p->fxsoffhookstate
11606  && !last->owner
11607  && !ast_strlen_zero(last->mailbox)
11608  && (thispass - analog_p->onhooktime > 3)) {
11609  res = has_voicemail(last);
11610  if (analog_p->msgstate != res) {
11611  /* Set driver resources for signalling VMWI */
11612  res2 = ioctl(last->subs[SUB_REAL].dfd, DAHDI_VMWI, &res);
11613  if (res2) {
11614  /* TODO: This message will ALWAYS be generated on some cards; any way to restrict it to those cards where it is interesting? */
11615  ast_debug(3, "Unable to control message waiting led on channel %d: %s\n", last->channel, strerror(errno));
11616  }
11617  /* If enabled for FSK spill then initiate it */
11618  if (mwi_send_init(last)) {
11619  ast_log(LOG_WARNING, "Unable to initiate mwi send sequence on channel %d\n", last->channel);
11620  }
11621  analog_p->msgstate = res;
11622  found ++;
11623  }
11624  }
11625  last = last->next;
11626  }
11627  }
11628  }
11629  if ((i->subs[SUB_REAL].dfd > -1) && i->sig) {
11630  if (i->radio && !i->owner)
11631  {
11632  res = dahdi_get_event(i->subs[SUB_REAL].dfd);
11633  if (res)
11634  {
11635  ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
11636  /* Don't hold iflock while handling init events */
11638  if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode))
11640  else
11641  doomed = handle_init_event(i, res);
11643  }
11644  continue;
11645  }
11646  pollres = ast_fdisset(pfds, i->subs[SUB_REAL].dfd, count, &spoint);
11647  if (pollres & POLLIN) {
11648  if (i->owner || i->subs[SUB_REAL].owner) {
11649 #ifdef HAVE_PRI
11650  if (!i->pri)
11651 #endif
11652  ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd);
11653  continue;
11654  }
11656  ast_log(LOG_WARNING, "Whoa.... I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd);
11657  continue;
11658  }
11659  res = read(i->subs[SUB_REAL].dfd, buf, sizeof(buf));
11660  if (res > 0) {
11661  if (i->mwimonitor_fsk) {
11662  if (calc_energy((unsigned char *) buf, res, AST_LAW(i)) > mwilevel) {
11663  pthread_attr_t attr;
11664  pthread_t threadid;
11665  struct mwi_thread_data *mtd;
11666 
11667  pthread_attr_init(&attr);
11668  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
11669 
11670  ast_debug(1, "Maybe some MWI on port %d!\n", i->channel);
11671  if ((mtd = ast_calloc(1, sizeof(*mtd)))) {
11672  mtd->pvt = i;
11673  memcpy(mtd->buf, buf, res);
11674  mtd->len = res;
11675  i->mwimonitoractive = 1;
11676  if (ast_pthread_create_background(&threadid, &attr, mwi_thread, mtd)) {
11677  ast_log(LOG_WARNING, "Unable to start mwi thread on channel %d\n", i->channel);
11678  i->mwimonitoractive = 0;
11679  ast_free(mtd);
11680  }
11681  }
11682  }
11683  /* If configured to check for a DTMF CID spill that comes without alert (e.g no polarity reversal) */
11684  } else if (i->cid_start == CID_START_DTMF_NOALERT) {
11685  int energy;
11686  struct timeval now;
11687  /* State machine dtmfcid_holdoff_state allows for the line to settle
11688  * before checking agin for dtmf energy. Presently waits for 500 mS before checking again
11689  */
11690  if (1 == i->dtmfcid_holdoff_state) {
11691  gettimeofday(&i->dtmfcid_delay, NULL);
11692  i->dtmfcid_holdoff_state = 2;
11693  } else if (2 == i->dtmfcid_holdoff_state) {
11694  gettimeofday(&now, NULL);
11695  if ((int)(now.tv_sec - i->dtmfcid_delay.tv_sec) * 1000000 + (int)now.tv_usec - (int)i->dtmfcid_delay.tv_usec > 500000) {
11696  i->dtmfcid_holdoff_state = 0;
11697  }
11698  } else {
11699  energy = calc_energy((unsigned char *) buf, res, AST_LAW(i));
11700  if (!i->mwisendactive && energy > dtmfcid_level) {
11701  pthread_t threadid;
11702  struct ast_channel *chan;
11704  if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode)) {
11705  /* just in case this event changes or somehow destroys a channel, set doomed here too */
11707  i->dtmfcid_holdoff_state = 1;
11708  } else {
11709  ast_callid callid = 0;
11710  int callid_created = ast_callid_threadstorage_auto(&callid);
11711  chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
11712  if (!chan) {
11713  ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
11714  } else {
11715  res = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan);
11716  if (res) {
11717  ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
11718  ast_hangup(chan);
11719  } else {
11720  i->dtmfcid_holdoff_state = 1;
11721  }
11722  }
11723  ast_callid_threadstorage_auto_clean(callid, callid_created);
11724  }
11726  }
11727  }
11728  }
11729  if (i->mwisendactive) {
11730  mwi_send_process_buffer(i, res);
11731  }
11732  } else {
11733  ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
11734  }
11735  }
11736  if (pollres & POLLPRI) {
11737  if (i->owner || i->subs[SUB_REAL].owner) {
11738 #ifdef HAVE_PRI
11739  if (!i->pri)
11740 #endif
11741  ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].dfd);
11742  continue;
11743  }
11744  res = dahdi_get_event(i->subs[SUB_REAL].dfd);
11745  ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
11746  /* Don't hold iflock while handling init events */
11748  if (0 == i->mwisendactive || 0 == mwi_send_process_event(i, res)) {
11749  if (dahdi_analog_lib_handles(i->sig, i->radio, i->oprmode))
11751  else
11752  doomed = handle_init_event(i, res);
11753  }
11755  }
11756  }
11757  }
11760 #ifdef HAVE_OPENR2
11761  dahdi_r2_destroy_nodev();
11762 #endif
11763  }
11764  /* Never reached */
11765  pthread_cleanup_pop(1);
11766  return NULL;
11767 
11768 }
struct dahdi_pvt * pvt
Definition: chan_dahdi.c:10707
Main Channel structure associated with a channel.
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static void monitor_pfds_clean(void *arg)
Definition: chan_dahdi.c:11477
void * analog_handle_init_event(struct analog_pvt *i, int event)
Definition: sig_analog.c:3675
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:563
static enum analog_event dahdievent_to_analogevent(int event)
Definition: chan_dahdi.c:2412
static int dtmfcid_level
Definition: chan_dahdi.c:613
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
int cid_start
Definition: chan_dahdi.h:542
#define LOG_WARNING
Definition: logger.h:274
static int ast_fdisset(struct pollfd *pfds, int fd, int maximum, int *start)
Helper function for migrating select to poll.
Definition: channel.h:2850
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:2042
static void * analog_ss_thread(void *data)
Definition: chan_dahdi.c:9512
struct ast_channel * owner
Definition: chan_dahdi.h:127
static void release_doomed_pris(void)
Definition: chan_dahdi.c:1156
struct ast_channel * owner
Definition: sig_analog.h:257
void * sig_pvt
Definition: chan_dahdi.h:709
static void dahdi_destroy_channel_range(int start, int end)
Definition: chan_dahdi.c:11068
unsigned int ast_callid
Definition: logger.h:87
static int calc_energy(const unsigned char *buf, int len, struct ast_format *law)
Definition: chan_dahdi.c:10712
#define ast_mutex_lock(a)
Definition: lock.h:187
static void * mwi_thread(void *data)
Definition: chan_dahdi.c:10726
static int ifcount
Definition: chan_dahdi.c:628
#define NULL
Definition: resample.c:96
struct timeval dtmfcid_delay
Definition: chan_dahdi.h:544
static int mwilevel
Definition: chan_dahdi.c:612
int oprmode
Definition: chan_dahdi.h:150
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_channel * owner
Definition: sig_analog.h:270
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
static int has_voicemail(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5033
int dtmfcid_holdoff_state
Definition: chan_dahdi.h:543
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int onhooktime
Definition: sig_analog.h:274
char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Voice mailbox location.
Definition: chan_dahdi.h:654
struct sla_ringing_trunk * last
Definition: app_meetme.c:1092
unsigned int mwimonitoractive
TRUE if an MWI monitor thread is currently active.
Definition: chan_dahdi.h:388
ast_mutex_t lock
Definition: chan_dahdi.h:125
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
static int mwi_send_init(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:10883
struct ast_channel * owner
Definition: chan_dahdi.h:79
#define AST_LAW(p)
Definition: chan_dahdi.c:521
unsigned int mwimonitor_fsk
TRUE if the FXO port monitors for fsk type MWI indications from the other end.
Definition: chan_dahdi.h:380
#define LOG_ERROR
Definition: logger.h:285
static int mwi_send_process_event(struct dahdi_pvt *pvt, int event)
Definition: chan_dahdi.c:11024
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SIG_FXSGS
Definition: chan_dahdi.h:732
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int dahdi_get_event(int fd)
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition: chan_dahdi.c:652
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
int msgstate
-1 = unknown, 0 = no messages, 1 = new messages available
Definition: sig_analog.h:277
static const char * event2str(int event)
Definition: chan_dahdi.c:4382
static int mwi_send_process_buffer(struct dahdi_pvt *pvt, int num_read)
Definition: chan_dahdi.c:10936
#define SIG_MFCR2
Definition: chan_dahdi.h:753
#define SIG_FXSKS
Definition: chan_dahdi.h:733
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
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:2020
#define SIG_FXSLS
Definition: chan_dahdi.h:731
int fxsoffhookstate
Definition: sig_analog.h:275
struct analog_subchannel subs[3]
Definition: sig_analog.h:272
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
#define CID_START_DTMF_NOALERT
Definition: callerid.h:68
static struct dahdi_pvt * handle_init_event(struct dahdi_pvt *i, int event)
Definition: chan_dahdi.c:11218
int channel
Definition: chan_dahdi.h:538
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:9153
unsigned char buf[READ_SIZE]
Definition: chan_dahdi.c:10708
#define ast_mutex_unlock(a)
Definition: lock.h:188
unsigned int mwisendactive
TRUE if a MWI message sending thread is active.
Definition: chan_dahdi.h:390

◆ drc_sample()

static int drc_sample ( int  sample,
float  drc 
)
static

Definition at line 4738 of file chan_dahdi.c.

References max.

Referenced by fill_rxgain(), and fill_txgain().

4739 {
4740  float neg;
4741  float shallow, steep;
4742  float max = SHRT_MAX;
4743 
4744  neg = (sample < 0 ? -1 : 1);
4745  steep = drc*sample;
4746  shallow = neg*(max-max/drc)+(float)sample/drc;
4747  if (fabsf(steep) < fabsf(shallow)) {
4748  sample = steep;
4749  }
4750  else {
4751  sample = shallow;
4752  }
4753 
4754  return sample;
4755 }
#define max(a, b)
Definition: f2c.h:198

◆ duplicate_pseudo()

static struct dahdi_pvt* duplicate_pseudo ( struct dahdi_pvt src)
static

Definition at line 13266 of file chan_dahdi.c.

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

Referenced by dahdi_request().

13267 {
13268  struct dahdi_pvt *p;
13269  struct dahdi_bufferinfo bi;
13270  int res;
13271 
13272  p = ast_malloc(sizeof(*p));
13273  if (!p) {
13274  return NULL;
13275  }
13276  *p = *src;
13277 
13278  /* Must deep copy the cc_params. */
13280  if (!p->cc_params) {
13281  ast_free(p);
13282  return NULL;
13283  }
13285 
13287  p->next = NULL;
13288  p->prev = NULL;
13289  ast_mutex_init(&p->lock);
13290  p->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo");
13291  if (p->subs[SUB_REAL].dfd < 0) {
13292  ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno));
13293  destroy_dahdi_pvt(p);
13294  return NULL;
13295  }
13296  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
13297  if (!res) {
13298  bi.txbufpolicy = src->buf_policy;
13299  bi.rxbufpolicy = src->buf_policy;
13300  bi.numbufs = src->buf_no;
13301  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
13302  if (res < 0) {
13303  ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel: %s\n", strerror(errno));
13304  }
13305  } else
13306  ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel: %s\n", strerror(errno));
13307  p->destroy = 1;
13309  return p;
13310 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
#define LOG_WARNING
Definition: logger.h:274
int buf_no
Definition: chan_dahdi.h:139
static void dahdi_iflist_insert(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:5282
#define NULL
Definition: resample.c:96
#define ast_cc_config_params_init()
Allocate and initialize an ast_cc_config_params structure.
Definition: ccss.h:135
#define ast_log
Definition: astobj2.c:42
struct ast_cc_config_params * cc_params
Definition: chan_dahdi.h:710
ast_mutex_t lock
Definition: chan_dahdi.h:125
static int dahdi_open(char *fn)
Definition: chan_dahdi.c:4086
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
struct dahdi_pvt * prev
Definition: chan_dahdi.h:169
unsigned int destroy
TRUE if the channel is to be destroyed on hangup. (Used by pseudo channels.)
Definition: chan_dahdi.h:226
#define LOG_ERROR
Definition: logger.h:285
enum DAHDI_IFLIST which_iflist
Definition: chan_dahdi.h:167
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define ast_free(a)
Definition: astmm.h:182
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:861
int buf_policy
Definition: chan_dahdi.h:140
static void destroy_dahdi_pvt(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:5569
#define ast_mutex_init(pmutex)
Definition: lock.h:184

◆ event2str()

static const char * event2str ( int  event)
static

Definition at line 4382 of file chan_dahdi.c.

References ARRAY_LEN, buf, and events.

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

4383 {
4384  static char buf[256];
4385  if ((event > -1) && (event < (ARRAY_LEN(events))) )
4386  return events[event];
4387  sprintf(buf, "Event %d", event); /* safe */
4388  return buf;
4389 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Definition: astman.c:222
static const char *const events[]
Definition: chan_dahdi.c:4337

◆ fill_rxgain()

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

Definition at line 4808 of file chan_dahdi.c.

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

Referenced by set_actual_rxgain().

4809 {
4810  int j;
4811  int k;
4812  float linear_gain = pow(10.0, gain / 20.0);
4813 
4814  switch (law) {
4815  case DAHDI_LAW_ALAW:
4816  for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
4817  if (gain || drc) {
4818  k = AST_ALAW(j);
4819  if (drc) {
4820  k = drc_sample(k, drc);
4821  }
4822  k = (float)k * linear_gain;
4823  if (k > 32767) {
4824  k = 32767;
4825  } else if (k < -32768) {
4826  k = -32768;
4827  }
4828  g->rxgain[j] = AST_LIN2A(k);
4829  } else {
4830  g->rxgain[j] = j;
4831  }
4832  }
4833  break;
4834  case DAHDI_LAW_MULAW:
4835  for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
4836  if (gain || drc) {
4837  k = AST_MULAW(j);
4838  if (drc) {
4839  k = drc_sample(k, drc);
4840  }
4841  k = (float)k * linear_gain;
4842  if (k > 32767) {
4843  k = 32767;
4844  } else if (k < -32768) {
4845  k = -32768;
4846  }
4847  g->rxgain[j] = AST_LIN2MU(k);
4848  } else {
4849  g->rxgain[j] = j;
4850  }
4851  }
4852  break;
4853  }
4854 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int drc_sample(int sample, float drc)
Definition: chan_dahdi.c:4738
#define AST_ALAW(a)
Definition: alaw.h:84
#define AST_MULAW(a)
Definition: ulaw.h:85
#define AST_LIN2MU(a)
Definition: ulaw.h:49
#define AST_LIN2A(a)
Definition: alaw.h:50

◆ fill_txgain()

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

Definition at line 4758 of file chan_dahdi.c.

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

Referenced by set_actual_txgain().

4759 {
4760  int j;
4761  int k;
4762 
4763  float linear_gain = pow(10.0, gain / 20.0);
4764 
4765  switch (law) {
4766  case DAHDI_LAW_ALAW:
4767  for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
4768  if (gain || drc) {
4769  k = AST_ALAW(j);
4770  if (drc) {
4771  k = drc_sample(k, drc);
4772  }
4773  k = (float)k * linear_gain;
4774  if (k > 32767) {
4775  k = 32767;
4776  } else if (k < -32768) {
4777  k = -32768;
4778  }
4779  g->txgain[j] = AST_LIN2A(k);
4780  } else {
4781  g->txgain[j] = j;
4782  }
4783  }
4784  break;
4785  case DAHDI_LAW_MULAW:
4786  for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
4787  if (gain || drc) {
4788  k = AST_MULAW(j);
4789  if (drc) {
4790  k = drc_sample(k, drc);
4791  }
4792  k = (float)k * linear_gain;
4793  if (k > 32767) {
4794  k = 32767;
4795  } else if (k < -32768) {
4796  k = -32768;
4797  }
4798  g->txgain[j] = AST_LIN2MU(k);
4799 
4800  } else {
4801  g->txgain[j] = j;
4802  }
4803  }
4804  break;
4805  }
4806 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int drc_sample(int sample, float drc)
Definition: chan_dahdi.c:4738
#define AST_ALAW(a)
Definition: alaw.h:84
#define AST_MULAW(a)
Definition: ulaw.h:85
#define AST_LIN2MU(a)
Definition: ulaw.h:49
#define AST_LIN2A(a)
Definition: alaw.h:50

◆ find_channel()

static struct dahdi_pvt* find_channel ( int  channel)
static

Definition at line 16253 of file chan_dahdi.c.

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

Referenced by find_channel_from_str().

16254 {
16255  struct dahdi_pvt *p;
16256 
16258  for (p = iflist; p; p = p->next) {
16259  if (p->channel == channel) {
16260  break;
16261  }
16262  }
16264  return p;
16265 }
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
#define ast_mutex_lock(a)
Definition: lock.h:187
Definition: muted.c:95
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
int channel
Definition: chan_dahdi.h:538
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ find_channel_from_str()

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

Definition at line 16276 of file chan_dahdi.c.

References find_channel(), and NULL.

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

16277 {
16278  int chan_num;
16279 
16280  if (sscanf(channel, "%30d", &chan_num) != 1) {
16281  /* Not numeric string. */
16282  return NULL;
16283  }
16284 
16285  return find_channel(chan_num);
16286 }
Definition: muted.c:95
#define NULL
Definition: resample.c:96
static struct dahdi_pvt * find_channel(int channel)
Definition: chan_dahdi.c:16253

◆ find_next_iface_in_span()

static struct dahdi_pvt* find_next_iface_in_span ( struct dahdi_pvt cur)
static

Definition at line 5558 of file chan_dahdi.c.

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

Referenced by destroy_dahdi_pvt().

5559 {
5560  if (cur->next && cur->next->span == cur->span) {
5561  return cur->next;
5562  } else if (cur->prev && cur->prev->span == cur->span) {
5563  return cur->prev;
5564  }
5565 
5566  return NULL;
5567 }
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
#define NULL
Definition: resample.c:96
struct dahdi_pvt * prev
Definition: chan_dahdi.h:169

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

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

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

7205 {
7206  int res;
7207  struct dahdi_spaninfo zi;
7208  struct dahdi_params params;
7209 
7210  memset(&zi, 0, sizeof(zi));
7211  zi.spanno = p->span;
7212 
7213  if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SPANSTAT, &zi)) >= 0) {
7214  if (zi.alarms != DAHDI_ALARM_NONE)
7215  return zi.alarms;
7216  } else {
7217  ast_log(LOG_WARNING, "Unable to determine alarm on channel %d: %s\n", p->channel, strerror(errno));
7218  return 0;
7219  }
7220 
7221  /* No alarms on the span. Check for channel alarms. */
7222  memset(&params, 0, sizeof(params));
7223  if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &params)) >= 0)
7224  return params.chan_alarms;
7225 
7226  ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
7227 
7228  return DAHDI_ALARM_NONE;
7229 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
int channel
Definition: chan_dahdi.h:538

◆ handle_alarms()

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

Definition at line 7364 of file chan_dahdi.c.

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_clear_alarms(), handle_init_event(), mkintf(), mwi_thread(), my_get_and_handle_alarms(), and my_set_inthreeway().

7365 {
7366  const char *alarm_str;
7367 
7368 #if defined(HAVE_PRI)
7370  return;
7371  }
7372 #endif /* defined(HAVE_PRI) */
7373 
7374  alarm_str = alarm2str(alms);
7376  ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
7377  publish_channel_alarm(p->channel, alarm_str);
7378  }
7379 
7381  ast_log(LOG_WARNING, "Detected alarm on span %d: %s\n", p->span, alarm_str);
7382  publish_span_alarm(p->span, alarm_str);
7383  }
7384 }
static void publish_span_alarm(int span, const char *alarm_txt)
Definition: chan_dahdi.c:7331
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
#define REPORT_CHANNEL_ALARMS
Definition: chan_dahdi.c:615
static int report_alarms
Definition: chan_dahdi.c:617
#define LOG_WARNING
Definition: logger.h:274
static char * alarm2str(int alm)
Definition: chan_dahdi.c:4372
#define REPORT_SPAN_ALARMS
Definition: chan_dahdi.c:616
#define ast_log
Definition: astobj2.c:42
unsigned int manages_span_alarms
TRUE if the channel alarms will be managed also as Span ones.
Definition: chan_dahdi.h:418
int channel
Definition: chan_dahdi.h:538
int sig_pri_is_alarm_ignored(struct sig_pri_span *pri)
static void publish_channel_alarm(int channel, const char *alarm_txt)
Definition: chan_dahdi.c:7345

◆ handle_clear_alarms()

static void handle_clear_alarms ( struct dahdi_pvt p)
static

Definition at line 3537 of file chan_dahdi.c.

References alarm, AST_ALAW, ast_alloca, ast_callid_threadstorage_auto(), ast_callid_threadstorage_auto_clean(), ast_control_pvt_cause_code::ast_cause, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_NO_ANSWER, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_NOTDEFINED, AST_CAUSE_PROTOCOL_ERROR, AST_CAUSE_UNREGISTERED, ast_channel_hangupcause_hash_set(), ast_channel_hangupcause_set(), AST_CHANNEL_NAME, ast_channel_name(), ast_channel_softhangup_internal_flag_add(), ast_channel_tech_pvt(), AST_CONTROL_PVT_CAUSE_CODE, ast_copy_string(), ast_debug, ast_exists_extension(), AST_LIN2A, AST_LIST_LOCK, AST_LIST_MOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log, ast_matchmore_extension(), ast_mutex_lock, ast_mutex_unlock, ast_queue_control_data(), ast_queue_hangup_with_cause(), AST_SOFTHANGUP_DEV, AST_STATE_RING, AST_STATE_UP, ast_strlen_zero, ast_true(), ast_verbose(), buf, c, ast_channel::callid, ast_control_pvt_cause_code::chan_name, dahdi_pvt::channel, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_subaddr, ast_control_pvt_cause_code::code, dahdi_pvt::context, dahdi_ec_enable(), dahdi_new(), dahdi_sig_pri_lib_handles(), dahdi_pvt::dialing, digit, dahdi_pvt::exten, format, get_alarms(), handle_alarms(), dahdi_pvt::immediate, dahdi_pvt::inalarm, dahdi_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, dahdi_pvt::manages_span_alarms, dahdi_subchannel::needanswer, dahdi_subchannel::needbusy, dahdi_subchannel::needcongestion, dahdi_subchannel::needringing, NULL, dahdi_pvt::owner, pbx_builtin_getvar_helper(), publish_channel_alarm_clear(), publish_span_alarm_clear(), dahdi_pvt::rdnis, dahdi_pvt::remotelyblocked, report_alarms, REPORT_CHANNEL_ALARMS, REPORT_SPAN_ALARMS, dahdi_pvt::sig, sig_pri_is_alarm_ignored(), dahdi_pvt::span, SUB_REAL, dahdi_pvt::subs, and dahdi_pvt::use_callerid.

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

3538 {
3539 #if defined(HAVE_PRI)
3541  return;
3542  }
3543 #endif /* defined(HAVE_PRI) */
3544 
3547  }
3550  }
3551 }
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
#define REPORT_CHANNEL_ALARMS
Definition: chan_dahdi.c:615
static int report_alarms
Definition: chan_dahdi.c:617
#define REPORT_SPAN_ALARMS
Definition: chan_dahdi.c:616
static void publish_channel_alarm_clear(int channel)
Definition: chan_dahdi.c:3506
static void publish_span_alarm_clear(int span)
Definition: chan_dahdi.c:3524
unsigned int manages_span_alarms
TRUE if the channel alarms will be managed also as Span ones.
Definition: chan_dahdi.h:418
int channel
Definition: chan_dahdi.h:538
int sig_pri_is_alarm_ignored(struct sig_pri_span *pri)

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

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

15854 {
15855  int i, j;
15856  switch (cmd) {
15857  case CLI_INIT:
15858  e->command = "dahdi show cadences";
15859  e->usage =
15860  "Usage: dahdi show cadences\n"
15861  " Shows all cadences currently defined\n";
15862  return NULL;
15863  case CLI_GENERATE:
15864  return NULL;
15865  }
15866  for (i = 0; i < num_cadence; i++) {
15867  char output[1024];
15868  char tmp[16], tmp2[64];
15869  snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
15870  term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
15871 
15872  for (j = 0; j < 16; j++) {
15873  if (cadences[i].ringcadence[j] == 0)
15874  break;
15875  snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
15876  if (cidrings[i] * 2 - 1 == j)
15877  term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
15878  else
15879  term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
15880  if (j != 0)
15881  strncat(output, ",", sizeof(output) - strlen(output) - 1);
15882  strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
15883  }
15884  ast_cli(a->fd,"%s\n",output);
15885  }
15886  return CLI_SUCCESS;
15887 }
static int tmp()
Definition: bt_open.c:389
Definition: cli.h:152
#define COLOR_GREEN
Definition: term.h:51
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
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:580
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:184
#define COLOR_BLACK
Definition: term.h:47
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX]
Definition: chan_dahdi.c:569
static int num_cadence
Definition: chan_dahdi.c:564
#define COLOR_MAGENTA
Definition: term.h:57

◆ handle_init_event()

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

Definition at line 11218 of file chan_dahdi.c.

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

11219 {
11220  int res;
11221  pthread_t threadid;
11222  struct ast_channel *chan;
11223  ast_callid callid = 0;
11224  int callid_created;
11225 
11226  /* Handle an event on a given channel for the monitor thread. */
11227 
11228  switch (event) {
11229  case DAHDI_EVENT_NONE:
11230  case DAHDI_EVENT_BITSCHANGED:
11231  break;
11232  case DAHDI_EVENT_WINKFLASH:
11233  case DAHDI_EVENT_RINGOFFHOOK:
11234  if (i->inalarm) break;
11235  if (i->radio) break;
11236  /* Got a ring/answer. What kind of channel are we? */
11237  switch (i->sig) {
11238  case SIG_FXOLS:
11239  case SIG_FXOGS:
11240  case SIG_FXOKS:
11241  res = dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
11242  if (res && (errno == EBUSY)) {
11243  break;
11244  }
11245 
11246  callid_created = ast_callid_threadstorage_auto(&callid);
11247 
11248  /* Cancel VMWI spill */
11249  ast_free(i->cidspill);
11250  i->cidspill = NULL;
11251  restore_conference(i);
11252 
11253  if (i->immediate) {
11254  dahdi_ec_enable(i);
11255  /* The channel is immediately up. Start right away */
11256  res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
11257  chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, NULL, NULL, callid);
11258  if (!chan) {
11259  ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
11260  res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
11261  if (res < 0)
11262  ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
11263  }
11264  } else {
11265  /* Check for callerid, digits, etc */
11266  chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, NULL, NULL, callid);
11267  if (chan) {
11268  if (has_voicemail(i))
11269  res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
11270  else
11271  res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
11272  if (res < 0)
11273  ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
11274  if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
11275  ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
11276  res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
11277  if (res < 0)
11278  ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
11279  ast_hangup(chan);
11280  }
11281  } else
11282  ast_log(LOG_WARNING, "Unable to create channel\n");
11283  }
11284 
11285  ast_callid_threadstorage_auto_clean(callid, callid_created);
11286  break;
11287  case SIG_FXSLS:
11288  case SIG_FXSGS:
11289  case SIG_FXSKS:
11290  i->ringt = i->ringt_base;
11291  /* Fall through */
11292  case SIG_EMWINK:
11293  case SIG_FEATD:
11294  case SIG_FEATDMF:
11295  case SIG_FEATDMF_TA:
11296  case SIG_E911:
11297  case SIG_FGC_CAMA:
11298  case SIG_FGC_CAMAMF:
11299  case SIG_FEATB:
11300  case SIG_EM:
11301  case SIG_EM_E1:
11302  case SIG_SFWINK:
11303  case SIG_SF_FEATD:
11304  case SIG_SF_FEATDMF:
11305  case SIG_SF_FEATB:
11306  case SIG_SF:
11307  /* Check for callerid, digits, etc */
11308  callid_created = ast_callid_threadstorage_auto(&callid);
11309  if (i->cid_start == CID_START_POLARITY_IN) {
11310  chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
11311  } else {
11312  chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, NULL, NULL, callid);
11313  }
11314 
11315  if (!chan) {
11316  ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
11317  } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
11318  ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
11319  res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
11320  if (res < 0) {
11321  ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
11322  }
11323  ast_hangup(chan);
11324  }
11325 
11326  ast_callid_threadstorage_auto_clean(callid, callid_created);
11327  break;
11328  default:
11329  ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
11330  res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
11331  if (res < 0)
11332  ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
11333  return NULL;
11334  }
11335  break;
11336  case DAHDI_EVENT_NOALARM:
11337  switch (i->sig) {
11338 #if defined(HAVE_PRI)
11340  ast_mutex_lock(&i->lock);
11342  ast_mutex_unlock(&i->lock);
11343  break;
11344 #endif /* defined(HAVE_PRI) */
11345 #if defined(HAVE_SS7)
11346  case SIG_SS7:
11347  sig_ss7_set_alarm(i->sig_pvt, 0);
11348  break;
11349 #endif /* defined(HAVE_SS7) */
11350  default:
11351  i->inalarm = 0;
11352  break;
11353  }
11355  break;
11356  case DAHDI_EVENT_ALARM:
11357  switch (i->sig) {
11358 #if defined(HAVE_PRI)
11360  ast_mutex_lock(&i->lock);
11362  ast_mutex_unlock(&i->lock);
11363  break;
11364 #endif /* defined(HAVE_PRI) */
11365 #if defined(HAVE_SS7)
11366  case SIG_SS7:
11367  sig_ss7_set_alarm(i->sig_pvt, 1);
11368  break;
11369 #endif /* defined(HAVE_SS7) */
11370  default:
11371  i->inalarm = 1;
11372  break;
11373  }
11374  res = get_alarms(i);
11375  handle_alarms(i, res);
11376  /* fall thru intentionally */
11377  case DAHDI_EVENT_ONHOOK:
11378  if (i->radio)
11379  break;
11380  /* Back on hook. Hang up. */
11381  switch (i->sig) {
11382  case SIG_FXOLS:
11383  case SIG_FXOGS:
11384  case SIG_FEATD:
11385  case SIG_FEATDMF:
11386  case SIG_FEATDMF_TA:
11387  case SIG_E911:
11388  case SIG_FGC_CAMA:
11389  case SIG_FGC_CAMAMF:
11390  case SIG_FEATB:
11391  case SIG_EM:
11392  case SIG_EM_E1:
11393  case SIG_EMWINK:
11394  case SIG_SF_FEATD:
11395  case SIG_SF_FEATDMF:
11396  case SIG_SF_FEATB:
11397  case SIG_SF:
11398  case SIG_SFWINK:
11399  case SIG_FXSLS:
11400  case SIG_FXSGS:
11401  case SIG_FXSKS:
11402  case SIG_FXOKS:
11403  dahdi_ec_disable(i);
11404  /* Diddle the battery for the zhone */
11405 #ifdef ZHONE_HACK
11406  dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
11407  usleep(1);
11408 #endif
11409  res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
11410  dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
11411  break;
11412  case SIG_SS7:
11414  dahdi_ec_disable(i);
11415  res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
11416  break;
11417  default:
11418  ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
11419  res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
11420  return NULL;
11421  }
11422  break;
11423  case DAHDI_EVENT_POLARITY:
11424  switch (i->sig) {
11425  case SIG_FXSLS:
11426  case SIG_FXSKS:
11427  case SIG_FXSGS:
11428  /* We have already got a PR before the channel was
11429  created, but it wasn't handled. We need polarity
11430  to be REV for remote hangup detection to work.
11431  At least in Spain */
11432  callid_created = ast_callid_threadstorage_auto(&callid);
11433  if (i->hanguponpolarityswitch)
11434  i->polarity = POLARITY_REV;
11436  i->polarity = POLARITY_REV;
11437  ast_verb(2, "Starting post polarity "
11438  "CID detection on channel %d\n",
11439  i->channel);
11440  chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
11441  if (!chan) {
11442  ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
11443  } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
11444  ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
11445  ast_hangup(chan);
11446  }
11447  }
11448  ast_callid_threadstorage_auto_clean(callid, callid_created);
11449  break;
11450  default:
11451  ast_log(LOG_WARNING, "handle_init_event detected "
11452  "polarity reversal on non-FXO (SIG_FXS) "
11453  "interface %d\n", i->channel);
11454  }
11455  break;
11456  case DAHDI_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */
11458  "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n",
11459  i->channel);
11460  return i;
11461  case DAHDI_EVENT_NEONMWI_ACTIVE:
11462  if (i->mwimonitor_neon) {
11463  notify_message(i->mailbox, 1);
11464  ast_log(LOG_NOTICE, "NEON MWI set for channel %d, mailbox %s \n", i->channel, i->mailbox);
11465  }
11466  break;
11467  case DAHDI_EVENT_NEONMWI_INACTIVE:
11468  if (i->mwimonitor_neon) {
11469  notify_message(i->mailbox, 0);
11470  ast_log(LOG_NOTICE, "NEON MWI cleared for channel %d, mailbox %s\n", i->channel, i->mailbox);
11471  }
11472  break;
11473  }
11474  return NULL;
11475 }
void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm)
Main Channel structure associated with a channel.
static void handle_clear_alarms(struct dahdi_pvt *p)
Definition: chan_dahdi.c:3537
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define SIG_FXOGS
Definition: chan_dahdi.h:735
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:563
#define SIG_SF_FEATDMF
Definition: chan_dahdi.h:740
void dahdi_ec_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4638
int cid_start
Definition: chan_dahdi.h:542
int ringt
Ring timeout timer??
Definition: chan_dahdi.h:556
#define LOG_WARNING
Definition: logger.h:274
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:2042
static void * analog_ss_thread(void *data)
Definition: chan_dahdi.c:9512
#define SIG_EM
Definition: chan_dahdi.h:722
#define CID_START_POLARITY
Definition: callerid.h:66
unsigned int immediate
TRUE if the channel should be answered immediately without attempting to gather any digits...
Definition: chan_dahdi.h:284
#define SIG_FXOKS
Definition: chan_dahdi.h:736
#define SIG_FEATB
Definition: chan_dahdi.h:726
void * sig_pvt
Definition: chan_dahdi.h:709
Definition: astman.c:222
unsigned int ast_callid
Definition: logger.h:87
#define SIG_FEATDMF_TA
Definition: chan_dahdi.h:728
void dahdi_ec_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4710
#define ast_mutex_lock(a)
Definition: lock.h:187
#define CID_START_POLARITY_IN
Definition: callerid.h:67
#define NULL
Definition: resample.c:96
int ringt_base
Ring timeout base.
Definition: chan_dahdi.h:561
#define ast_verb(level,...)
Definition: logger.h:463
#define SIG_SF
Definition: chan_dahdi.h:737
#define SIG_EMWINK
Definition: chan_dahdi.h:723
static void handle_alarms(struct dahdi_pvt *p, int alms)
Definition: chan_dahdi.c:7364
static int has_voicemail(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5033
#define SIG_FGC_CAMAMF
Definition: chan_dahdi.h:730
#define ast_log
Definition: astobj2.c:42
int polarity
Current line interface polarity. POLARITY_IDLE, POLARITY_REV.
Definition: chan_dahdi.h:681
unsigned int hanguponpolarityswitch
TRUE if the call will be considered "hung up" on a polarity reversal.
Definition: chan_dahdi.h:261
char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Voice mailbox location.
Definition: chan_dahdi.h:654
#define SIG_FEATD
Definition: chan_dahdi.h:724
ast_mutex_t lock
Definition: chan_dahdi.h:125
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
void sig_ss7_set_alarm(struct sig_ss7_chan *p, int in_alarm)
#define SIG_SS7
Definition: chan_dahdi.h:750
#define SIG_E911
Definition: chan_dahdi.h:727
static void notify_message(char *mailbox, int thereornot)
Send MWI state change.
Definition: chan_dahdi.c:3292
#define POLARITY_REV
Definition: chan_dahdi.c:793
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SIG_FXSGS
Definition: chan_dahdi.h:732
#define LOG_NOTICE
Definition: logger.h:263
static int restore_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5002
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
#define SIG_SF_FEATD
Definition: chan_dahdi.h:739
#define ast_free(a)
Definition: astmm.h:182
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922
static int get_alarms(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7204
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
#define SIG_SFWINK
Definition: chan_dahdi.h:738
#define SIG_FGC_CAMA
Definition: chan_dahdi.h:729
#define SIG_SF_FEATB
Definition: chan_dahdi.h:741
#define SIG_FXSKS
Definition: chan_dahdi.h:733
unsigned int mwimonitor_neon
TRUE if the FXO port monitors for neon type MWI indications from the other end.
Definition: chan_dahdi.h:375
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:2020
#define SIG_FXSLS
Definition: chan_dahdi.h:731
#define SIG_FXOLS
Definition: chan_dahdi.h:734
#define sig2str
Definition: chan_dahdi.c:4455
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
#define SIG_FEATDMF
Definition: chan_dahdi.h:725
unsigned int inalarm
TRUE if in an alarm condition.
Definition: chan_dahdi.h:286
int channel
Definition: chan_dahdi.h:538
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:9153
#define SIG_EM_E1
Definition: chan_dahdi.h:742
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ has_voicemail()

static int has_voicemail ( struct dahdi_pvt p)
static

Definition at line 5033 of file chan_dahdi.c.

References ao2_cleanup, ast_app_has_voicemail(), ast_mwi_state_cache(), ast_mwi_state_type(), dahdi_pvt::mailbox, 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(), my_allocate_sub(), and my_has_voicemail().

5034 {
5035  int new_msgs;
5036  RAII_VAR(struct stasis_message *, mwi_message, NULL, ao2_cleanup);
5037 
5039  if (mwi_message) {
5040  struct ast_mwi_state *mwi_state = stasis_message_data(mwi_message);
5041  new_msgs = mwi_state->new_msgs;
5042  } else {
5043  new_msgs = ast_app_has_voicemail(p->mailbox, NULL);
5044  }
5045 
5046  return new_msgs;
5047 }
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
Definition: mwi.c:90
#define NULL
Definition: resample.c:96
char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Voice mailbox location.
Definition: chan_dahdi.h:654
#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:911
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
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". If folder is "INBOX", includes the number of messages in the "Urgent" folder.
Definition: main/app.c:655
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int new_msgs
Definition: mwi.h:461
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:457

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

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

Referenced by dahdi_cc_callback(), and dahdi_request().

13026 {
13027 #if defined(HAVE_PRI)
13028  if (0 < span) {
13029  /* The channel must be on the specified PRI span. */
13030  if (!p->pri || p->pri->span != span) {
13031  return 0;
13032  }
13033  if (!groupmatch && channelmatch == -1) {
13034  /* Match any group since it only needs to be on the PRI span. */
13035  *groupmatched = 1;
13036  return 1;
13037  }
13038  }
13039 #endif /* defined(HAVE_PRI) */
13040  /* check group matching */
13041  if (groupmatch) {
13042  if ((p->group & groupmatch) != groupmatch)
13043  /* Doesn't match the specified group, try the next one */
13044  return 0;
13045  *groupmatched = 1;
13046  }
13047  /* Check to see if we have a channel match */
13048  if (channelmatch != -1) {
13049  if (p->channel != channelmatch)
13050  /* Doesn't match the specified channel, try the next one */
13051  return 0;
13052  *channelmatched = 1;
13053  }
13054 
13055  return 1;
13056 }
ast_group_t group
Bitmapped groups this belongs to.
Definition: chan_dahdi.h:505
int channel
Definition: chan_dahdi.h:538

◆ isourconf()

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

Definition at line 4495 of file chan_dahdi.c.

References dahdi_pvt::channel, dahdi_pvt::confno, and dahdi_subchannel::curconf.

Referenced by conf_del().

4496 {
4497  /* If they're listening to our channel, they're ours */
4498  if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON))
4499  return 1;
4500  /* If they're a talker on our (allocated) conference, they're ours */
4501  if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER))
4502  return 1;
4503  return 0;
4504 }
int confno
Definition: chan_dahdi.h:510
int channel
Definition: chan_dahdi.h:538
struct dahdi_confinfo curconf
Definition: chan_dahdi.h:92

◆ isslavenative()

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

Definition at line 4525 of file chan_dahdi.c.

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

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

4526 {
4527  int x;
4528  int useslavenative;
4529  struct dahdi_pvt *slave = NULL;
4530  /* Start out optimistic */
4531  useslavenative = 1;
4532  /* Update conference state in a stateless fashion */
4533  for (x = 0; x < 3; x++) {
4534  /* Any three-way calling makes slave native mode *definitely* out
4535  of the question */
4536  if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway)
4537  useslavenative = 0;
4538  }
4539  /* If we don't have any 3-way calls, check to see if we have
4540  precisely one slave */
4541  if (useslavenative) {
4542  for (x = 0; x < MAX_SLAVES; x++) {
4543  if (p->slaves[x]) {
4544  if (slave) {
4545  /* Whoops already have a slave! No
4546  slave native and stop right away */
4547  slave = NULL;
4548  useslavenative = 0;
4549  break;
4550  } else {
4551  /* We have one slave so far */
4552  slave = p->slaves[x];
4553  }
4554  }
4555  }
4556  }
4557  /* If no slave, slave native definitely out */
4558  if (!slave)
4559  useslavenative = 0;
4560  else if (slave->law != p->law) {
4561  useslavenative = 0;
4562  slave = NULL;
4563  }
4564  if (out)
4565  *out = slave;
4566  return useslavenative;
4567 }
#define MAX_SLAVES
Definition: chan_dahdi.h:95
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
int law
Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:509
#define NULL
Definition: resample.c:96
struct dahdi_pvt * slaves[MAX_SLAVES]
Definition: chan_dahdi.h:134
unsigned int inthreeway
Definition: chan_dahdi.h:91

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

References __unload_module(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_dahdishowchannels(), 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_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_native_load(), EVENT_FLAG_SYSTEM, LOG_ERROR, NULL, NUM_SPANS, 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.

Referenced by reload().

19672 {
19673  int res;
19674 #if defined(HAVE_PRI) || defined(HAVE_SS7)
19675  int y;
19676 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
19677 
19678  if (STASIS_MESSAGE_TYPE_INIT(dahdichannel_type)) {
19679  return AST_MODULE_LOAD_DECLINE;
19680  }
19681 
19683  return AST_MODULE_LOAD_DECLINE;
19684  }
19688 
19689  if (dahdi_native_load(&dahdi_tech)) {
19691  return AST_MODULE_LOAD_DECLINE;
19692  }
19693 
19694 #ifdef HAVE_PRI
19695  memset(pris, 0, sizeof(pris));
19696  for (y = 0; y < NUM_SPANS; y++) {
19697  sig_pri_init_pri(&pris[y].pri);
19698  }
19699  pri_set_error(dahdi_pri_error);
19700  pri_set_message(dahdi_pri_message);
19701  ast_register_application_xml(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec);
19702 #ifdef HAVE_PRI_PROG_W_CAUSE
19703  ast_register_application_xml(dahdi_send_callrerouting_facility_app, dahdi_send_callrerouting_facility_exec);
19704 #endif
19705 #if defined(HAVE_PRI_CCSS)
19706  if (ast_cc_agent_register(&dahdi_pri_cc_agent_callbacks)
19707  || ast_cc_monitor_register(&dahdi_pri_cc_monitor_callbacks)) {
19708  __unload_module();
19709  return AST_MODULE_LOAD_DECLINE;
19710  }
19711 #endif /* defined(HAVE_PRI_CCSS) */
19712  if (sig_pri_load(
19713 #if defined(HAVE_PRI_CCSS)
19714  dahdi_pri_cc_type
19715 #else
19716  NULL
19717 #endif /* defined(HAVE_PRI_CCSS) */
19718  )) {
19719  __unload_module();
19720  return AST_MODULE_LOAD_DECLINE;
19721  }
19722 #endif
19723 #if defined(HAVE_SS7)
19724  memset(linksets, 0, sizeof(linksets));
19725  for (y = 0; y < NUM_SPANS; y++) {
19726  sig_ss7_init_linkset(&linksets[y].ss7);
19727  }
19728  ss7_set_error(dahdi_ss7_error);
19729  ss7_set_message(dahdi_ss7_message);
19730  ss7_set_hangup(sig_ss7_cb_hangup);
19731  ss7_set_notinservice(sig_ss7_cb_notinservice);
19732  ss7_set_call_null(sig_ss7_cb_call_null);
19733 #endif /* defined(HAVE_SS7) */
19734  res = setup_dahdi(0);
19735  /* Make sure we can register our DAHDI channel type */
19736  if (res) {
19737  __unload_module();
19738  return AST_MODULE_LOAD_DECLINE;
19739  }
19741  ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n");
19742  __unload_module();
19743  return AST_MODULE_LOAD_DECLINE;
19744  }
19745 #ifdef HAVE_PRI
19746  ast_cli_register_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
19747 #endif
19748 #if defined(HAVE_SS7)
19749  ast_cli_register_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli));
19750 #endif /* defined(HAVE_SS7) */
19751 #ifdef HAVE_OPENR2
19752  ast_cli_register_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli));
19753  ast_register_application_xml(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec);
19754 #endif
19755 
19757  memset(round_robin, 0, sizeof(round_robin));
19758  ast_manager_register_xml("DAHDITransfer", 0, action_transfer);
19760  ast_manager_register_xml("DAHDIDialOffhook", 0, action_dahdidialoffhook);
19761  ast_manager_register_xml("DAHDIDNDon", 0, action_dahdidndon);
19762  ast_manager_register_xml("DAHDIDNDoff", 0, action_dahdidndoff);
19763  ast_manager_register_xml("DAHDIShowChannels", 0, action_dahdishowchannels);
19764  ast_manager_register_xml("DAHDIRestart", 0, action_dahdirestart);
19765 #if defined(HAVE_PRI)
19766  ast_manager_register_xml("PRIShowSpans", 0, action_prishowspans);
19767  ast_manager_register_xml("PRIDebugSet", 0, action_pri_debug_set);
19768  ast_manager_register_xml("PRIDebugFileSet", EVENT_FLAG_SYSTEM, action_pri_debug_file_set);
19769  ast_manager_register_xml("PRIDebugFileUnset", 0, action_pri_debug_file_unset);
19770 #endif /* defined(HAVE_PRI) */
19771 
19773 
19774  return res;
19775 }
int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks)
Register a set of agent callbacks with the core.
Definition: ccss.c:1239
static int __unload_module(void)
Definition: chan_dahdi.c:17540
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_cli_entry dahdi_cli[]
Definition: chan_dahdi.c:16220
static struct ast_channel_tech dahdi_tech
Definition: chan_dahdi.c:1030
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1501
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
static ast_cond_t ss_thread_complete
Definition: chan_dahdi.c:641
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
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
static int setup_dahdi(int reload)
Definition: chan_dahdi.c:19642
void sig_ss7_cb_notinservice(struct ss7 *ss7, int cic, unsigned int dpc)
#define NULL
Definition: resample.c:96
static int action_dahdidndon(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16288
void sig_pri_init_pri(struct sig_pri_span *pri)
int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks)
Register a set of monitor callbacks with the core.
Definition: ccss.c:1184
int dahdi_native_load(const struct ast_channel_tech *tech)
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int action_dahdidndoff(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16307
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
static int action_dahdirestart(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:15562
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
#define LOG_ERROR
Definition: logger.h:285
struct ast_format_cap * capabilities
Definition: channel.h:633
void sig_ss7_init_linkset(struct sig_ss7_linkset *ss7)
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int action_dahdishowchannels(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16404
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
static struct dahdi_pvt * round_robin[32]
Definition: chan_dahdi.c:3429
#define NUM_SPANS
Definition: chan_dahdi.c:553
int sig_pri_load(const char *cc_type_name)
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:186
int sig_ss7_cb_hangup(struct ss7 *ss7, int cic, unsigned int dpc, int cause, int do_hangup)
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
static int action_transfer(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16326
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626
static int action_dahdidialoffhook(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16372
static int action_transferhangup(struct mansession *s, const struct message *m)
Definition: chan_dahdi.c:16349
void sig_ss7_cb_call_null(struct ss7 *ss7, struct isup_call *c, int lock)

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

References dahdi_pvt::accountcode, dahdi_pvt::adsi, dahdi_pvt::amaflags, ANALOG_CID_START_DTMF_NOALERT, ANALOG_CID_START_POLARITY, ANALOG_CID_START_POLARITY_IN, ANALOG_CID_START_RING, analog_config_complete(), analog_new(), ANALOG_SIG_NONE, dahdi_pvt::answeronpolarityswitch, 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(), dahdi_pvt::buf_no, dahdi_pvt::buf_policy, dahdi_pvt::bufsize, dahdi_pvt::busy_cadence, dahdi_pvt::busycount, dahdi_pvt::busydetect, dahdi_pvt::callgroup, dahdi_pvt::callprogress, dahdi_pvt::callreturn, analog_pvt::callreturn, dahdi_pvt::callwaiting, dahdi_pvt::callwaitingcallerid, analog_pvt::callwaitingcallerid, dahdi_pvt::cancallforward, analog_pvt::cancallforward, dahdi_pvt::canpark, analog_pvt::canpark, dahdi_pvt::cc_params, dahdi_chan_conf::chan, CHAN_PSEUDO, sig_ss7_chan::channel, sig_pri_chan::channel, analog_pvt::channel, dahdi_pvt::channel, sig_ss7_chan::cic, analog_pvt::cid_name, dahdi_pvt::cid_name, analog_pvt::cid_num, dahdi_pvt::cid_num, dahdi_pvt::cid_rxgain, CID_SIG_SMDI, analog_pvt::cid_signalling, dahdi_pvt::cid_signalling, analog_pvt::cid_start, dahdi_pvt::cid_start, CID_START_DTMF_NOALERT, CID_START_POLARITY, CID_START_POLARITY_IN, dahdi_pvt::cid_subaddr, dahdi_pvt::cid_tag, dahdi_pvt::cid_ton, dahdi_pvt::confno, sig_ss7_chan::context, sig_pri_chan::context, dahdi_pvt::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, dahdi_pvt::dahditrcallerid, dahdi_pvt::defcontext, dahdi_pvt::description, dahdi_pvt::destroy, destroy_dahdi_pvt(), dahdi_subchannel::dfd, sig_pri_span::dialplan, dahdi_pvt::dialtone_detect, sig_ss7_chan::dpc, dahdi_pvt::drings, dahdi_pvt::dsp, DSP_DIGITMODE_DTMF, dahdi_pvt::dtmfrelax, dahdi_pvt::echocanbridged, dahdi_pvt::echocancel, analog_pvt::echotraining, dahdi_pvt::echotraining, errno, dahdi_pvt::faxbuf_no, dahdi_pvt::faxbuf_policy, dahdi_pvt::faxdetect_timeout, ast_variable::file, dahdi_pvt::firstdigit_timeout, dahdi_pvt::firstradio, analog_pvt::fxsoffhookstate, get_alarms(), dahdi_pvt::group, handle_alarms(), dahdi_pvt::hanguponpolarityswitch, analog_pvt::hanguponpolarityswitch, dahdi_pvt::head, sig_ss7_chan::hidecallerid, dahdi_pvt::hidecallerid, sig_pri_chan::hidecallerid, dahdi_pvt::hidecalleridname, sig_pri_chan::hidecalleridname, dahdi_pvt::hwrxgain, dahdi_pvt::hwrxgain_enabled, dahdi_pvt::hwtxgain, dahdi_pvt::hwtxgain_enabled, sig_pri_span::idledial, sig_pri_span::idleext, ifcount, sig_ss7_chan::immediate, dahdi_pvt::immediate, sig_pri_chan::immediate, analog_pvt::immediate, dahdi_pvt::inalarm, sig_ss7_chan::inalarm, analog_pvt::inalarm, sig_pri_chan::inalarm, sig_ss7_chan::inservice, dahdi_pvt::inservice, dahdi_pvt::interdigit_timeout, dahdi_chan_conf::is_sig_auto, dahdi_pvt::language, dahdi_pvt::law, dahdi_pvt::law_default, LINKSET_FLAG_INITIALHWBLO, sig_ss7_chan::locallyblocked, dahdi_pvt::locallyblocked, dahdi_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, dahdi_pvt::mailbox, dahdi_pvt::matchdigit_timeout, sig_pri_span::minidle, sig_pri_span::minunused, sig_ss7_chan::mohinterpret, sig_pri_chan::mohinterpret, dahdi_pvt::mohinterpret, analog_pvt::mohsuggest, dahdi_pvt::mohsuggest, analog_pvt::msgstate, dahdi_pvt::mwi_event_sub, dahdi_pvt::mwimonitor_fsk, dahdi_pvt::mwimonitor_neon, dahdi_pvt::mwimonitor_rpas, ast_variable::name, dahdi_pvt::named_callgroups, dahdi_pvt::named_pickupgroups, ast_variable::next, dahdi_pvt::next, sig_pri_span::nodetype, NULL, NUM_SPANS, sig_pri_span::numchans, analog_pvt::onhooktime, dahdi_pvt::oprmode, dahdi_pvt::outsigmod, analog_pvt::outsigmod, dahdi_pvt::parkinglot, analog_pvt::permcallwaiting, dahdi_pvt::permcallwaiting, analog_pvt::permhidecallerid, dahdi_pvt::permhidecallerid, dahdi_pvt::pickupgroup, analog_pvt::polarityonanswerdelay, dahdi_pvt::polarityonanswerdelay, sig_pri_chan::priexclusive, dahdi_pvt::priexclusive, sig_pri_chan::priindication_oob, dahdi_pvt::priindication_oob, dahdi_pvt::propconfno, analog_pvt::pulse, dahdi_pvt::pulse, sig_pri_span::pvts, dahdi_pvt::radio, distRingData::range, sig_ss7_chan::remotelyblocked, dahdi_pvt::remotelyblocked, dahdi_pvt::restrictcid, dahdi_distRings::ringnum, analog_pvt::ringt, dahdi_pvt::ringt, analog_pvt::ringt_base, dahdi_pvt::ringt_base, ringt_base, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, dahdi_pvt::sendcalleridafter, set_actual_gain(), set_hwgain(), dahdi_pvt::sig, sig2str, SIG_BRI_PTMP, SIG_E911, SIG_EM, SIG_EM_E1, SIG_EMWINK, SIG_FEATB, SIG_FEATD, SIG_FEATDMF, SIG_FEATDMF_TA, SIG_FGC_CAMA, SIG_FGC_CAMAMF, SIG_FXOGS, SIG_FXOKS, SIG_FXOLS, SIG_FXSKS, SIG_FXSLS, SIG_MFCR2, SIG_PRI, sig_pri_chan_new(), SIG_PRI_LIB_HANDLE_CASES, SIG_PRI_NUM_DCHANS, sig_pri_set_alarm(), dahdi_pvt::sig_pvt, SIG_SF, SIG_SF_FEATB, SIG_SF_FEATD, SIG_SF_FEATDMF, SIG_SFWINK, SIG_SS7, sig_ss7_chan_new(), sig_ss7_set_alarm(), sigtype_to_signalling(), analog_pvt::smdi_iface, dahdi_pvt::smdi_iface, dahdi_chan_conf::smdi_port, dahdi_pvt::span, SS7_BLOCKED_HARDWARE, stasis_subscription_cb_noop(), state, sig_ss7_chan::stripmsd, sig_pri_chan::stripmsd, analog_pvt::stripmsd, dahdi_pvt::stripmsd, SUB_REAL, dahdi_pvt::subs, sig_pri_span::switchtype, analog_pvt::threewaycalling, dahdi_pvt::threewaycalling, dahdi_chan_conf::timing, tmp(), dahdi_pvt::tonezone, analog_pvt::transfer, dahdi_pvt::transfer, analog_pvt::transfertobusy, dahdi_pvt::transfertobusy, sig_pri_span::trunkgroup, dahdi_pvt::txdrc, dahdi_pvt::txgain, sig_ss7_chan::use_callerid, sig_pri_chan::use_callerid, analog_pvt::use_callerid, dahdi_pvt::use_callerid, sig_ss7_chan::use_callingpres, sig_pri_chan::use_callingpres, dahdi_pvt::use_callingpres, analog_pvt::use_smdi, dahdi_pvt::use_smdi, analog_pvt::usedistinctiveringdetection, dahdi_pvt::usedistinctiveringdetection, usedistinctiveringdetection, dahdi_pvt::usefaxbuffers, ast_variable::value, dahdi_pvt::vars, and dahdi_pvt::waitfordialtone.

Referenced by build_channels(), and process_dahdi().

12096 {
12097  /* Make a dahdi_pvt structure for this interface */
12098  struct dahdi_pvt *tmp;/*!< Current channel structure initializing */
12099  char fn[80];
12100  struct dahdi_bufferinfo bi;
12101 
12102  int res;
12103 #if defined(HAVE_PRI)
12104  int span = 0;
12105 #endif /* defined(HAVE_PRI) */
12106  int here = 0;/*!< TRUE if the channel interface already exists. */
12107  int x;
12108  struct analog_pvt *analog_p = NULL;
12109  struct dahdi_params p;
12110 #if defined(HAVE_PRI)
12111  struct dahdi_spaninfo si;
12112  struct sig_pri_chan *pri_chan = NULL;
12113 #endif /* defined(HAVE_PRI) */
12114 #if defined(HAVE_SS7)
12115  struct sig_ss7_chan *ss7_chan = NULL;
12116 #endif /* defined(HAVE_SS7) */
12117 
12118  /* Search channel interface list to see if it already exists. */
12119  for (tmp = iflist; tmp; tmp = tmp->next) {
12120  if (!tmp->destroy) {
12121  if (tmp->channel == channel) {
12122  /* The channel interface already exists. */
12123  here = 1;
12124  break;
12125  }
12126  if (tmp->channel > channel) {
12127  /* No way it can be in the sorted list. */
12128  tmp = NULL;
12129  break;
12130  }
12131  }
12132  }
12133 
12134  if (!here && reloading != 1) {
12135  tmp = ast_calloc(1, sizeof(*tmp));
12136  if (!tmp) {
12137  return NULL;
12138  }
12140  if (!tmp->cc_params) {
12141  ast_free(tmp);
12142  return NULL;
12143  }
12144  ast_mutex_init(&tmp->lock);
12145  ifcount++;
12146  for (x = 0; x < 3; x++)
12147  tmp->subs[x].dfd = -1;
12148  tmp->channel = channel;
12150  }
12151 
12152  if (tmp) {
12153  int chan_sig = conf->chan.sig;
12154 
12155  /* If there are variables in tmp before it is updated to match the new config, clear them */
12156  if (reloading && tmp->vars) {
12158  tmp->vars = NULL;
12159  }
12160 
12161  if (!here) {
12162  /* Can only get here if this is a new channel interface being created. */
12163  if ((channel != CHAN_PSEUDO)) {
12164  int count = 0;
12165 
12166  snprintf(fn, sizeof(fn), "%d", channel);
12167  /* Open non-blocking */
12168  tmp->subs[SUB_REAL].dfd = dahdi_open(fn);
12169  while (tmp->subs[SUB_REAL].dfd < 0 && reloading == 2 && count < 1000) { /* the kernel may not call dahdi_release fast enough for the open flagbit to be cleared in time */
12170  usleep(1);
12171  tmp->subs[SUB_REAL].dfd = dahdi_open(fn);
12172  count++;
12173  }
12174  /* Allocate a DAHDI structure */
12175  if (tmp->subs[SUB_REAL].dfd < 0) {
12176  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);
12177  destroy_dahdi_pvt(tmp);
12178  return NULL;
12179  }
12180  memset(&p, 0, sizeof(p));
12181  res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
12182  if (res < 0) {
12183  ast_log(LOG_ERROR, "Unable to get parameters: %s\n", strerror(errno));
12184  destroy_dahdi_pvt(tmp);
12185  return NULL;
12186  }
12187  if (conf->is_sig_auto)
12188  chan_sig = sigtype_to_signalling(p.sigtype);
12189  if (p.sigtype != (chan_sig & 0x3ffff)) {
12190  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));
12191  destroy_dahdi_pvt(tmp);
12192  return NULL;
12193  }
12194  tmp->law_default = p.curlaw;
12195  tmp->law = p.curlaw;
12196  tmp->span = p.spanno;
12197 #if defined(HAVE_PRI)
12198  span = p.spanno - 1;
12199 #endif /* defined(HAVE_PRI) */
12200  } else {
12201  chan_sig = 0;
12202  }
12203  tmp->sig = chan_sig;
12204  tmp->outsigmod = conf->chan.outsigmod;
12205 
12206  if (dahdi_analog_lib_handles(chan_sig, tmp->radio, tmp->oprmode)) {
12207  analog_p = analog_new(dahdisig_to_analogsig(chan_sig), tmp);
12208  if (!analog_p) {
12209  destroy_dahdi_pvt(tmp);
12210  return NULL;
12211  }
12212  tmp->sig_pvt = analog_p;
12213  }
12214 #if defined(HAVE_SS7)
12215  if (chan_sig == SIG_SS7) {
12216  struct dahdi_ss7 *ss7;
12217  int clear = 0;
12218 
12219  if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &clear)) {
12220  ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
12221  destroy_dahdi_pvt(tmp);
12222  return NULL;
12223  }
12224 
12225  ss7 = ss7_resolve_linkset(cur_linkset);
12226  if (!ss7) {
12227  ast_log(LOG_ERROR, "Unable to find linkset %d\n", cur_linkset);
12228  destroy_dahdi_pvt(tmp);
12229  return NULL;
12230  }
12231  ss7->ss7.span = cur_linkset;
12232  if (cur_cicbeginswith < 0) {
12233  ast_log(LOG_ERROR, "Need to set cicbeginswith for the channels!\n");
12234  destroy_dahdi_pvt(tmp);
12235  return NULL;
12236  }
12237  ss7_chan = sig_ss7_chan_new(tmp, &ss7->ss7);
12238  if (!ss7_chan) {
12239  destroy_dahdi_pvt(tmp);
12240  return NULL;
12241  }
12242  tmp->sig_pvt = ss7_chan;
12243  tmp->ss7 = &ss7->ss7;
12244 
12245  ss7_chan->channel = tmp->channel;
12246  ss7_chan->cic = cur_cicbeginswith++;
12247 
12248  /* DB: Add CIC's DPC information */
12249  ss7_chan->dpc = cur_defaultdpc;
12250 
12251  ss7->ss7.pvts[ss7->ss7.numchans++] = ss7_chan;
12252 
12253  ast_copy_string(ss7->ss7.internationalprefix, conf->ss7.ss7.internationalprefix, sizeof(ss7->ss7.internationalprefix));
12254  ast_copy_string(ss7->ss7.nationalprefix, conf->ss7.ss7.nationalprefix, sizeof(ss7->ss7.nationalprefix));
12255  ast_copy_string(ss7->ss7.subscriberprefix, conf->ss7.ss7.subscriberprefix, sizeof(ss7->ss7.subscriberprefix));
12256  ast_copy_string(ss7->ss7.unknownprefix, conf->ss7.ss7.unknownprefix, sizeof(ss7->ss7.unknownprefix));
12257  ast_copy_string(ss7->ss7.networkroutedprefix, conf->ss7.ss7.networkroutedprefix, sizeof(ss7->ss7.networkroutedprefix));
12258 
12259  ss7->ss7.called_nai = conf->ss7.ss7.called_nai;
12260  ss7->ss7.calling_nai = conf->ss7.ss7.calling_nai;
12261  }
12262 #endif /* defined(HAVE_SS7) */
12263 #ifdef HAVE_OPENR2
12264  if (chan_sig == SIG_MFCR2) {
12265  struct dahdi_mfcr2 *r2_link;
12266  struct r2link_entry *r2_le = dahdi_r2_get_link(conf);
12267  r2_link = &r2_le->mfcr2;
12268  if (!r2_link) {
12269  ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n");
12270  destroy_dahdi_pvt(tmp);
12271  return NULL;
12272  }
12273  if (!r2_link->protocol_context && dahdi_r2_set_context(r2_link, conf)) {
12274  ast_log(LOG_ERROR, "Cannot create OpenR2 protocol context.\n");
12275  destroy_dahdi_pvt(tmp);
12276  return NULL;
12277  }
12278  if (r2_link->numchans == ARRAY_LEN(r2_link->pvts)) {
12279  ast_log(LOG_ERROR, "Cannot add more channels to this link!\n");
12280  destroy_dahdi_pvt(tmp);
12281  return NULL;
12282  }
12283  r2_link->pvts[r2_link->numchans++] = tmp;
12284  tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context,
12285  tmp->subs[SUB_REAL].dfd,
12286  NULL, NULL);
12287  if (!tmp->r2chan) {
12288  openr2_liberr_t err = openr2_context_get_last_error(r2_link->protocol_context);
12289  ast_log(LOG_ERROR, "Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err));
12290  destroy_dahdi_pvt(tmp);
12291  return NULL;
12292  }
12293  r2_link->live_chans++;
12294  tmp->mfcr2 = r2_link;
12295  if (conf->mfcr2.call_files) {
12296  openr2_chan_enable_call_files(tmp->r2chan);
12297  }
12298  openr2_chan_set_client_data(tmp->r2chan, tmp);
12299  /* cast seems to be needed to get rid of the annoying warning regarding format attribute */
12300  openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log);
12301  openr2_chan_set_log_level(tmp->r2chan, conf->mfcr2.loglevel);
12302  tmp->mfcr2_category = conf->mfcr2.category;
12303  tmp->mfcr2_charge_calls = conf->mfcr2.charge_calls;
12304  tmp->mfcr2_allow_collect_calls = conf->mfcr2.allow_collect_calls;
12305  tmp->mfcr2_forced_release = conf->mfcr2.forced_release;
12306  tmp->mfcr2_accept_on_offer = conf->mfcr2.accept_on_offer;
12307  tmp->mfcr2call = 0;
12308  tmp->mfcr2_dnis_index = 0;
12309  tmp->mfcr2_ani_index = 0;
12310  }
12311 #endif
12312 #ifdef HAVE_PRI
12313  if (dahdi_sig_pri_lib_handles(chan_sig)) {
12314  int offset;
12315  int matchesdchan;
12316  int x,y;
12317  int myswitchtype = 0;
12318 
12319  offset = 0;
12320  if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &offset)) {
12321  ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
12322  destroy_dahdi_pvt(tmp);
12323  return NULL;
12324  }
12325  if (span >= NUM_SPANS) {
12326  ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
12327  destroy_dahdi_pvt(tmp);
12328  return NULL;
12329  } else {
12330  si.spanno = 0;
12331  if (ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SPANSTAT,&si) == -1) {
12332  ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
12333  destroy_dahdi_pvt(tmp);
12334  return NULL;
12335  }
12336  /* Store the logical span first based upon the real span */
12337  tmp->logicalspan = pris[span].prilogicalspan;
12338  pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
12339  if (span < 0) {
12340  ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
12341  destroy_dahdi_pvt(tmp);
12342  return NULL;
12343  }
12344  myswitchtype = conf->pri.pri.switchtype;
12345  /* Make sure this isn't a d-channel */
12346  matchesdchan=0;
12347  for (x = 0; x < NUM_SPANS; x++) {
12348  for (y = 0; y < SIG_PRI_NUM_DCHANS; y++) {
12349  if (pris[x].dchannels[y] == tmp->channel) {
12350  matchesdchan = 1;
12351  break;
12352  }
12353  }
12354  }
12355  if (!matchesdchan) {
12356  if (pris[span].pri.nodetype && (pris[span].pri.nodetype != conf->pri.pri.nodetype)) {
12357  ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].pri.nodetype));
12358  destroy_dahdi_pvt(tmp);
12359  return NULL;
12360  }
12361  if (pris[span].pri.switchtype && (pris[span].pri.switchtype != myswitchtype)) {
12362  ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].pri.switchtype));
12363  destroy_dahdi_pvt(tmp);
12364  return NULL;
12365  }
12366  if ((pris[span].pri.dialplan) && (pris[span].pri.dialplan != conf->pri.pri.dialplan)) {
12367  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));
12368  destroy_dahdi_pvt(tmp);
12369  return NULL;
12370  }
12371  if (!ast_strlen_zero(pris[span].pri.idledial) && strcmp(pris[span].pri.idledial, conf->pri.pri.idledial)) {
12372  ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.pri.idledial);
12373  destroy_dahdi_pvt(tmp);
12374  return NULL;
12375  }
12376  if (!ast_strlen_zero(pris[span].pri.idleext) && strcmp(pris[span].pri.idleext, conf->pri.pri.idleext)) {
12377  ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.pri.idleext);
12378  destroy_dahdi_pvt(tmp);
12379  return NULL;
12380  }
12381  if (pris[span].pri.minunused && (pris[span].pri.minunused != conf->pri.pri.minunused)) {
12382  ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.pri.minunused);
12383  destroy_dahdi_pvt(tmp);
12384  return NULL;
12385  }
12386  if (pris[span].pri.minidle && (pris[span].pri.minidle != conf->pri.pri.minidle)) {
12387  ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.pri.minidle);
12388  destroy_dahdi_pvt(tmp);
12389  return NULL;
12390  }
12391  if (pris[span].pri.numchans >= ARRAY_LEN(pris[span].pri.pvts)) {
12392  ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
12393  pris[span].pri.trunkgroup);
12394  destroy_dahdi_pvt(tmp);
12395  return NULL;
12396  }
12397 
12398  pri_chan = sig_pri_chan_new(tmp, &pris[span].pri, tmp->logicalspan, p.chanpos, pris[span].mastertrunkgroup);
12399  if (!pri_chan) {
12400  destroy_dahdi_pvt(tmp);
12401  return NULL;
12402  }
12403  tmp->sig_pvt = pri_chan;
12404  tmp->pri = &pris[span].pri;
12405 
12406  tmp->priexclusive = conf->chan.priexclusive;
12407 
12408  if (!tmp->pri->cc_params) {
12409  tmp->pri->cc_params = ast_cc_config_params_init();
12410  if (!tmp->pri->cc_params) {
12411  destroy_dahdi_pvt(tmp);
12412  return NULL;
12413  }
12414  }
12416  conf->chan.cc_params);
12417 
12418  pris[span].pri.sig = chan_sig;
12419  pris[span].pri.nodetype = conf->pri.pri.nodetype;
12420  pris[span].pri.switchtype = myswitchtype;
12421  pris[span].pri.nsf = conf->pri.pri.nsf;
12422  pris[span].pri.dialplan = conf->pri.pri.dialplan;
12423  pris[span].pri.localdialplan = conf->pri.pri.localdialplan;
12424  pris[span].pri.cpndialplan = conf->pri.pri.cpndialplan;
12425  pris[span].pri.pvts[pris[span].pri.numchans++] = tmp->sig_pvt;
12426  pris[span].pri.minunused = conf->pri.pri.minunused;
12427  pris[span].pri.minidle = conf->pri.pri.minidle;
12428  pris[span].pri.overlapdial = conf->pri.pri.overlapdial;
12429  pris[span].pri.qsigchannelmapping = conf->pri.pri.qsigchannelmapping;
12430  pris[span].pri.discardremoteholdretrieval = conf->pri.pri.discardremoteholdretrieval;
12431 #if defined(HAVE_PRI_SERVICE_MESSAGES)
12432  pris[span].pri.enable_service_message_support = conf->pri.pri.enable_service_message_support;
12433 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
12434 #ifdef HAVE_PRI_INBANDDISCONNECT
12435  pris[span].pri.inbanddisconnect = conf->pri.pri.inbanddisconnect;
12436 #endif
12437 #if defined(HAVE_PRI_CALL_HOLD)
12438  pris[span].pri.hold_disconnect_transfer =
12439  conf->pri.pri.hold_disconnect_transfer;
12440 #endif /* defined(HAVE_PRI_CALL_HOLD) */
12441 #if defined(HAVE_PRI_CCSS)
12442  pris[span].pri.cc_ptmp_recall_mode =
12443  conf->pri.pri.cc_ptmp_recall_mode;
12444  pris[span].pri.cc_qsig_signaling_link_req =
12445  conf->pri.pri.cc_qsig_signaling_link_req;
12446  pris[span].pri.cc_qsig_signaling_link_rsp =
12447  conf->pri.pri.cc_qsig_signaling_link_rsp;
12448 #endif /* defined(HAVE_PRI_CCSS) */
12449 #if defined(HAVE_PRI_CALL_WAITING)
12450  pris[span].pri.max_call_waiting_calls =
12451  conf->pri.pri.max_call_waiting_calls;
12452  pris[span].pri.allow_call_waiting_calls =
12453  conf->pri.pri.allow_call_waiting_calls;
12454 #endif /* defined(HAVE_PRI_CALL_WAITING) */
12455  pris[span].pri.transfer = conf->chan.transfer;
12456  pris[span].pri.facilityenable = conf->pri.pri.facilityenable;
12457 #if defined(HAVE_PRI_L2_PERSISTENCE)
12458  pris[span].pri.l2_persistence = conf->pri.pri.l2_persistence;
12459 #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */
12460  pris[span].pri.colp_send = conf->pri.pri.colp_send;
12461 #if defined(HAVE_PRI_AOC_EVENTS)
12462  pris[span].pri.aoc_passthrough_flag = conf->pri.pri.aoc_passthrough_flag;
12463  pris[span].pri.aoce_delayhangup = conf->pri.pri.aoce_delayhangup;
12464 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
12465  if (chan_sig == SIG_BRI_PTMP) {
12466  pris[span].pri.layer1_ignored = conf->pri.pri.layer1_ignored;
12467  } else {
12468  /* Option does not apply to this line type. */
12469  pris[span].pri.layer1_ignored = 0;
12470  }
12471  pris[span].pri.append_msn_to_user_tag = conf->pri.pri.append_msn_to_user_tag;
12472  pris[span].pri.inband_on_setup_ack = conf->pri.pri.inband_on_setup_ack;
12473  pris[span].pri.inband_on_proceeding = conf->pri.pri.inband_on_proceeding;
12474  ast_copy_string(pris[span].pri.initial_user_tag, conf->chan.cid_tag, sizeof(pris[span].pri.initial_user_tag));
12475  ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list));
12476 #if defined(HAVE_PRI_MWI)
12477  ast_copy_string(pris[span].pri.mwi_mailboxes,
12478  conf->pri.pri.mwi_mailboxes,
12479  sizeof(pris[span].pri.mwi_mailboxes));
12480  ast_copy_string(pris[span].pri.mwi_vm_boxes,
12481  conf->pri.pri.mwi_vm_boxes,
12482  sizeof(pris[span].pri.mwi_vm_boxes));
12483  ast_copy_string(pris[span].pri.mwi_vm_numbers,
12484  conf->pri.pri.mwi_vm_numbers,
12485  sizeof(pris[span].pri.mwi_vm_numbers));
12486 #endif /* defined(HAVE_PRI_MWI) */
12487  ast_copy_string(pris[span].pri.idledial, conf->pri.pri.idledial, sizeof(pris[span].pri.idledial));
12488  ast_copy_string(pris[span].pri.idleext, conf->pri.pri.idleext, sizeof(pris[span].pri.idleext));
12489  ast_copy_string(pris[span].pri.internationalprefix, conf->pri.pri.internationalprefix, sizeof(pris[span].pri.internationalprefix));
12490  ast_copy_string(pris[span].pri.nationalprefix, conf->pri.pri.nationalprefix, sizeof(pris[span].pri.nationalprefix));
12491  ast_copy_string(pris[span].pri.localprefix, conf->pri.pri.localprefix, sizeof(pris[span].pri.localprefix));
12492  ast_copy_string(pris[span].pri.privateprefix, conf->pri.pri.privateprefix, sizeof(pris[span].pri.privateprefix));
12493  ast_copy_string(pris[span].pri.unknownprefix, conf->pri.pri.unknownprefix, sizeof(pris[span].pri.unknownprefix));
12494  pris[span].pri.moh_signaling = conf->pri.pri.moh_signaling;
12495  pris[span].pri.resetinterval = conf->pri.pri.resetinterval;
12496 #if defined(HAVE_PRI_DISPLAY_TEXT)
12497  pris[span].pri.display_flags_send = conf->pri.pri.display_flags_send;
12498  pris[span].pri.display_flags_receive = conf->pri.pri.display_flags_receive;
12499 #endif /* defined(HAVE_PRI_DISPLAY_TEXT) */
12500 #if defined(HAVE_PRI_MCID)
12501  pris[span].pri.mcid_send = conf->pri.pri.mcid_send;
12502 #endif /* defined(HAVE_PRI_MCID) */
12503  pris[span].pri.force_restart_unavailable_chans = conf->pri.pri.force_restart_unavailable_chans;
12504 #if defined(HAVE_PRI_DATETIME_SEND)
12505  pris[span].pri.datetime_send = conf->pri.pri.datetime_send;
12506 #endif /* defined(HAVE_PRI_DATETIME_SEND) */
12507 
12508  for (x = 0; x < PRI_MAX_TIMERS; x++) {
12509  pris[span].pri.pritimers[x] = conf->pri.pri.pritimers[x];
12510  }
12511 
12512 #if defined(HAVE_PRI_CALL_WAITING)
12513  /* Channel initial config parameters. */
12514  pris[span].pri.ch_cfg.stripmsd = conf->chan.stripmsd;
12515  pris[span].pri.ch_cfg.hidecallerid = conf->chan.hidecallerid;
12516  pris[span].pri.ch_cfg.hidecalleridname = conf->chan.hidecalleridname;
12517  pris[span].pri.ch_cfg.immediate = conf->chan.immediate;
12518  pris[span].pri.ch_cfg.priexclusive = conf->chan.priexclusive;
12519  pris[span].pri.ch_cfg.priindication_oob = conf->chan.priindication_oob;
12520  pris[span].pri.ch_cfg.use_callerid = conf->chan.use_callerid;
12521  pris[span].pri.ch_cfg.use_callingpres = conf->chan.use_callingpres;
12522  ast_copy_string(pris[span].pri.ch_cfg.context, conf->chan.context, sizeof(pris[span].pri.ch_cfg.context));
12523  ast_copy_string(pris[span].pri.ch_cfg.mohinterpret, conf->chan.mohinterpret, sizeof(pris[span].pri.ch_cfg.mohinterpret));
12524 #endif /* defined(HAVE_PRI_CALL_WAITING) */
12525  } else {
12526  ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", p.chanpos);
12527  destroy_dahdi_pvt(tmp);
12528  return NULL;
12529  }
12530  }
12531  }
12532 #endif
12533  } else {
12534  /* already exists in interface list */
12535  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));
12536  chan_sig = tmp->sig;
12537  if (tmp->subs[SUB_REAL].dfd > -1) {
12538  memset(&p, 0, sizeof(p));
12539  res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
12540  }
12541  }
12542  /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
12543  switch (chan_sig) {
12544  case SIG_FXSKS:
12545  case SIG_FXSLS:
12546  case SIG_EM:
12547  case SIG_EM_E1:
12548  case SIG_EMWINK:
12549  case SIG_FEATD:
12550  case SIG_FEATDMF:
12551  case SIG_FEATDMF_TA:
12552  case SIG_FEATB:
12553  case SIG_E911:
12554  case SIG_SF:
12555  case SIG_SFWINK:
12556  case SIG_FGC_CAMA:
12557  case SIG_FGC_CAMAMF:
12558  case SIG_SF_FEATD:
12559  case SIG_SF_FEATDMF:
12560  case SIG_SF_FEATB:
12561  p.starttime = 250;
12562  break;
12563  }
12564 
12565  if (tmp->radio) {
12566  /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
12567  p.channo = channel;
12568  p.rxwinktime = 1;
12569  p.rxflashtime = 1;
12570  p.starttime = 1;
12571  p.debouncetime = 5;
12572  } else {
12573  p.channo = channel;
12574  /* Override timing settings based on config file */
12575  if (conf->timing.prewinktime >= 0)
12576  p.prewinktime = conf->timing.prewinktime;
12577  if (conf->timing.preflashtime >= 0)
12578  p.preflashtime = conf->timing.preflashtime;
12579  if (conf->timing.winktime >= 0)
12580  p.winktime = conf->timing.winktime;
12581  if (conf->timing.flashtime >= 0)
12582  p.flashtime = conf->timing.flashtime;
12583  if (conf->timing.starttime >= 0)
12584  p.starttime = conf->timing.starttime;
12585  if (conf->timing.rxwinktime >= 0)
12586  p.rxwinktime = conf->timing.rxwinktime;
12587  if (conf->timing.rxflashtime >= 0)
12588  p.rxflashtime = conf->timing.rxflashtime;
12589  if (conf->timing.debouncetime >= 0)
12590  p.debouncetime = conf->timing.debouncetime;
12591  }
12592 
12593  /* don't set parms on a pseudo-channel */
12594  if (tmp->subs[SUB_REAL].dfd >= 0)
12595  {
12596  res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_PARAMS, &p);
12597  if (res < 0) {
12598  ast_log(LOG_ERROR, "Unable to set parameters: %s\n", strerror(errno));
12599  destroy_dahdi_pvt(tmp);
12600  return NULL;
12601  }
12602  }
12603 #if 1
12604  if (!here && (tmp->subs[SUB_REAL].dfd > -1)) {
12605  memset(&bi, 0, sizeof(bi));
12606  res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
12607  if (!res) {
12608  bi.txbufpolicy = conf->chan.buf_policy;
12609  bi.rxbufpolicy = conf->chan.buf_policy;
12610  bi.numbufs = conf->chan.buf_no;
12611  res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
12612  if (res < 0) {
12613  ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", channel, strerror(errno));
12614  }
12615  } else {
12616  ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", channel, strerror(errno));
12617  }
12618  tmp->buf_policy = conf->chan.buf_policy;
12619  tmp->buf_no = conf->chan.buf_no;
12620  tmp->usefaxbuffers = conf->chan.usefaxbuffers;
12621  tmp->faxbuf_policy = conf->chan.faxbuf_policy;
12622  tmp->faxbuf_no = conf->chan.faxbuf_no;
12623  /* This is not as gnarly as it may first appear. If the ioctl above failed, we'd be setting
12624  * tmp->bufsize to zero which would cause subsequent faxbuffer-related ioctl calls to fail.
12625  * The reason the ioctl call above failed should to be determined before worrying about the
12626  * faxbuffer-related ioctl calls */
12627  tmp->bufsize = bi.bufsize;
12628  }
12629 #endif
12630  tmp->immediate = conf->chan.immediate;
12631  tmp->transfertobusy = conf->chan.transfertobusy;
12632  if (chan_sig & __DAHDI_SIG_FXS) {
12633  tmp->mwimonitor_fsk = conf->chan.mwimonitor_fsk;
12634  tmp->mwimonitor_neon = conf->chan.mwimonitor_neon;
12635  tmp->mwimonitor_rpas = conf->chan.mwimonitor_rpas;
12636  }
12637  tmp->ringt_base = ringt_base;
12638  tmp->firstradio = 0;
12639  if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS))
12640  tmp->permcallwaiting = conf->chan.callwaiting;
12641  else
12642  tmp->permcallwaiting = 0;
12643  /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */
12644  tmp->destroy = 0;
12645  tmp->drings = conf->chan.drings;
12646 
12647  /* 10 is a nice default. */
12648  if (tmp->drings.ringnum[0].range == 0)
12649  tmp->drings.ringnum[0].range = 10;
12650  if (tmp->drings.ringnum[1].range == 0)
12651  tmp->drings.ringnum[1].range = 10;
12652  if (tmp->drings.ringnum[2].range == 0)
12653  tmp->drings.ringnum[2].range = 10;
12654 
12657  tmp->threewaycalling = conf->chan.threewaycalling;
12658  tmp->adsi = conf->chan.adsi;
12659  tmp->use_smdi = conf->chan.use_smdi;
12660  tmp->permhidecallerid = conf->chan.hidecallerid;
12661  tmp->hidecalleridname = conf->chan.hidecalleridname;
12662  tmp->callreturn = conf->chan.callreturn;
12663  tmp->echocancel = conf->chan.echocancel;
12664  tmp->echotraining = conf->chan.echotraining;
12665  tmp->pulse = conf->chan.pulse;
12666  if (tmp->echocancel.head.tap_length) {
12667  tmp->echocanbridged = conf->chan.echocanbridged;
12668  } else {
12669  if (conf->chan.echocanbridged)
12670  ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
12671  tmp->echocanbridged = 0;
12672  }
12673  tmp->busydetect = conf->chan.busydetect;
12674  tmp->busycount = conf->chan.busycount;
12675  tmp->busy_cadence = conf->chan.busy_cadence;
12676  tmp->callprogress = conf->chan.callprogress;
12677  tmp->waitfordialtone = conf->chan.waitfordialtone;
12678  tmp->dialtone_detect = conf->chan.dialtone_detect;
12683  tmp->cancallforward = conf->chan.cancallforward;
12684  tmp->dtmfrelax = conf->chan.dtmfrelax;
12685  tmp->callwaiting = tmp->permcallwaiting;
12686  tmp->hidecallerid = tmp->permhidecallerid;
12687  tmp->channel = channel;
12688  tmp->stripmsd = conf->chan.stripmsd;
12689  tmp->use_callerid = conf->chan.use_callerid;
12690  tmp->cid_signalling = conf->chan.cid_signalling;
12691  tmp->cid_start = conf->chan.cid_start;
12692  tmp->dahditrcallerid = conf->chan.dahditrcallerid;
12693  tmp->restrictcid = conf->chan.restrictcid;
12694  tmp->use_callingpres = conf->chan.use_callingpres;
12695  if (tmp->usedistinctiveringdetection) {
12696  if (!tmp->use_callerid) {
12697  ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
12698  tmp->use_callerid = 1;
12699  }
12700  }
12701 
12702  if (tmp->cid_signalling == CID_SIG_SMDI) {
12703  if (!tmp->use_smdi) {
12704  ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
12705  tmp->use_smdi = 1;
12706  }
12707  }
12708  if (tmp->use_smdi) {
12710  if (!(tmp->smdi_iface)) {
12711  ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
12712  tmp->use_smdi = 0;
12713  }
12714  }
12715 
12716  ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode));
12717  tmp->amaflags = conf->chan.amaflags;
12718  if (!here) {
12719  tmp->confno = -1;
12720  tmp->propconfno = -1;
12721  }
12722  tmp->canpark = conf->chan.canpark;
12723  tmp->transfer = conf->chan.transfer;
12724  ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext));
12725  ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language));
12726  ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret));
12727  ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest));
12728  ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context));
12729  ast_copy_string(tmp->description, conf->chan.description, sizeof(tmp->description));
12730  ast_copy_string(tmp->parkinglot, conf->chan.parkinglot, sizeof(tmp->parkinglot));
12731  tmp->cid_ton = 0;
12732  if (dahdi_analog_lib_handles(tmp->sig, tmp->radio, tmp->oprmode)) {
12733  ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num));
12734  ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name));
12735  } else {
12736  tmp->cid_num[0] = '\0';
12737  tmp->cid_name[0] = '\0';
12738  }
12739 #if defined(HAVE_PRI)
12740  if (dahdi_sig_pri_lib_handles(tmp->sig)) {
12741  tmp->cid_tag[0] = '\0';
12742  } else
12743 #endif /* defined(HAVE_PRI) */
12744  {
12745  ast_copy_string(tmp->cid_tag, conf->chan.cid_tag, sizeof(tmp->cid_tag));
12746  }
12747  tmp->cid_subaddr[0] = '\0';
12748  ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox));
12749  if (channel != CHAN_PSEUDO && !ast_strlen_zero(tmp->mailbox)) {
12750  /* This module does not handle MWI in an event-based manner. However, it
12751  * subscribes to MWI for each mailbox that is configured so that the core
12752  * knows that we care about it. Then, chan_dahdi will get the MWI from the
12753  * event cache instead of checking the mailbox directly. */
12755  }
12756 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
12757  tmp->mwisend_setting = conf->chan.mwisend_setting;
12758  tmp->mwisend_fsk = conf->chan.mwisend_fsk;
12759  tmp->mwisend_rpas = conf->chan.mwisend_rpas;
12760 #endif
12761 
12762  tmp->group = conf->chan.group;
12763  tmp->callgroup = conf->chan.callgroup;
12764  tmp->pickupgroup= conf->chan.pickupgroup;
12769  if (conf->chan.vars) {
12770  struct ast_variable *v, *tmpvar;
12771  for (v = conf->chan.vars ; v ; v = v->next) {
12772  if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
12773  if (ast_variable_list_replace(&tmp->vars, tmpvar)) {
12774  tmpvar->next = tmp->vars;
12775  tmp->vars = tmpvar;
12776  }
12777  }
12778  }
12779  }
12780  tmp->hwrxgain_enabled = conf->chan.hwrxgain_enabled;
12781  tmp->hwtxgain_enabled = conf->chan.hwtxgain_enabled;
12782  tmp->hwrxgain = conf->chan.hwrxgain;
12783  tmp->hwtxgain = conf->chan.hwtxgain;
12784  tmp->cid_rxgain = conf->chan.cid_rxgain;
12785  tmp->rxgain = conf->chan.rxgain;
12786  tmp->txgain = conf->chan.txgain;
12787  tmp->txdrc = conf->chan.txdrc;
12788  tmp->rxdrc = conf->chan.rxdrc;
12789  tmp->tonezone = conf->chan.tonezone;
12790  if (tmp->subs[SUB_REAL].dfd > -1) {
12791  if (tmp->hwrxgain_enabled) {
12792  tmp->hwrxgain_enabled = !set_hwgain(tmp->subs[SUB_REAL].dfd, tmp->hwrxgain, 0);
12793  }
12794  if (tmp->hwtxgain_enabled) {
12795  tmp->hwtxgain_enabled = !set_hwgain(tmp->subs[SUB_REAL].dfd, tmp->hwtxgain, 1);
12796  }
12797  set_actual_gain(tmp->subs[SUB_REAL].dfd, tmp->rxgain, tmp->txgain, tmp->rxdrc, tmp->txdrc, tmp->law);
12798  if (tmp->dsp)
12800  dahdi_conf_update(tmp);
12801  if (!here) {
12802  switch (chan_sig) {
12804  case SIG_SS7:
12805  case SIG_MFCR2:
12806  break;
12807  default:
12808  /* Hang it up to be sure it's good */
12809  dahdi_set_hook(tmp->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
12810  break;
12811  }
12812  }
12813  ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SETTONEZONE,&tmp->tonezone);
12814  if ((res = get_alarms(tmp)) != DAHDI_ALARM_NONE) {
12815  /* the dchannel is down so put the channel in alarm */
12816  switch (tmp->sig) {
12817 #ifdef HAVE_PRI
12819  sig_pri_set_alarm(tmp->sig_pvt, 1);
12820  break;
12821 #endif
12822 #if defined(HAVE_SS7)
12823  case SIG_SS7:
12824  sig_ss7_set_alarm(tmp->sig_pvt, 1);
12825  break;
12826 #endif /* defined(HAVE_SS7) */
12827  default:
12828  /* The only sig submodule left should be sig_analog. */
12829  analog_p = tmp->sig_pvt;
12830  if (analog_p) {
12831  analog_p->inalarm = 1;
12832  }
12833  tmp->inalarm = 1;
12834  break;
12835  }
12836  handle_alarms(tmp, res);
12837  }
12838  }
12839 
12845 
12846  if (!here) {
12847  tmp->locallyblocked = 0;
12848  tmp->remotelyblocked = 0;
12849  switch (tmp->sig) {
12850 #if defined(HAVE_PRI)
12852  tmp->inservice = 1;/* Inservice until actually implemented. */
12853 #if defined(HAVE_PRI_SERVICE_MESSAGES)
12854  ((struct sig_pri_chan *) tmp->sig_pvt)->service_status = 0;
12855  if (chan_sig == SIG_PRI) {
12856  char db_chan_name[20];
12857  char db_answer[5];
12858 
12859  /*
12860  * Initialize the active out-of-service status
12861  * and delete any record if the feature is not enabled.
12862  */
12863  snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, tmp->span, tmp->channel);
12864  if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) {
12865  unsigned *why;
12866 
12867  why = &((struct sig_pri_chan *) tmp->sig_pvt)->service_status;
12868  if (tmp->pri->enable_service_message_support) {
12869  char state;
12870 
12871  sscanf(db_answer, "%1c:%30u", &state, why);
12872 
12873  /* Ensure that only the implemented bits could be set.*/
12874  *why &= (SRVST_NEAREND | SRVST_FAREND);
12875  }
12876  if (!*why) {
12877  ast_db_del(db_chan_name, SRVST_DBKEY);
12878  }
12879  }
12880  }
12881 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
12882  break;
12883 #endif /* defined(HAVE_PRI) */
12884 #if defined(HAVE_SS7)
12885  case SIG_SS7:
12886  tmp->inservice = 0;
12887  if (tmp->ss7->flags & LINKSET_FLAG_INITIALHWBLO) {
12889  }
12890  break;
12891 #endif /* defined(HAVE_SS7) */
12892  default:
12893  /* We default to in service on protocols that don't have a reset */
12894  tmp->inservice = 1;
12895  break;
12896  }
12897  }
12898 
12899  switch (tmp->sig) {
12900 #if defined(HAVE_PRI)
12902  if (pri_chan) {
12903  pri_chan->channel = tmp->channel;
12904  pri_chan->hidecallerid = tmp->hidecallerid;
12905  pri_chan->hidecalleridname = tmp->hidecalleridname;
12906  pri_chan->immediate = tmp->immediate;
12907  pri_chan->inalarm = tmp->inalarm;
12908  pri_chan->priexclusive = tmp->priexclusive;
12909  pri_chan->priindication_oob = tmp->priindication_oob;
12910  pri_chan->use_callerid = tmp->use_callerid;
12911  pri_chan->use_callingpres = tmp->use_callingpres;
12912  ast_copy_string(pri_chan->context, tmp->context,
12913  sizeof(pri_chan->context));
12914  ast_copy_string(pri_chan->mohinterpret, tmp->mohinterpret,
12915  sizeof(pri_chan->mohinterpret));
12916  pri_chan->stripmsd = tmp->stripmsd;
12917  }
12918  break;
12919 #endif /* defined(HAVE_PRI) */
12920 #if defined(HAVE_SS7)
12921  case SIG_SS7:
12922  if (ss7_chan) {
12923  ss7_chan->inalarm = tmp->inalarm;
12924  ss7_chan->inservice = tmp->inservice;
12925 
12926  ss7_chan->stripmsd = tmp->stripmsd;
12927  ss7_chan->hidecallerid = tmp->hidecallerid;
12928  ss7_chan->use_callerid = tmp->use_callerid;
12929  ss7_chan->use_callingpres = tmp->use_callingpres;
12930  ss7_chan->immediate = tmp->immediate;
12931  ss7_chan->locallyblocked = tmp->locallyblocked;
12932  ss7_chan->remotelyblocked = tmp->remotelyblocked;
12933  ast_copy_string(ss7_chan->context, tmp->context,
12934  sizeof(ss7_chan->context));
12935  ast_copy_string(ss7_chan->mohinterpret, tmp->mohinterpret,
12936  sizeof(ss7_chan->mohinterpret));
12937  }
12938  break;
12939 #endif /* defined(HAVE_SS7) */
12940  default:
12941  /* The only sig submodule left should be sig_analog. */
12942  analog_p = tmp->sig_pvt;
12943  if (analog_p) {
12944  analog_p->channel = tmp->channel;
12948  analog_p->permcallwaiting = conf->chan.callwaiting; /* permcallwaiting possibly modified in analog_config_complete */
12949  analog_p->callreturn = conf->chan.callreturn;
12950  analog_p->cancallforward = conf->chan.cancallforward;
12951  analog_p->canpark = conf->chan.canpark;
12952  analog_p->dahditrcallerid = conf->chan.dahditrcallerid;
12953  analog_p->immediate = conf->chan.immediate;
12954  analog_p->permhidecallerid = conf->chan.permhidecallerid;
12955  analog_p->pulse = conf->chan.pulse;
12956  analog_p->threewaycalling = conf->chan.threewaycalling;
12957  analog_p->transfer = conf->chan.transfer;
12958  analog_p->transfertobusy = conf->chan.transfertobusy;
12959  analog_p->use_callerid = tmp->use_callerid;
12961  analog_p->use_smdi = tmp->use_smdi;
12962  analog_p->smdi_iface = tmp->smdi_iface;
12963  analog_p->outsigmod = ANALOG_SIG_NONE;
12964  analog_p->echotraining = conf->chan.echotraining;
12965  analog_p->cid_signalling = conf->chan.cid_signalling;
12966  analog_p->stripmsd = conf->chan.stripmsd;
12967  switch (conf->chan.cid_start) {
12968  case CID_START_POLARITY:
12970  break;
12971  case CID_START_POLARITY_IN:
12973  break;
12976  break;
12977  default:
12978  analog_p->cid_start = ANALOG_CID_START_RING;
12979  break;
12980  }
12981  analog_p->callwaitingcallerid = conf->chan.callwaitingcallerid;
12982  analog_p->ringt = conf->chan.ringt;
12983  analog_p->ringt_base = ringt_base;
12984  analog_p->onhooktime = time(NULL);
12985  if (chan_sig & __DAHDI_SIG_FXO) {
12986  memset(&p, 0, sizeof(p));
12987  res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
12988  if (!res) {
12989  analog_p->fxsoffhookstate = p.rxisoffhook;
12990  }
12991 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
12992  res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting);
12993 #endif
12994  }
12995  analog_p->msgstate = -1;
12996 
12997  ast_copy_string(analog_p->mohsuggest, conf->chan.mohsuggest, sizeof(analog_p->mohsuggest));
12998  ast_copy_string(analog_p->cid_num, conf->chan.cid_num, sizeof(analog_p->cid_num));
12999  ast_copy_string(analog_p->cid_name, conf->chan.cid_name, sizeof(analog_p->cid_name));
13000 
13001  analog_config_complete(analog_p);
13002  }
13003  break;
13004  }
13005 #if defined(HAVE_PRI)
13006  if (tmp->channel == CHAN_PSEUDO) {
13007  /*
13008  * Save off pseudo channel buffer policy values for dynamic creation of
13009  * no B channel interfaces.
13010  */
13011  dahdi_pseudo_parms.buf_no = tmp->buf_no;
13012  dahdi_pseudo_parms.buf_policy = tmp->buf_policy;
13013  dahdi_pseudo_parms.faxbuf_no = tmp->faxbuf_no;
13014  dahdi_pseudo_parms.faxbuf_policy = tmp->faxbuf_policy;
13015  }
13016 #endif /* defined(HAVE_PRI) */
13017  }
13018  if (tmp && !here) {
13019  /* Add the new channel interface to the sorted channel interface list. */
13020  dahdi_iflist_insert(tmp);
13021  }
13022  return tmp;
13023 }
char defcontext[AST_MAX_CONTEXT]
Default distinctive ring context.
Definition: chan_dahdi.h:453
int outsigmod
Definition: chan_dahdi.h:149
struct ast_variable * next
int matchdigit_timeout
Time (ms) to wait, in case of ambiguous match (in an analog phone)
Definition: chan_dahdi.h:635
char description[32]
A description for the channel configuration.
Definition: chan_dahdi.h:449
enum sip_cc_notify_state state
Definition: chan_sip.c:959
int dtmfrelax
Definition: chan_dahdi.h:665
unsigned int priexclusive
TRUE if PRI B channels are always exclusively selected.
Definition: chan_dahdi.h:311
char cid_name[AST_MAX_EXTENSION]
Definition: sig_analog.h:314
unsigned int threewaycalling
Definition: sig_analog.h:290
int faxbuf_no
Definition: chan_dahdi.h:141
unsigned int use_callerid
Definition: sig_analog.h:293
struct ast_smdi_interface * smdi_iface
The SMDI interface to get SMDI messages from.
Definition: sig_analog.h:301
char cid_subaddr[AST_MAX_EXTENSION]
Caller ID subaddress from an incoming call.
Definition: chan_dahdi.h:490
unsigned int permhidecallerid
TRUE if the outgoing caller ID is blocked/restricted/hidden.
Definition: chan_dahdi.h:301
unsigned int cancallforward
TRUE if support for call forwarding enabled. Dial *72 to enable call forwarding. Dial *73 to disable ...
Definition: chan_dahdi.h:214
unsigned int priexclusive
Definition: sig_pri.h:285
int cid_ton
Caller ID Q.931 TON/NPI field values. Set by PRI. Zero otherwise.
Definition: chan_dahdi.h:486
struct ast_namedgroups * named_pickupgroups
Named pickup groups this belongs to.
Definition: chan_dahdi.h:532
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:770
int tonezone
Definition: chan_dahdi.h:166
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:202
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int firstdigit_timeout
Time (ms) to detect first digit (in an analog phone)
Definition: chan_dahdi.h:625
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
unsigned int immediate
Definition: sig_analog.h:286
unsigned int use_callingpres
Definition: sig_pri.h:288
unsigned int dpc
Definition: sig_ss7.h:202
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#define SIG_FXOGS
Definition: chan_dahdi.h:735
#define SIG_SF_FEATDMF
Definition: chan_dahdi.h:740
char parkinglot[AST_MAX_EXTENSION]
Definition: chan_dahdi.h:471
int cid_signalling
Definition: chan_dahdi.h:541
unsigned int callwaitingcallerid
TRUE if send caller ID for Call Waiting.
Definition: chan_dahdi.h:207
unsigned int priindication_oob
Definition: sig_pri.h:286
unsigned int use_callerid
Definition: sig_pri.h:287
unsigned int hidecallerid
TRUE if the outgoing caller ID is blocked/hidden.
Definition: sig_ss7.h:213
struct dahdi_pvt * next
Definition: chan_dahdi.h:168
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
int interdigit_timeout
Time (ms) to detect following digits (in an analog phone)
Definition: chan_dahdi.h:630
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
int cid_start
Definition: chan_dahdi.h:542
#define CID_SIG_SMDI
Definition: callerid.h:63
int ringt
Ring timeout timer??
Definition: chan_dahdi.h:556
char mohsuggest[MAX_MUSICCLASS]
Definition: sig_analog.h:312
unsigned int firstradio
TRUE if over a radio and dahdi_read() has been called.
Definition: chan_dahdi.h:256
int echotraining
Definition: sig_analog.h:307
int ringt_base
Definition: sig_analog.h:357
#define LOG_WARNING
Definition: logger.h:274
struct ast_mwi_subscriber * mwi_event_sub
Opaque event subscription parameters for message waiting indication support.
Definition: chan_dahdi.h:656
unsigned int locallyblocked
Bitmask for the channel being locally blocked.
Definition: chan_dahdi.h:404
static int usedistinctiveringdetection
Definition: chan_dahdi.c:607
float txdrc
Definition: chan_dahdi.h:163
unsigned int inservice
TRUE if channel is out of reset and ready.
Definition: chan_dahdi.h:395
#define SIG_EM
Definition: chan_dahdi.h:722
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
#define LINKSET_FLAG_INITIALHWBLO
Definition: sig_ss7.h:69
static int tmp()
Definition: bt_open.c:389
int channel
Definition: sig_ss7.h:200
unsigned int callreturn
Definition: sig_analog.h:281
Structure for variables, used for configurations and for channel variables.
int buf_no
Definition: chan_dahdi.h:139
unsigned int dahditrcallerid
TRUE if we should use the callerid from incoming call on dahdi transfer.
Definition: chan_dahdi.h:365
unsigned int usefaxbuffers
Definition: chan_dahdi.h:252
int law_default
Default call PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:507
#define CID_START_POLARITY
Definition: callerid.h:66
unsigned int immediate
TRUE if the channel should be answered immediately without attempting to gather any digits...
Definition: chan_dahdi.h:284
int cid_signalling
Definition: sig_analog.h:308
#define SIG_FXOKS
Definition: chan_dahdi.h:736
#define SIG_FEATB
Definition: chan_dahdi.h:726
void * sig_pvt
Definition: chan_dahdi.h:709
float cid_rxgain
Amount of gain to increase during caller id.
Definition: chan_dahdi.h:157
#define CHAN_PSEUDO
Definition: chan_dahdi.c:556
#define SIG_BRI_PTMP
Definition: chan_dahdi.h:747
struct ast_dsp_busy_pattern busy_cadence
Busy cadence pattern description.
Definition: chan_dahdi.h:599
static void dahdi_iflist_insert(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:5282
int bufsize
Definition: chan_dahdi.h:138
unsigned int inalarm
TRUE if channel is associated with a link that is down.
Definition: sig_ss7.h:288
unsigned int transfertobusy
TRUE if allowed to flash-transfer to busy channels.
Definition: chan_dahdi.h:370
unsigned int usedistinctiveringdetection
Definition: sig_analog.h:294
#define SIG_FEATDMF_TA
Definition: chan_dahdi.h:728
unsigned int transfertobusy
Definition: sig_analog.h:292
Definition: muted.c:95
unsigned int inalarm
Definition: sig_pri.h:326
#define CID_START_POLARITY_IN
Definition: callerid.h:67
int law
Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:509
static int ifcount
Definition: chan_dahdi.c:628
#define NULL
Definition: resample.c:96
void dahdi_conf_update(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4583
unsigned int adsi
TRUE if ADSI (Analog Display Services Interface) available.
Definition: chan_dahdi.h:177
#define ast_cc_config_params_init()
Allocate and initialize an ast_cc_config_params structure.
Definition: ccss.h:135
int ringt_base
Ring timeout base.
Definition: chan_dahdi.h:561
float txgain
Software Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:161
int polarityonanswerdelay
Definition: sig_analog.h:309
#define SS7_BLOCKED_HARDWARE
Definition: sig_ss7.h:75
unsigned int hidecalleridname
TRUE if hide just the name not the number for legacy PBX use.
Definition: chan_dahdi.h:276
unsigned int use_smdi
TRUE if SMDI (Simplified Message Desk Interface) is enabled.
Definition: sig_analog.h:299
#define SIG_SF
Definition: chan_dahdi.h:737
struct analog_pvt * analog_new(enum analog_sigtype signallingtype, void *private_data)
Definition: sig_analog.c:3928
unsigned int pulse
TRUE if we will pulse dial.
Definition: chan_dahdi.h:316
int oprmode
Definition: chan_dahdi.h:150
unsigned int cancallforward
Definition: sig_analog.h:282
#define ast_strlen_zero(foo)
Definition: strings.h:52
ast_group_t pickupgroup
Bitmapped pickup groups this belongs to.
Definition: chan_dahdi.h:522
char cid_name[AST_MAX_EXTENSION]
Caller ID name from an incoming call.
Definition: chan_dahdi.h:488
unsigned int hwtxgain_enabled
TRUE if hardware Tx gain set by Asterisk.
Definition: chan_dahdi.h:422
struct dahdi_params timing
Definition: chan_dahdi.c:844
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
static int set_hwgain(int fd, float gain, int tx_direction)
Definition: chan_dahdi.c:4728
#define SIG_EMWINK
Definition: chan_dahdi.h:723
unsigned int remotelyblocked
Bitmask for the channel being remotely blocked.
Definition: sig_ss7.h:235
static void handle_alarms(struct dahdi_pvt *p, int alms)
Definition: chan_dahdi.c:7364
static enum analog_sigtype dahdisig_to_analogsig(int sig)
Definition: chan_dahdi.c:1055
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:183
int stripmsd
Definition: sig_analog.h:310
char context[AST_MAX_CONTEXT]
Definition: sig_ss7.h:237
#define SIG_FGC_CAMAMF
Definition: chan_dahdi.h:730
#define ast_log
Definition: astobj2.c:42
char smdi_port[SMDI_MAX_FILENAME_LEN]
The serial port to listen for SMDI data on.
Definition: chan_dahdi.c:853
unsigned int hanguponpolarityswitch
TRUE if the call will be considered "hung up" on a polarity reversal.
Definition: chan_dahdi.h:261
unsigned int callreturn
TRUE if call return is enabled. (*69, if your dialplan doesn&#39;t catch this first)
Definition: chan_dahdi.h:195
unsigned int transfer
TRUE if call transfer is enabled.
Definition: chan_dahdi.h:339
unsigned int use_callerid
TRUE if caller ID is used on this channel.
Definition: sig_ss7.h:215
struct ast_cc_config_params * cc_params
Definition: chan_dahdi.h:710
int amaflags
Definition: chan_dahdi.h:646
int stripmsd
Number of most significant digits/characters to strip from the dialed number.
Definition: sig_ss7.h:209
int onhooktime
Definition: sig_analog.h:274
char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Voice mailbox location.
Definition: chan_dahdi.h:654
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 sig_ss7_chan * sig_ss7_chan_new(void *pvt_data, struct sig_ss7_linkset *ss7)
int stripmsd
Definition: sig_pri.h:291
#define SIG_FEATD
Definition: chan_dahdi.h:724
int echotraining
Echo training time. 0 = disabled.
Definition: chan_dahdi.h:587
static int sigtype_to_signalling(int sigtype)
Definition: chan_dahdi.c:12076
ast_mutex_t lock
Definition: chan_dahdi.h:125
static int ringt_base
Configured ring timeout base.
Definition: chan_dahdi.c:690
float rxdrc
Definition: chan_dahdi.h:164
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:296
static int dahdi_open(char *fn)
Definition: chan_dahdi.c:4086
void sig_ss7_set_alarm(struct sig_ss7_chan *p, int in_alarm)
unsigned int busydetect
TRUE if busy detection is enabled. (Listens for the beep-beep busy pattern.)
Definition: chan_dahdi.h:189
unsigned int mwimonitor_fsk
TRUE if the FXO port monitors for fsk type MWI indications from the other end.
Definition: chan_dahdi.h:380
char mohinterpret[MAX_MUSICCLASS]
Definition: sig_ss7.h:238
#define ast_variable_new(name, value, filename)
unsigned int inservice
TRUE if channel is in service.
Definition: sig_ss7.h:290
unsigned int use_callingpres
TRUE if we will use the calling presentation setting from the Asterisk channel for outgoing calls...
Definition: chan_dahdi.h:354
char cid_tag[AST_MAX_EXTENSION]
Caller ID tag from incoming call.
Definition: chan_dahdi.h:484
#define SIG_PRI
Definition: chan_dahdi.h:745
char cid_num[AST_MAX_EXTENSION]
Definition: sig_analog.h:313
unsigned int use_smdi
TRUE if SMDI (Simplified Message Desk Interface) is enabled.
Definition: chan_dahdi.h:432
#define SIG_SS7
Definition: chan_dahdi.h:750
#define SIG_E911
Definition: chan_dahdi.h:727
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
int busycount
Number of times to see "busy" tone before hanging up.
Definition: chan_dahdi.h:594
unsigned int destroy
TRUE if the channel is to be destroyed on hangup. (Used by pseudo channels.)
Definition: chan_dahdi.h:226
enum analog_cid_start cid_start
Definition: sig_analog.h:311
#define LOG_ERROR
Definition: logger.h:285
struct dahdi_pvt::@110 echocancel
Echo cancel parameters.
char mohinterpret[MAX_MUSICCLASS]
The configured music-on-hold class to use for calls.
Definition: chan_dahdi.h:465
char cid_num[AST_MAX_EXTENSION]
Caller ID number from an incoming call.
Definition: chan_dahdi.h:479
int analog_config_complete(struct analog_pvt *p)
Definition: sig_analog.c:3963
static char * dahdi_sig2str(int sig)
Definition: chan_dahdi.c:4391
unsigned int use_callerid
TRUE if caller ID is used on this channel.
Definition: chan_dahdi.h:347
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
int confno
Definition: chan_dahdi.h:510
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:241
int propconfno
Definition: chan_dahdi.h:512
unsigned int immediate
Definition: sig_pri.h:284
#define LOG_NOTICE
Definition: logger.h:263
#define SIG_PRI_LIB_HANDLE_CASES
Definition: chan_dahdi.h:756
struct ast_namedgroups * ast_ref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7838
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:811
#define SIG_SF_FEATD
Definition: chan_dahdi.h:739
unsigned int usedistinctiveringdetection
TRUE if distinctive rings are to be detected.
Definition: chan_dahdi.h:360
#define ast_free(a)
Definition: astmm.h:182
unsigned int hidecalleridname
Definition: sig_pri.h:283
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922
void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm)
unsigned int faxdetect_timeout
The number of seconds into call to disable fax detection. (0 = disabled)
Definition: chan_dahdi.h:620
unsigned int restrictcid
TRUE if caller ID is restricted.
Definition: chan_dahdi.h:325
static int get_alarms(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7204
unsigned int dahditrcallerid
Definition: sig_analog.h:284
char context[AST_MAX_CONTEXT]
The configured context for incoming calls.
Definition: chan_dahdi.h:444
unsigned int remotelyblocked
Bitmask for the channel being remotely blocked. 1 maintenance, 2 blocked in hardware.
Definition: chan_dahdi.h:413
unsigned int threewaycalling
TRUE if three way calling is enabled.
Definition: chan_dahdi.h:330
int msgstate
-1 = unknown, 0 = no messages, 1 = new messages available
Definition: sig_analog.h:277
unsigned int permhidecallerid
Definition: sig_analog.h:288
#define SIG_SFWINK
Definition: chan_dahdi.h:738
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:861
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:412
int stripmsd
Number of most significant digits/characters to strip from the dialed number.
Definition: chan_dahdi.h:568
struct ast_namedgroups * named_callgroups
Named call groups this belongs to.
Definition: chan_dahdi.h:527
struct ast_smdi_interface * smdi_iface
The SMDI interface to get SMDI messages from.
Definition: chan_dahdi.h:435
#define SIG_FGC_CAMA
Definition: chan_dahdi.h:729
#define SIG_SF_FEATB
Definition: chan_dahdi.h:741
#define SIG_MFCR2
Definition: chan_dahdi.h:753
int buf_policy
Definition: chan_dahdi.h:140
#define SIG_FXSKS
Definition: chan_dahdi.h:733
struct dahdi_echocanparams head
Definition: chan_dahdi.h:580
unsigned int mwimonitor_neon
TRUE if the FXO port monitors for neon type MWI indications from the other end.
Definition: chan_dahdi.h:375
unsigned int hidecallerid
Definition: sig_pri.h:282
int waitfordialtone
Number of milliseconds to wait for dialtone.
Definition: chan_dahdi.h:609
unsigned int locallyblocked
Bitmask for the channel being locally blocked.
Definition: sig_ss7.h:228
unsigned int immediate
Definition: sig_ss7.h:221
float hwtxgain
Hardware Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:155
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: main/db.c:429
struct dahdi_distRings drings
Distinctive Ring data.
Definition: chan_dahdi.h:438
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
unsigned int callwaitingcallerid
Definition: sig_analog.h:295
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
struct dahdi_pvt chan
Definition: chan_dahdi.c:832
#define SIG_FXSLS
Definition: chan_dahdi.h:731
struct ast_variable * vars
Channel variable list with associated values to set when a channel is created.
Definition: chan_dahdi.h:537
unsigned int priindication_oob
TRUE if PRI congestion/busy indications are sent out-of-band.
Definition: chan_dahdi.h:306
static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law)
Definition: chan_dahdi.c:4890
enum analog_sigtype outsigmod
Definition: sig_analog.h:306
unsigned int inalarm
Definition: sig_analog.h:325
unsigned int hidecallerid
TRUE if the outgoing caller ID is blocked/hidden.
Definition: chan_dahdi.h:270
int fxsoffhookstate
Definition: sig_analog.h:275
int faxbuf_policy
Definition: chan_dahdi.h:142
unsigned int echocanbridged
TRUE if echo cancellation enabled when bridged.
Definition: chan_dahdi.h:246
int polarityonanswerdelay
Minimal time period (ms) between the answer polarity switch and hangup polarity switch.
Definition: chan_dahdi.h:672
float rxgain
Software Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:159
unsigned int pulse
Definition: sig_analog.h:289
static void destroy_dahdi_pvt(struct dahdi_pvt *pvt)
Definition: chan_dahdi.c:5569
#define NUM_SPANS
Definition: chan_dahdi.c:553
#define ast_mutex_init(pmutex)
Definition: lock.h:184
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7832
unsigned int transfer
Definition: sig_analog.h:291
#define SIG_FXOLS
Definition: chan_dahdi.h:734
#define sig2str
Definition: chan_dahdi.c:4455
unsigned int hanguponpolarityswitch
Definition: sig_analog.h:285
struct sig_pri_chan * sig_pri_chan_new(void *pvt_data, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup)
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
#define CID_START_DTMF_NOALERT
Definition: callerid.h:68
#define SIG_FEATDMF
Definition: chan_dahdi.h:725
char context[AST_MAX_CONTEXT]
Definition: sig_pri.h:289
unsigned int canpark
Definition: sig_analog.h:283
int callprogress
Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
Definition: chan_dahdi.h:604
float hwrxgain
Hardware Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:153
char language[MAX_LANGUAGE]
Language configured for calls.
Definition: chan_dahdi.h:460
unsigned int hwrxgain_enabled
TRUE if hardware Rx gain set by Asterisk.
Definition: chan_dahdi.h:420
ast_group_t group
Bitmapped groups this belongs to.
Definition: chan_dahdi.h:505
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:230
int dialtone_detect
Number of frames to watch for dialtone in incoming calls.
Definition: chan_dahdi.h:614
unsigned int inalarm
TRUE if in an alarm condition.
Definition: chan_dahdi.h:286
int channel
Definition: chan_dahdi.h:538
int sendcalleridafter
Send caller ID on FXS after this many rings. Set to 1 for US.
Definition: chan_dahdi.h:679
ast_group_t callgroup
Bitmapped call groups this belongs to.
Definition: chan_dahdi.h:517
unsigned int permcallwaiting
Definition: sig_analog.h:287
char mohinterpret[MAX_MUSICCLASS]
Definition: sig_pri.h:290
unsigned int canpark
TRUE if support for call parking is enabled.
Definition: chan_dahdi.h:219
#define SIG_EM_E1
Definition: chan_dahdi.h:742
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1844
int channel
Definition: sig_pri.h:292
struct distRingData ringnum[3]
Definition: chan_dahdi.h:70
char mohsuggest[MAX_MUSICCLASS]
Suggested music-on-hold class for peer channel to use for calls.
Definition: chan_dahdi.h:470
unsigned int answeronpolarityswitch
Definition: sig_analog.h:280
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_dahdi.h:645
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:386

◆ monitor_pfds_clean()

static void monitor_pfds_clean ( void *  arg)
static

Definition at line 11477 of file chan_dahdi.c.

References ast_free.

Referenced by do_monitor().

11477  {
11478  struct pollfd **pfds = arg;
11479  ast_free(*pfds);
11480 }
#define ast_free(a)
Definition: astmm.h:182

◆ mwi_send_init()

static int mwi_send_init ( struct dahdi_pvt pvt)
static

Definition at line 10883 of file chan_dahdi.c.

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

Referenced by do_monitor().

10884 {
10885  int x;
10886 
10887 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
10888  /* Determine how this spill is to be sent */
10889  if (pvt->mwisend_rpas) {
10891  pvt->mwisendactive = 1;
10892  } else if (pvt->mwisend_fsk) {
10894  pvt->mwisendactive = 1;
10895  } else {
10896  pvt->mwisendactive = 0;
10897  return 0;
10898  }
10899 #else
10900  if (mwisend_rpas) {
10902  } else {
10904  }
10905  pvt->mwisendactive = 1;
10906 #endif
10907 
10908  if (pvt->cidspill) {
10909  ast_log(LOG_WARNING, "cidspill already exists when trying to send FSK MWI\n");
10910  ast_free(pvt->cidspill);
10911  pvt->cidspill = NULL;
10912  pvt->cidpos = 0;
10913  pvt->cidlen = 0;
10914  }
10916  if (!pvt->cidspill) {
10917  pvt->mwisendactive = 0;
10918  return -1;
10919  }
10920  x = DAHDI_FLUSH_BOTH;
10921  ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
10922  x = 3000;
10923  ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_ONHOOKTRANSFER, &x);
10924 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
10925  if (pvt->mwisend_fsk) {
10926 #endif
10928  CID_MWI_TYPE_MDMF_FULL, AST_LAW(pvt), pvt->cid_name, pvt->cid_num, 0);
10929  pvt->cidpos = 0;
10930 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
10931  }
10932 #endif
10933  return 0;
10934 }
int cidpos
Position in the cidspill buffer to send out next.
Definition: chan_dahdi.h:552
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
mwisend_states mwisend_current
Definition: chan_dahdi.h:112
#define CID_MWI_TYPE_MDMF_FULL
Definition: callerid.h:76
#define NULL
Definition: resample.c:96
#define MAX_CALLERID_SIZE
Definition: callerid.h:50
char cid_name[AST_MAX_EXTENSION]
Caller ID name from an incoming call.
Definition: chan_dahdi.h:488
static int mwisend_rpas
Definition: chan_dahdi.c:602
static int has_voicemail(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5033
#define ast_log
Definition: astobj2.c:42
struct mwisend_info mwisend_data
Definition: chan_dahdi.h:433
int cidlen
Length of the cidspill buffer containing samples.
Definition: chan_dahdi.h:554
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
#define AST_LAW(p)
Definition: chan_dahdi.c:521
char cid_num[AST_MAX_EXTENSION]
Caller ID number from an incoming call.
Definition: chan_dahdi.h:479
#define SUB_REAL
Definition: chan_dahdi.h:57
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
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:810
unsigned int mwisendactive
TRUE if a MWI message sending thread is active.
Definition: chan_dahdi.h:390

◆ mwi_send_process_buffer()

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

Definition at line 10936 of file chan_dahdi.c.

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

10937 {
10938  struct timeval now;
10939  int res;
10940 
10941  /* sanity check to catch if this had been interrupted previously
10942  * i.e. state says there is more to do but there is no spill allocated
10943  */
10944  if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current && !pvt->cidspill) {
10946  } else if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) {
10947  /* Normal processing -- Perform mwi send action */
10948  switch ( pvt->mwisend_data.mwisend_current) {
10949  case MWI_SEND_SA:
10950  /* Send the Ring Pulse Signal Alert */
10951  res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &AS_RP_cadence);
10952  if (res) {
10953  ast_log(LOG_WARNING, "Unable to set RP-AS ring cadence: %s\n", strerror(errno));
10954  goto quit;
10955  }
10956  res = dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RING);
10958  break;
10959  case MWI_SEND_SA_WAIT: /* do nothing until I get RINGEROFF event */
10960  break;
10961  case MWI_SEND_PAUSE: /* Wait between alert and spill - min of 500 mS*/
10962 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
10963  if (pvt->mwisend_fsk) {
10964 #endif
10965  gettimeofday(&now, NULL);
10966  if ((int)(now.tv_sec - pvt->mwisend_data.pause.tv_sec) * 1000000 + (int)now.tv_usec - (int)pvt->mwisend_data.pause.tv_usec > 500000) {
10968  }
10969 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
10970  } else { /* support for mwisendtype=nofsk */
10972  }
10973 #endif
10974  break;
10975  case MWI_SEND_SPILL:
10976  /* We read some number of bytes. Write an equal amount of data */
10977  if (0 < num_read) {
10978  if (num_read > pvt->cidlen - pvt->cidpos) {
10979  num_read = pvt->cidlen - pvt->cidpos;
10980  }
10981  res = write(pvt->subs[SUB_REAL].dfd, pvt->cidspill + pvt->cidpos, num_read);
10982  if (res > 0) {
10983  pvt->cidpos += res;
10984  if (pvt->cidpos >= pvt->cidlen) {
10986  }
10987  } else {
10988  ast_log(LOG_WARNING, "MWI FSK Send Write failed: %s\n", strerror(errno));
10989  goto quit;
10990  }
10991  }
10992  break;
10993  case MWI_SEND_CLEANUP:
10994  /* For now, do nothing */
10996  break;
10997  default:
10998  /* Should not get here, punt*/
10999  goto quit;
11000  }
11001  }
11002 
11004  if (pvt->cidspill) {
11005  ast_free(pvt->cidspill);
11006  pvt->cidspill = NULL;
11007  pvt->cidpos = 0;
11008  pvt->cidlen = 0;
11009  }
11010  pvt->mwisendactive = 0;
11011  }
11012  return 0;
11013 quit:
11014  if (pvt->cidspill) {
11015  ast_free(pvt->cidspill);
11016  pvt->cidspill = NULL;
11017  pvt->cidpos = 0;
11018  pvt->cidlen = 0;
11019  }
11020  pvt->mwisendactive = 0;
11021  return -1;
11022 }
int cidpos
Position in the cidspill buffer to send out next.
Definition: chan_dahdi.h:552
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
mwisend_states mwisend_current
Definition: chan_dahdi.h:112
#define NULL
Definition: resample.c:96
struct timeval pause
Definition: chan_dahdi.h:111
static struct dahdi_ring_cadence AS_RP_cadence
Definition: chan_dahdi.c:588
#define ast_log
Definition: astobj2.c:42
struct mwisend_info mwisend_data
Definition: chan_dahdi.h:433
int cidlen
Length of the cidspill buffer containing samples.
Definition: chan_dahdi.h:554
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define ast_free(a)
Definition: astmm.h:182
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922
unsigned int mwisendactive
TRUE if a MWI message sending thread is active.
Definition: chan_dahdi.h:390

◆ mwi_send_process_event()

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

Definition at line 11024 of file chan_dahdi.c.

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

Referenced by do_monitor().

11025 {
11026  int handled = 0;
11027 
11029  switch (event) {
11030  case DAHDI_EVENT_RINGEROFF:
11032  handled = 1;
11033 
11034  if (dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RINGOFF) ) {
11035  ast_log(LOG_WARNING, "Unable to finish RP-AS: %s mwi send aborted\n", strerror(errno));
11036  ast_free(pvt->cidspill);
11037  pvt->cidspill = NULL;
11039  pvt->mwisendactive = 0;
11040  } else {
11042  gettimeofday(&pvt->mwisend_data.pause, NULL);
11043  }
11044  }
11045  break;
11046  /* Going off hook, I need to punt this spill */
11047  case DAHDI_EVENT_RINGOFFHOOK:
11048  if (pvt->cidspill) {
11049  ast_free(pvt->cidspill);
11050  pvt->cidspill = NULL;
11051  pvt->cidpos = 0;
11052  pvt->cidlen = 0;
11053  }
11055  pvt->mwisendactive = 0;
11056  break;
11057  case DAHDI_EVENT_RINGERON:
11058  case DAHDI_EVENT_HOOKCOMPLETE:
11059  break;
11060  default:
11061  break;
11062  }
11063  }
11064  return handled;
11065 }
int cidpos
Position in the cidspill buffer to send out next.
Definition: chan_dahdi.h:552
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
mwisend_states mwisend_current
Definition: chan_dahdi.h:112
Definition: astman.c:222
#define NULL
Definition: resample.c:96
struct timeval pause
Definition: chan_dahdi.h:111
#define ast_log
Definition: astobj2.c:42
struct mwisend_info mwisend_data
Definition: chan_dahdi.h:433
int cidlen
Length of the cidspill buffer containing samples.
Definition: chan_dahdi.h:554
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define ast_free(a)
Definition: astmm.h:182
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922
unsigned int mwisendactive
TRUE if a MWI message sending thread is active.
Definition: chan_dahdi.h:390

◆ mwi_thread()

static void* mwi_thread ( void *  data)
static

Definition at line 10726 of file chan_dahdi.c.

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

10727 {
10728  struct mwi_thread_data *mtd = data;
10729  struct callerid_state *cs;
10730  pthread_t threadid;
10731  int samples = 0;
10732  char *name, *number;
10733  int flags;
10734  int i, res;
10735  unsigned int spill_done = 0;
10736  int spill_result = -1;
10737 
10738  if (!(cs = callerid_new(mtd->pvt->cid_signalling))) {
10739  goto quit_no_clean;
10740  }
10741 
10742  callerid_feed(cs, mtd->buf, mtd->len, AST_LAW(mtd->pvt));
10743 
10744  bump_gains(mtd->pvt);
10745 
10746  for (;;) {
10747  i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10748  if ((res = ioctl(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_IOMUX, &i))) {
10749  ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
10750  goto quit;
10751  }
10752 
10753  if (i & DAHDI_IOMUX_SIGEVENT) {
10754  struct ast_channel *chan;
10755  ast_callid callid = 0;
10756  int callid_created;
10757 
10758  /* If we get an event, screen out events that we do not act on.
10759  * Otherwise, cancel and go to the simple switch to let it deal with it.
10760  */
10761  res = dahdi_get_event(mtd->pvt->subs[SUB_REAL].dfd);
10762 
10763  switch (res) {
10764  case DAHDI_EVENT_NEONMWI_ACTIVE:
10765  case DAHDI_EVENT_NEONMWI_INACTIVE:
10766  case DAHDI_EVENT_NONE:
10767  case DAHDI_EVENT_BITSCHANGED:
10768  break;
10769  case DAHDI_EVENT_NOALARM:
10770  if (dahdi_analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
10771  struct analog_pvt *analog_p = mtd->pvt->sig_pvt;
10772 
10773  analog_p->inalarm = 0;
10774  }
10775  mtd->pvt->inalarm = 0;
10776  handle_clear_alarms(mtd->pvt);
10777  break;
10778  case DAHDI_EVENT_ALARM:
10779  if (dahdi_analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
10780  struct analog_pvt *analog_p = mtd->pvt->sig_pvt;
10781 
10782  analog_p->inalarm = 1;
10783  }
10784  mtd->pvt->inalarm = 1;
10785  res = get_alarms(mtd->pvt);
10786  handle_alarms(mtd->pvt, res);
10787  break; /* What to do on channel alarm ???? -- fall thru intentionally?? */
10788  default:
10789  callid_created = ast_callid_threadstorage_auto(&callid);
10790  ast_log(LOG_NOTICE, "Got event %d (%s)... Passing along to analog_ss_thread\n", res, event2str(res));
10791  callerid_free(cs);
10792 
10793  restore_gains(mtd->pvt);
10794  mtd->pvt->ringt = mtd->pvt->ringt_base;
10795 
10796  if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, NULL, NULL, callid))) {
10797  int result;
10798 
10799  if (dahdi_analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
10800  result = analog_ss_thread_start(mtd->pvt->sig_pvt, chan);
10801  } else {
10802  result = ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan);
10803  }
10804  if (result) {
10805  ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", mtd->pvt->channel);
10806  res = tone_zone_play_tone(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
10807  if (res < 0)
10808  ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", mtd->pvt->channel);
10809  ast_hangup(chan);
10810  }
10811  } else {
10812  ast_log(LOG_WARNING, "Could not create channel to handle call\n");
10813  }
10814 
10815  ast_callid_threadstorage_auto_clean(callid, callid_created);
10816  goto quit_no_clean;
10817  }
10818  } else if (i & DAHDI_IOMUX_READ) {
10819  if ((res = read(mtd->pvt->subs[SUB_REAL].dfd, mtd->buf, sizeof(mtd->buf))) < 0) {
10820  if (errno != ELAST) {
10821  ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
10822  goto quit;
10823  }
10824  break;
10825  }
10826  samples += res;
10827  if (!spill_done) {
10828  if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) {
10829  /*
10830  * The previous diagnostic message output likely
10831  * explains why it failed.
10832  */
10833  ast_log(LOG_WARNING, "Failed to decode CallerID\n");
10834  break;
10835  } else if (spill_result) {
10836  spill_done = 1;
10837  }
10838  } else {
10839  /* keep reading data until the energy level drops below the threshold
10840  so we don't get another 'trigger' on the remaining carrier signal
10841  */
10842  if (calc_energy(mtd->buf, res, AST_LAW(mtd->pvt)) <= mwilevel)
10843  break;
10844  }
10845  if (samples > (8000 * 4)) /*Termination case - time to give up*/
10846  break;
10847  }
10848  }
10849 
10850  if (spill_result == 1) {
10851  callerid_get(cs, &name, &number, &flags);
10852  if (flags & CID_MSGWAITING) {
10853  ast_log(LOG_NOTICE, "mwi: Have Messages on channel %d\n", mtd->pvt->channel);
10854  notify_message(mtd->pvt->mailbox, 1);
10855  } else if (flags & CID_NOMSGWAITING) {
10856  ast_log(LOG_NOTICE, "mwi: No Messages on channel %d\n", mtd->pvt->channel);
10857  notify_message(mtd->pvt->mailbox, 0);
10858  } else {
10859  ast_log(LOG_NOTICE, "mwi: Status unknown on channel %d\n", mtd->pvt->channel);
10860  }
10861  }
10862 
10863 
10864 quit:
10865  callerid_free(cs);
10866 
10867  restore_gains(mtd->pvt);
10868 
10869 quit_no_clean:
10870  mtd->pvt->mwimonitoractive = 0;
10871  ast_free(mtd);
10872 
10873  return NULL;
10874 }
struct dahdi_pvt * pvt
Definition: chan_dahdi.c:10707
Main Channel structure associated with a channel.
#define CID_MSGWAITING
Definition: callerid.h:56
static void handle_clear_alarms(struct dahdi_pvt *p)
Definition: chan_dahdi.c:3537
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:563
int cid_signalling
Definition: chan_dahdi.h:541
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
int ringt
Ring timeout timer??
Definition: chan_dahdi.h:556
#define LOG_WARNING
Definition: logger.h:274
char * name
Definition: chan_dahdi.c:4361
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:2042
static void * analog_ss_thread(void *data)
Definition: chan_dahdi.c:9512
void * sig_pvt
Definition: chan_dahdi.h:709
unsigned int ast_callid
Definition: logger.h:87
static int calc_energy(const unsigned char *buf, int len, struct ast_format *law)
Definition: chan_dahdi.c:10712
#define NULL
Definition: resample.c:96
int ringt_base
Ring timeout base.
Definition: chan_dahdi.h:561
static int mwilevel
Definition: chan_dahdi.c:612
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:188
int oprmode
Definition: chan_dahdi.h:150
static void handle_alarms(struct dahdi_pvt *p, int alms)
Definition: chan_dahdi.c:7364
#define ast_log
Definition: astobj2.c:42
char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Voice mailbox location.
Definition: chan_dahdi.h:654
#define CID_NOMSGWAITING
Definition: callerid.h:57
unsigned int mwimonitoractive
TRUE if an MWI monitor thread is currently active.
Definition: chan_dahdi.h:388
#define AST_LAW(p)
Definition: chan_dahdi.c:521
static int restore_gains(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4909
static int bump_gains(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4895
static void notify_message(char *mailbox, int thereornot)
Send MWI state change.
Definition: chan_dahdi.c:3292
int analog_ss_thread_start(struct analog_pvt *p, struct ast_channel *chan)
Definition: sig_analog.c:2665
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define LOG_NOTICE
Definition: logger.h:263
#define ast_free(a)
Definition: astmm.h:182
static int get_alarms(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7204
static int dahdi_get_event(int fd)
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition: chan_dahdi.c:652
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
static const char * event2str(int event)
Definition: chan_dahdi.c:4382
void callerid_free(struct callerid_state *cid)
This function frees callerid_state cid.
Definition: callerid.c:734
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:2020
static PGresult * result
Definition: cel_pgsql.c:88
unsigned int inalarm
Definition: sig_analog.h:325
struct callerid_state * callerid_new(int cid_signalling)
Create a callerID state machine.
Definition: callerid.c:129
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
unsigned int inalarm
TRUE if in an alarm condition.
Definition: chan_dahdi.h:286
int channel
Definition: chan_dahdi.h:538
char number[64]
Definition: callerid.c:54
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:9153
unsigned char buf[READ_SIZE]
Definition: chan_dahdi.c:10708
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:545

◆ my_all_subchannels_hungup()

static void my_all_subchannels_hungup ( void *  pvt)
static

Definition at line 2066 of file chan_dahdi.c.

References ast_dsp_free(), ast_log, dahdi_pvt::channel, conf_del(), 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.

2067 {
2068  struct dahdi_pvt *p = pvt;
2069  int res, law;
2070 
2071  p->faxhandled = 0;
2072  p->didtdd = 0;
2073 
2074  if (p->dsp) {
2075  ast_dsp_free(p->dsp);
2076  p->dsp = NULL;
2077  }
2078 
2079  p->law = p->law_default;
2080  law = p->law_default;
2081  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
2082  if (res < 0)
2083  ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
2084 
2085  dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
2086 
2087 #if 1
2088  {
2089  int i;
2090  p->owner = NULL;
2091  /* Cleanup owners here */
2092  for (i = 0; i < 3; i++) {
2093  p->subs[i].owner = NULL;
2094  }
2095  }
2096 #endif
2097 
2098  reset_conf(p);
2099  if (num_restart_pending == 0) {
2100  restart_monitor();
2101  }
2102 }
static int num_restart_pending
Definition: chan_dahdi.c:645
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
#define LOG_WARNING
Definition: logger.h:274
struct ast_channel * owner
Definition: chan_dahdi.h:127
int law_default
Default call PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:507
int law
Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:509
#define NULL
Definition: resample.c:96
static int restart_monitor(void)
Definition: chan_dahdi.c:11770
unsigned int didtdd
Definition: chan_dahdi.h:227
#define ast_log
Definition: astobj2.c:42
static int reset_conf(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4569
struct ast_channel * owner
Definition: chan_dahdi.h:79
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
unsigned int faxhandled
TRUE if a fax tone has already been handled.
Definition: chan_dahdi.h:250
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
static int dahdi_setlinear(int dfd, int linear)
Definition: chan_dahdi.c:4161
int channel
Definition: chan_dahdi.h:538

◆ my_allocate_sub()

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

Definition at line 2386 of file chan_dahdi.c.

References alloc_sub(), analogsub_to_dahdisub(), and has_voicemail().

2387 {
2388  struct dahdi_pvt *p = pvt;
2389 
2390  return alloc_sub(p, analogsub_to_dahdisub(analogsub));
2391 }
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
static int alloc_sub(struct dahdi_pvt *p, int x)
Definition: chan_dahdi.c:4167

◆ my_answer_polarityswitch()

static void my_answer_polarityswitch ( void *  pvt)
static

Definition at line 2621 of file chan_dahdi.c.

References dahdi_pvt::answeronpolarityswitch, and my_set_polarity().

2622 {
2623  struct dahdi_pvt *p = pvt;
2624 
2625  if (!p->answeronpolarityswitch) {
2626  return;
2627  }
2628 
2629  my_set_polarity(pvt, 1);
2630 }
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:183
static void my_set_polarity(void *pvt, int value)
Definition: chan_dahdi.c:2601

◆ my_callwait()

static int my_callwait ( void *  pvt)
static

Definition at line 1513 of file chan_dahdi.c.

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

1514 {
1515  struct dahdi_pvt *p = pvt;
1516 
1518  if (p->cidspill) {
1519  ast_log(LOG_WARNING, "Spill already exists?!?\n");
1520  ast_free(p->cidspill);
1521  }
1522 
1523  /*
1524  * SAS: Subscriber Alert Signal, 440Hz for 300ms
1525  * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
1526  */
1527  if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
1528  return -1;
1529  save_conference(p);
1530  /* Silence */
1531  memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
1532  if (!p->callwaitrings && p->callwaitingcallerid) {
1533  ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
1534  p->callwaitcas = 1;
1535  p->cidlen = 2400 + 680 + READ_SIZE * 4;
1536  } else {
1537  ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
1538  p->callwaitcas = 0;
1539  p->cidlen = 2400 + READ_SIZE * 4;
1540  }
1541  p->cidpos = 0;
1542  send_callerid(p);
1543 
1544  return 0;
1545 }
int cidpos
Position in the cidspill buffer to send out next.
Definition: chan_dahdi.h:552
int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: chan_dahdi.h:575
int callwaitrings
Number of call waiting rings.
Definition: chan_dahdi.h:577
unsigned int callwaitingcallerid
TRUE if send caller ID for Call Waiting.
Definition: chan_dahdi.h:207
#define LOG_WARNING
Definition: logger.h:274
int callwaitingrepeat
Definition: chan_dahdi.h:546
#define ast_log
Definition: astobj2.c:42
int cidlen
Length of the cidspill buffer containing samples.
Definition: chan_dahdi.h:554
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
#define AST_LAW(p)
Definition: chan_dahdi.c:521
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define READ_SIZE
Definition: chan_dahdi.c:673
#define ast_free(a)
Definition: astmm.h:182
static int send_callerid(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5051
#define CALLWAITING_REPEAT_SAMPLES
Definition: chan_dahdi.c:679
static int save_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4976
int ast_gen_cas(unsigned char *outbuf, int sas, int len, struct ast_format *codec)
Generate a CAS (CPE Alert Signal) tone for &#39;n&#39; samples.
Definition: callerid.c:261

◆ my_cancel_cidspill()

static void my_cancel_cidspill ( void *  pvt)
static

Definition at line 2016 of file chan_dahdi.c.

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

2017 {
2018  struct dahdi_pvt *p = pvt;
2019 
2020  ast_free(p->cidspill);
2021  p->cidspill = NULL;
2022  restore_conference(p);
2023 }
#define NULL
Definition: resample.c:96
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
static int restore_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5002
#define ast_free(a)
Definition: astmm.h:182

◆ my_check_confirmanswer()

static int my_check_confirmanswer ( void *  pvt)
static

Definition at line 1999 of file chan_dahdi.c.

References dahdi_pvt::confirmanswer.

2000 {
2001  struct dahdi_pvt *p = pvt;
2002  if (p->confirmanswer) {
2003  return 1;
2004  }
2005 
2006  return 0;
2007 }
unsigned int confirmanswer
TRUE if to wait for a DTMF digit to confirm answer.
Definition: chan_dahdi.h:221

◆ my_check_for_conference()

static int my_check_for_conference ( void *  pvt)
static

Definition at line 2176 of file chan_dahdi.c.

References check_for_conference().

2177 {
2178  struct dahdi_pvt *p = pvt;
2179  return check_for_conference(p);
2180 }
static int check_for_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7178

◆ my_check_waitingfordt()

static int my_check_waitingfordt ( void *  pvt)
static

Definition at line 1982 of file chan_dahdi.c.

References dahdi_pvt::waitingfordt.

1983 {
1984  struct dahdi_pvt *p = pvt;
1985 
1986  if (p->waitingfordt.tv_sec) {
1987  return 1;
1988  }
1989 
1990  return 0;
1991 }
struct timeval waitingfordt
Definition: chan_dahdi.h:636

◆ my_complete_conference_update()

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

Definition at line 2126 of file chan_dahdi.c.

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

2127 {
2128  struct dahdi_pvt *p = pvt;
2129  int needconf = needconference;
2130  int x;
2131  int useslavenative;
2132  struct dahdi_pvt *slave = NULL;
2133 
2134  useslavenative = isslavenative(p, &slave);
2135 
2136  /* If we have a slave, add him to our conference now. or DAX
2137  if this is slave native */
2138  for (x = 0; x < MAX_SLAVES; x++) {
2139  if (p->slaves[x]) {
2140  if (useslavenative)
2141  conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
2142  else {
2143  conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
2144  needconf++;
2145  }
2146  }
2147  }
2148  /* If we're supposed to be in there, do so now */
2149  if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
2150  if (useslavenative)
2151  conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
2152  else {
2153  conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
2154  needconf++;
2155  }
2156  }
2157  /* If we have a master, add ourselves to his conference */
2158  if (p->master) {
2159  if (isslavenative(p->master, NULL)) {
2161  } else {
2162  conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
2163  }
2164  }
2165  if (!needconf) {
2166  /* Nobody is left (or should be left) in our conference.
2167  Kill it. */
2168  p->confno = -1;
2169  }
2170 
2171  return 0;
2172 }
#define MAX_SLAVES
Definition: chan_dahdi.h:95
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct dahdi_pvt * master
Definition: chan_dahdi.h:135
static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel)
Definition: chan_dahdi.c:4457
#define NULL
Definition: resample.c:96
int inconference
Definition: chan_dahdi.h:136
struct dahdi_pvt * slaves[MAX_SLAVES]
Definition: chan_dahdi.h:134
#define GET_CHANNEL(p)
Definition: chan_dahdi.c:1053
unsigned int inthreeway
Definition: chan_dahdi.h:91
#define SUB_REAL
Definition: chan_dahdi.h:57
int confno
Definition: chan_dahdi.h:510
static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out)
Definition: chan_dahdi.c:4525

◆ my_conf_add()

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

Definition at line 2116 of file chan_dahdi.c.

References analogsub_to_dahdisub(), conf_add(), isslavenative(), out, and dahdi_pvt::subs.

2117 {
2118  struct dahdi_pvt *p = pvt;
2119  int x = analogsub_to_dahdisub(sub);
2120 
2121  return conf_add(p, &p->subs[x], x, 0);
2122 }
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel)
Definition: chan_dahdi.c:4457
struct stasis_forward * sub
Definition: res_corosync.c:240

◆ my_conf_del()

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

Definition at line 2106 of file chan_dahdi.c.

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

2107 {
2108  struct dahdi_pvt *p = pvt;
2109  int x = analogsub_to_dahdisub(sub);
2110 
2111  return conf_del(p, &p->subs[x], x);
2112 }
static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index)
Definition: chan_dahdi.c:4506
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct stasis_forward * sub
Definition: res_corosync.c:240

◆ my_confmute()

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

Definition at line 2025 of file chan_dahdi.c.

References dahdi_confmute().

2026 {
2027  struct dahdi_pvt *p = pvt;
2028  return dahdi_confmute(p, mute);
2029 }
static int dahdi_confmute(struct dahdi_pvt *p, int muted)
Definition: chan_dahdi.c:4939
static int mute
Definition: chan_alsa.c:144

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

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

Referenced by dahdi_write().

8873 {
8874  int sent=0;
8875  int size;
8876  int res;
8877  int fd;
8878  fd = p->subs[idx].dfd;
8879  while (len) {
8880  size = len;
8881  if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
8882  size = (linear ? READ_SIZE * 2 : READ_SIZE);
8883  res = write(fd, buf, size);
8884  if (res != size) {
8885  ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
8886  return sent;
8887  }
8888  len -= size;
8889  buf += size;
8890  }
8891  return sent;
8892 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
#define READ_SIZE
Definition: chan_dahdi.c:673
int channel
Definition: chan_dahdi.h:538

◆ my_deadlock_avoidance_private()

static void my_deadlock_avoidance_private ( void *  pvt)
static

Definition at line 1734 of file chan_dahdi.c.

References DEADLOCK_AVOIDANCE, and dahdi_pvt::lock.

Referenced by my_on_hook().

1735 {
1736  struct dahdi_pvt *p = pvt;
1737 
1738  DEADLOCK_AVOIDANCE(&p->lock);
1739 }
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:374
ast_mutex_t lock
Definition: chan_dahdi.h:125

◆ my_decrease_ss_count()

static void my_decrease_ss_count ( void  )
static

Definition at line 2058 of file chan_dahdi.c.

References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, ss_thread_complete, ss_thread_count, and ss_thread_lock.

2059 {
2061  ss_thread_count--;
2064 }
static ast_mutex_t ss_thread_lock
Definition: chan_dahdi.c:642
static ast_cond_t ss_thread_complete
Definition: chan_dahdi.c:641
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_cond_signal(cond)
Definition: lock.h:201
static int ss_thread_count
Definition: chan_dahdi.c:644
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ my_dial_digits()

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

Definition at line 2655 of file chan_dahdi.c.

References ANALOG_DIAL_OP_REPLACE, ANALOG_SUB_REAL, ast_log, dahdi_pvt::channel, dahdi_dial_str(), dahdi_train_ec(), analog_dialoperation::dialstr, LOG_ERROR, and analog_dialoperation::op.

2656 {
2657  struct dahdi_pvt *p = pvt;
2658 
2659  if (dop->op != ANALOG_DIAL_OP_REPLACE) {
2660  ast_log(LOG_ERROR, "Fix the dial_digits callback!\n");
2661  return -1;
2662  }
2663 
2664  if (sub != ANALOG_SUB_REAL) {
2665  ast_log(LOG_ERROR, "Trying to dial_digits '%s' on channel %d subchannel %u\n",
2666  dop->dialstr, p->channel, sub);
2667  return -1;
2668  }
2669 
2670  return dahdi_dial_str(p, DAHDI_DIAL_OP_REPLACE, dop->dialstr);
2671 }
static int dahdi_dial_str(struct dahdi_pvt *pvt, int operation, const char *dial_str)
Definition: chan_dahdi.c:1223
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
struct stasis_forward * sub
Definition: res_corosync.c:240
int channel
Definition: chan_dahdi.h:538

◆ my_distinctive_ring()

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

Definition at line 1375 of file chan_dahdi.c.

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.

1376 {
1377  unsigned char buf[256];
1378  int distMatches;
1379  int curRingData[RING_PATTERNS];
1380  int receivedRingT;
1381  int counter1;
1382  int counter;
1383  int i;
1384  int res;
1385  int checkaftercid = 0;
1386  const char *matched_context;
1387  struct dahdi_pvt *p = pvt;
1388  struct analog_pvt *analog_p = p->sig_pvt;
1389 
1390  if (ringdata == NULL) {
1391  ringdata = curRingData;
1392  } else {
1393  checkaftercid = 1;
1394  }
1395 
1396  /* We must have a ring by now so lets try to listen for distinctive ringing */
1397  if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) {
1398  /* Clear the current ring data array so we don't have old data in it. */
1399  for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++)
1400  ringdata[receivedRingT] = 0;
1401  receivedRingT = 0;
1402 
1403  if (checkaftercid && distinctiveringaftercid) {
1404  ast_verb(3, "Detecting post-CID distinctive ring\n");
1405  }
1406 
1407  for (;;) {
1408  i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
1409  res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i);
1410  if (res) {
1411  ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
1412  ast_hangup(chan);
1413  return 1;
1414  }
1415  if (i & DAHDI_IOMUX_SIGEVENT) {
1416  res = dahdi_get_event(p->subs[idx].dfd);
1417  ast_debug(3, "Got event %d (%s)...\n", res, event2str(res));
1418  if (res == DAHDI_EVENT_NOALARM) {
1419  p->inalarm = 0;
1420  analog_p->inalarm = 0;
1421  } else if (res == DAHDI_EVENT_RINGOFFHOOK) {
1422  /* Let us detect distinctive ring */
1423  ringdata[receivedRingT] = analog_p->ringt;
1424 
1425  if (analog_p->ringt < analog_p->ringt_base / 2) {
1426  break;
1427  }
1428  /* Increment the ringT counter so we can match it against
1429  values in chan_dahdi.conf for distinctive ring */
1430  if (++receivedRingT == RING_PATTERNS) {
1431  break;
1432  }
1433  }
1434  } else if (i & DAHDI_IOMUX_READ) {
1435  res = read(p->subs[idx].dfd, buf, sizeof(buf));
1436  if (res < 0) {
1437  if (errno != ELAST) {
1438  ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1439  ast_hangup(chan);
1440  return 1;
1441  }
1442  break;
1443  }
1444  if (analog_p->ringt > 0) {
1445  if (!(--analog_p->ringt)) {
1446  break;
1447  }
1448  }
1449  }
1450  }
1451  }
1452 
1453  /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */
1454  ast_verb(3, "Detected ring pattern: %d,%d,%d\n", ringdata[0], ringdata[1], ringdata[2]);
1455  matched_context = p->defcontext;
1456  for (counter = 0; counter < 3; counter++) {
1457  int range = p->drings.ringnum[counter].range;
1458 
1459  distMatches = 0;
1460  ast_verb(3, "Checking %d,%d,%d with +/- %d range\n",
1461  p->drings.ringnum[counter].ring[0],
1462  p->drings.ringnum[counter].ring[1],
1463  p->drings.ringnum[counter].ring[2],
1464  range);
1465  for (counter1 = 0; counter1 < 3; counter1++) {
1466  int ring = p->drings.ringnum[counter].ring[counter1];
1467 
1468  if (ring == -1) {
1469  ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
1470  ringdata[counter1]);
1471  distMatches++;
1472  } else if (ring - range <= ringdata[counter1] && ringdata[counter1] <= ring + range) {
1473  ast_verb(3, "Ring pattern %d is in range: %d to %d\n",
1474  ringdata[counter1], ring - range, ring + range);
1475  distMatches++;
1476  } else {
1477  /* The current dring pattern cannot match. */
1478  break;
1479  }
1480  }
1481 
1482  if (distMatches == 3) {
1483  /* The ring matches, set the context to whatever is for distinctive ring.. */
1484  matched_context = S_OR(p->drings.ringContext[counter].contextData, p->defcontext);
1485  ast_verb(3, "Matched Distinctive Ring context %s\n", matched_context);
1486  break;
1487  }
1488  }
1489 
1490  /* Set selected distinctive ring context if not already set. */
1491  if (strcmp(p->context, matched_context) != 0) {
1492  ast_copy_string(p->context, matched_context, sizeof(p->context));
1493  ast_channel_context_set(chan, matched_context);
1494  }
1495 
1496  return 0;
1497 }
char defcontext[AST_MAX_CONTEXT]
Default distinctive ring context.
Definition: chan_dahdi.h:453
struct ringContextData ringContext[3]
Definition: chan_dahdi.h:71
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ringt_base
Definition: sig_analog.h:357
#define LOG_WARNING
Definition: logger.h:274
void * sig_pvt
Definition: chan_dahdi.h:709
#define RING_PATTERNS
Definition: sig_analog.h:35
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
char contextData[AST_MAX_CONTEXT]
Definition: chan_dahdi.h:67
int ring[3]
Definition: chan_dahdi.h:63
int errno
static int dahdi_get_event(int fd)
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition: chan_dahdi.c:652
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
char context[AST_MAX_CONTEXT]
The configured context for incoming calls.
Definition: chan_dahdi.h:444
static const char * event2str(int event)
Definition: chan_dahdi.c:4382
static int distinctiveringaftercid
Definition: chan_dahdi.c:608
void ast_channel_context_set(struct ast_channel *chan, const char *value)
struct dahdi_distRings drings
Distinctive Ring data.
Definition: chan_dahdi.h:438
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
unsigned int inalarm
Definition: sig_analog.h:325
unsigned int inalarm
TRUE if in an alarm condition.
Definition: chan_dahdi.h:286
struct distRingData ringnum[3]
Definition: chan_dahdi.h:70

◆ my_dsp_reset_and_flush_digits()

static int my_dsp_reset_and_flush_digits ( void *  pvt)
static

Definition at line 1582 of file chan_dahdi.c.

References ast_dsp_digitreset(), and dahdi_pvt::dsp.

Referenced by my_on_hook().

1583 {
1584  struct dahdi_pvt *p = pvt;
1585  if (p->dsp)
1586  ast_dsp_digitreset(p->dsp);
1587 
1588  return 0;
1589 }
void ast_dsp_digitreset(struct ast_dsp *dsp)
Reset DTMF detector.
Definition: dsp.c:1797
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639

◆ my_dsp_set_digitmode()

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

Definition at line 1591 of file chan_dahdi.c.

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

1592 {
1593  struct dahdi_pvt *p = pvt;
1594 
1595  if (p->channel == CHAN_PSEUDO)
1596  ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n");
1597 
1598  if (mode == ANALOG_DIGITMODE_DTMF) {
1599  /* If we do hardware dtmf, no need for a DSP */
1600  if (p->hardwaredtmf) {
1601  if (p->dsp) {
1602  ast_dsp_free(p->dsp);
1603  p->dsp = NULL;
1604  }
1605  return 0;
1606  }
1607 
1608  if (!p->dsp) {
1609  p->dsp = ast_dsp_new();
1610  if (!p->dsp) {
1611  ast_log(LOG_ERROR, "Unable to allocate DSP\n");
1612  return -1;
1613  }
1614  }
1615 
1617  } else if (mode == ANALOG_DIGITMODE_MF) {
1618  if (!p->dsp) {
1619  p->dsp = ast_dsp_new();
1620  if (!p->dsp) {
1621  ast_log(LOG_ERROR, "Unable to allocate DSP\n");
1622  return -1;
1623  }
1624  }
1626  }
1627  return 0;
1628 }
int dtmfrelax
Definition: chan_dahdi.h:665
unsigned int hardwaredtmf
TRUE if DTMF detection needs to be done by hardware.
Definition: chan_dahdi.h:263
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
#define DSP_DIGITMODE_MF
Definition: dsp.h:32
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
#define CHAN_PSEUDO
Definition: chan_dahdi.c:556
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
#define LOG_ERROR
Definition: logger.h:285
int channel
Definition: chan_dahdi.h:538
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1844

◆ my_flash()

static int my_flash ( void *  pvt)
static

Definition at line 2580 of file chan_dahdi.c.

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

2581 {
2582  struct dahdi_pvt *p = pvt;
2583  int func = DAHDI_FLASH;
2584  return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func);
2585 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define SUB_REAL
Definition: chan_dahdi.h:57

◆ my_get_and_handle_alarms()

static void my_get_and_handle_alarms ( void *  pvt)
static

Definition at line 1862 of file chan_dahdi.c.

References get_alarms(), and handle_alarms().

1863 {
1864  int res;
1865  struct dahdi_pvt *p = pvt;
1866 
1867  res = get_alarms(p);
1868  handle_alarms(p, res);
1869 }
static void handle_alarms(struct dahdi_pvt *p, int alms)
Definition: chan_dahdi.c:7364
static int get_alarms(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7204

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

References ANALOG_EVENT_NONE, ANALOG_MAX_CID, ast_copy_string(), ast_debug, AST_LAW, ast_log, buf, callerid_feed(), callerid_feed_jp(), callerid_get(), CID_SIG_V23_JP, dahdi_pvt::cid_signalling, dahdi_pvt::cs, dahdi_get_event(), dahdievent_to_analogevent(), dahdi_subchannel::dfd, errno, event2str(), LOG_WARNING, name, analog_pvt::ringt, dahdi_pvt::sig_pvt, SUB_REAL, and dahdi_pvt::subs.

1303 {
1304  struct dahdi_pvt *p = pvt;
1305  struct analog_pvt *analog_p = p->sig_pvt;
1306  struct pollfd poller;
1307  char *name, *num;
1308  int index = SUB_REAL;
1309  int res;
1310  unsigned char buf[256];
1311  int flags;
1312 
1313  poller.fd = p->subs[SUB_REAL].dfd;
1314  poller.events = POLLPRI | POLLIN;
1315  poller.revents = 0;
1316 
1317  res = poll(&poller, 1, timeout);
1318 
1319  if (poller.revents & POLLPRI) {
1321  return 1;
1322  }
1323 
1324  if (poller.revents & POLLIN) {
1325  /*** NOTES ***/
1326  /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function
1327  * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until
1328  * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be
1329  * a failure and die, and returning 2 means no event was received. */
1330  res = read(p->subs[index].dfd, buf, sizeof(buf));
1331  if (res < 0) {
1332  ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1333  return -1;
1334  }
1335 
1336  if (analog_p->ringt > 0) {
1337  if (!(--analog_p->ringt)) {
1338  /* only return if we timeout from a ring event */
1339  return -1;
1340  }
1341  }
1342 
1343  if (p->cid_signalling == CID_SIG_V23_JP) {
1344  res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p));
1345  } else {
1346  res = callerid_feed(p->cs, buf, res, AST_LAW(p));
1347  }
1348  if (res < 0) {
1349  /*
1350  * The previous diagnostic message output likely
1351  * explains why it failed.
1352  */
1353  ast_log(LOG_WARNING, "Failed to decode CallerID\n");
1354  return -1;
1355  }
1356 
1357  if (res == 1) {
1358  callerid_get(p->cs, &name, &num, &flags);
1359  if (name)
1360  ast_copy_string(namebuf, name, ANALOG_MAX_CID);
1361  if (num)
1362  ast_copy_string(numbuf, num, ANALOG_MAX_CID);
1363 
1364  ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags);
1365  return 0;
1366  }
1367  }
1368 
1369  *ev = ANALOG_EVENT_NONE;
1370  return 2;
1371 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static enum analog_event dahdievent_to_analogevent(int event)
Definition: chan_dahdi.c:2412
int cid_signalling
Definition: chan_dahdi.h:541
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
char * name
Definition: chan_dahdi.c:4361
static int timeout
Definition: cdr_mysql.c:86
void * sig_pvt
Definition: chan_dahdi.h:709
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:188
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:306
#define ANALOG_MAX_CID
Definition: sig_analog.h:33
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define AST_LAW(p)
Definition: chan_dahdi.c:521
#define CID_SIG_V23_JP
Definition: callerid.h:62
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
static int dahdi_get_event(int fd)
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition: chan_dahdi.c:652
struct callerid_state * cs
Definition: chan_dahdi.h:126
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
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:545

◆ my_get_event()

static int my_get_event ( void *  pvt)
static

Definition at line 2516 of file chan_dahdi.c.

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

2517 {
2518  struct dahdi_pvt *p = pvt;
2519  int res;
2520 
2521  if (p->fake_event) {
2522  res = p->fake_event;
2523  p->fake_event = 0;
2524  } else
2525  res = dahdi_get_event(p->subs[SUB_REAL].dfd);
2526 
2527  return dahdievent_to_analogevent(res);
2528 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static enum analog_event dahdievent_to_analogevent(int event)
Definition: chan_dahdi.c:2412
#define SUB_REAL
Definition: chan_dahdi.h:57
static int dahdi_get_event(int fd)
Avoid the silly dahdi_getevent which ignores a bunch of events.
Definition: chan_dahdi.c:652
int fake_event
Holding place for event injected from outside normal operation.
Definition: chan_dahdi.h:667

◆ my_get_orig_dialstring()

static const char* my_get_orig_dialstring ( void *  pvt)
static

Definition at line 2044 of file chan_dahdi.c.

References dahdi_pvt::dialstring.

Referenced by my_on_hook().

2045 {
2046  struct dahdi_pvt *p = pvt;
2047 
2048  return p->dialstring;
2049 }
char dialstring[AST_CHANNEL_NAME]
Definition: chan_dahdi.h:717

◆ my_get_sigpvt_bridged_channel()

static void* my_get_sigpvt_bridged_channel ( struct ast_channel chan)
static

Definition at line 1871 of file chan_dahdi.c.

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

1872 {
1874 
1875  if (bridged && ast_channel_tech(bridged) == &dahdi_tech) {
1876  struct dahdi_pvt *p = ast_channel_tech_pvt(bridged);
1877 
1878  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
1879  return p->sig_pvt;
1880  }
1881  }
1882  return NULL;
1883 }
Main Channel structure associated with a channel.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
Definition: chan_dahdi.h:786
static struct ast_channel_tech dahdi_tech
Definition: chan_dahdi.c:1030
void * sig_pvt
Definition: chan_dahdi.h:709
#define NULL
Definition: resample.c:96
int oprmode
Definition: chan_dahdi.h:150
#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:911
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: channel.c:10765
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)

◆ my_get_sub_fd()

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

Definition at line 1885 of file chan_dahdi.c.

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

1886 {
1887  struct dahdi_pvt *p = pvt;
1888  int dahdi_sub = analogsub_to_dahdisub(sub);
1889  return p->subs[dahdi_sub].dfd;
1890 }
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct stasis_forward * sub
Definition: res_corosync.c:240

◆ my_getsigstr()

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

Definition at line 9400 of file chan_dahdi.c.

References ast_waitfordigit(), and c.

Referenced by analog_ss_thread().

9401 {
9402  char c;
9403 
9404  *str = 0; /* start with empty output buffer */
9405  for (;;)
9406  {
9407  /* Wait for the first digit (up to specified ms). */
9408  c = ast_waitfordigit(chan, ms);
9409  /* if timeout, hangup or error, return as such */
9410  if (c < 1)
9411  return c;
9412  *str++ = c;
9413  *str = 0;
9414  if (strchr(term, c))
9415  return 1;
9416  }
9417 }
static struct test_val c
const char * str
Definition: app_jack.c:147
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3184

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

References analogsub_to_dahdisub(), ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_lock, ast_channel_macrocontext(), 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, DSP_FEATURE_FAX_DETECT, 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, S_OR, ast_frame::subclass, dahdi_pvt::subs, and dahdi_pvt::usefaxbuffers.

1649 {
1650  struct ast_frame *f = *dest;
1651  struct dahdi_pvt *p = pvt;
1652  int idx = analogsub_to_dahdisub(analog_index);
1653 
1654  ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
1655  f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
1656  (unsigned)f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
1657 
1658  if (f->subclass.integer == 'f') {
1659  if (f->frametype == AST_FRAME_DTMF_END) {
1660  /* Fax tone -- Handle and return NULL */
1661  if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
1662  /* If faxbuffers are configured, use them for the fax transmission */
1663  if (p->usefaxbuffers && !p->bufferoverrideinuse) {
1664  struct dahdi_bufferinfo bi = {
1665  .txbufpolicy = p->faxbuf_policy,
1666  .bufsize = p->bufsize,
1667  .numbufs = p->faxbuf_no
1668  };
1669  int res;
1670 
1671  if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
1672  ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno));
1673  } else {
1674  p->bufferoverrideinuse = 1;
1675  }
1676  }
1677  p->faxhandled = 1;
1678  if (p->dsp) {
1681  ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
1682  }
1683  if (strcmp(ast_channel_exten(ast), "fax")) {
1684  const char *target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
1685 
1686  /*
1687  * We need to unlock 'ast' here because ast_exists_extension has the
1688  * potential to start autoservice on the channel. Such action is prone
1689  * to deadlock if the channel is locked.
1690  *
1691  * ast_async_goto() has its own restriction on not holding the
1692  * channel lock.
1693  */
1694  ast_mutex_unlock(&p->lock);
1695  ast_channel_unlock(ast);
1696  if (ast_exists_extension(ast, target_context, "fax", 1,
1697  S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, NULL))) {
1698  ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast));
1699  /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
1700  pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
1701  if (ast_async_goto(ast, target_context, "fax", 1))
1702  ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
1703  } else {
1704  ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
1705  }
1706  ast_channel_lock(ast);
1707  ast_mutex_lock(&p->lock);
1708  } else {
1709  ast_debug(1, "Already in a fax extension, not redirecting\n");
1710  }
1711  } else {
1712  ast_debug(1, "Fax already handled\n");
1713  }
1714  dahdi_confmute(p, 0);
1715  }
1716  p->subs[idx].f.frametype = AST_FRAME_NULL;
1717  p->subs[idx].f.subclass.integer = 0;
1718  *dest = &p->subs[idx].f;
1719  }
1720 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int faxbuf_no
Definition: chan_dahdi.h:141
#define ast_channel_lock(chan)
Definition: channel.h:2945
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static int dahdi_confmute(struct dahdi_pvt *p, int muted)
Definition: chan_dahdi.c:4939
#define LOG_WARNING
Definition: logger.h:274
int dsp_features
DSP feature flags: DSP_FEATURE_xxx.
Definition: chan_dahdi.h:683
unsigned int usefaxbuffers
Definition: chan_dahdi.h:252
int bufsize
Definition: chan_dahdi.h:138
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
struct ast_frame f
Definition: chan_dahdi.h:82
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_frame_subclass subclass
Number structure.
Definition: app_followme.c:154
unsigned int bufferoverrideinuse
Definition: chan_dahdi.h:254
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
ast_mutex_t lock
Definition: chan_dahdi.h:125
#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:85
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
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:4179
const char * ast_channel_exten(const struct ast_channel *chan)
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
unsigned int faxhandled
TRUE if a fax tone has already been handled.
Definition: chan_dahdi.h:250
int errno
#define LOG_NOTICE
Definition: logger.h:263
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
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...
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
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:7011
Data structure associated with a single frame of data.
int faxbuf_policy
Definition: chan_dahdi.h:142
const char * ast_channel_context(const struct ast_channel *chan)
enum ast_frame_type frametype
const char * ast_channel_macrocontext(const struct ast_channel *chan)
int callprogress
Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
Definition: chan_dahdi.h:604
#define CALLPROGRESS_FAX
Definition: chan_dahdi.c:561
#define ast_mutex_unlock(a)
Definition: lock.h:188

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

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

Referenced by analog_ss_thread().

3308 {
3309  struct dahdi_pvt *p = pvt;
3310 
3311  if (neon_mwievent > -1 && !p->mwimonitor_neon)
3312  return;
3313 
3314  if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) {
3315  ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox);
3316  notify_message(p->mailbox, 1);
3317  } else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) {
3318  ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox);
3319  notify_message(p->mailbox, 0);
3320  }
3321  /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
3322  /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
3323  if (neon_mwievent == -1 && p->mwimonitor_rpas) {
3324  ast_hangup(chan);
3325  return;
3326  }
3327 }
#define CID_MSGWAITING
Definition: callerid.h:56
#define ast_log
Definition: astobj2.c:42
char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Voice mailbox location.
Definition: chan_dahdi.h:654
#define CID_NOMSGWAITING
Definition: callerid.h:57
static void notify_message(char *mailbox, int thereornot)
Send MWI state change.
Definition: chan_dahdi.c:3292
#define LOG_NOTICE
Definition: logger.h:263
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
unsigned int mwimonitor_neon
TRUE if the FXO port monitors for neon type MWI indications from the other end.
Definition: chan_dahdi.h:375
int channel
Definition: chan_dahdi.h:538
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:386

◆ my_hangup_polarityswitch()

static void my_hangup_polarityswitch ( void *  pvt)
static

Definition at line 2632 of file chan_dahdi.c.

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

2633 {
2634  struct dahdi_pvt *p = pvt;
2635 
2636  if (!p->hanguponpolarityswitch) {
2637  return;
2638  }
2639 
2640  if (p->answeronpolarityswitch) {
2641  my_set_polarity(pvt, 0);
2642  } else {
2643  my_set_polarity(pvt, 1);
2644  }
2645 }
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:183
unsigned int hanguponpolarityswitch
TRUE if the call will be considered "hung up" on a polarity reversal.
Definition: chan_dahdi.h:261
static void my_set_polarity(void *pvt, int value)
Definition: chan_dahdi.c:2601

◆ my_has_voicemail()

static int my_has_voicemail ( void *  pvt)
static

Definition at line 2395 of file chan_dahdi.c.

References has_voicemail().

2396 {
2397  struct dahdi_pvt *p = pvt;
2398 
2399  return has_voicemail(p);
2400 }
static int has_voicemail(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5033

◆ my_have_progressdetect()

static int my_have_progressdetect ( void *  pvt)
static

Definition at line 3329 of file chan_dahdi.c.

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

3330 {
3331  struct dahdi_pvt *p = pvt;
3332 
3334  && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
3335  return 1;
3336  } else {
3337  /* Don't have progress detection. */
3338  return 0;
3339  }
3340 }
unsigned int outgoing
TRUE if we originated the call leg.
Definition: chan_dahdi.h:290
#define CALLPROGRESS_PROGRESS
Definition: chan_dahdi.c:558
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
int callprogress
Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
Definition: chan_dahdi.h:604
#define CANPROGRESSDETECT(p)
Definition: chan_dahdi.c:594

◆ my_increase_ss_count()

static void my_increase_ss_count ( void  )
static

Definition at line 2051 of file chan_dahdi.c.

References ast_mutex_lock, ast_mutex_unlock, ss_thread_count, and ss_thread_lock.

2052 {
2054  ss_thread_count++;
2056 }
static ast_mutex_t ss_thread_lock
Definition: chan_dahdi.c:642
#define ast_mutex_lock(a)
Definition: lock.h:187
static int ss_thread_count
Definition: chan_dahdi.c:644
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ my_is_dialing()

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

Definition at line 2684 of file chan_dahdi.c.

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

2685 {
2686  struct dahdi_pvt *p = pvt;
2687  int index;
2688  int x;
2689 
2690  index = analogsub_to_dahdisub(sub);
2691 
2692  if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) {
2693  ast_debug(1, "DAHDI_DIALING ioctl failed!\n");
2694  return -1;
2695  }
2696 
2697  return x;
2698 }
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct stasis_forward * sub
Definition: res_corosync.c:240

◆ my_is_off_hook()

static int my_is_off_hook ( void *  pvt)
static

Definition at line 2530 of file chan_dahdi.c.

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

2531 {
2532  struct dahdi_pvt *p = pvt;
2533  int res;
2534  struct dahdi_params par;
2535 
2536  memset(&par, 0, sizeof(par));
2537 
2538  if (p->subs[SUB_REAL].dfd > -1)
2539  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
2540  else {
2541  /* Assume not off hook on CVRS */
2542  res = 0;
2543  par.rxisoffhook = 0;
2544  }
2545  if (res) {
2546  ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno));
2547  }
2548 
2549  if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
2550  /* When "onhook" that means no battery on the line, and thus
2551  it is out of service..., if it's on a TDM card... If it's a channel
2552  bank, there is no telling... */
2553  return (par.rxbits > -1) || par.rxisoffhook;
2554  }
2555 
2556  return par.rxisoffhook;
2557 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SIG_FXSGS
Definition: chan_dahdi.h:732
#define SIG_FXSKS
Definition: chan_dahdi.h:733
int channel
Definition: chan_dahdi.h:538

◆ my_lock_private()

static void my_lock_private ( void *  pvt)
static

Definition at line 1722 of file chan_dahdi.c.

References ast_mutex_lock, and dahdi_pvt::lock.

Referenced by my_on_hook().

1723 {
1724  struct dahdi_pvt *p = pvt;
1725  ast_mutex_lock(&p->lock);
1726 }
#define ast_mutex_lock(a)
Definition: lock.h:187
ast_mutex_t lock
Definition: chan_dahdi.h:125

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

References analogsub_to_dahdisub(), ast_callid_threadstorage_auto(), ast_copy_string(), ast_dsp_set_features(), ast_log, ast_channel::callid, dahdi_pvt::channel, dahdi_dial_str(), dahdi_new_callid_clean(), dahdi_subchannel::dfd, dahdi_pvt::dialing, dahdi_pvt::digital, dahdi_pvt::dsp, dahdi_pvt::dsp_features, errno, exten, dahdi_pvt::exten, dahdi_pvt::law, LOG_WARNING, NULL, dahdi_pvt::rxdrc, dahdi_pvt::rxgain, set_actual_gain(), dahdi_pvt::sig, SIG_PRI_ALAW, SIG_PRI_DEFLAW, SIG_PRI_LIB_HANDLE_CASES, SIG_PRI_ULAW, dahdi_pvt::sig_pvt, SUB_REAL, dahdi_pvt::subs, dahdi_pvt::txdrc, dahdi_pvt::txgain, and unalloc_sub().

2226 {
2227  ast_callid callid = 0;
2228  int callid_created = ast_callid_threadstorage_auto(&callid);
2229  struct dahdi_pvt *p = pvt;
2230  int dsub = analogsub_to_dahdisub(sub);
2231 
2232  return dahdi_new_callid_clean(p, state, startpbx, dsub, 0, NULL, requestor, callid, callid_created);
2233 }
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
unsigned int ast_callid
Definition: logger.h:87
#define NULL
Definition: resample.c:96
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:9144
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:2020
struct stasis_forward * sub
Definition: res_corosync.c:240

◆ my_off_hook()

static int my_off_hook ( void *  pvt)
static

Definition at line 2589 of file chan_dahdi.c.

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

2590 {
2591  struct dahdi_pvt *p = pvt;
2592  return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
2593 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define SUB_REAL
Definition: chan_dahdi.h:57
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922

◆ my_on_hook()

static int my_on_hook ( void *  pvt)
static

Definition at line 2700 of file chan_dahdi.c.

References ANALOG_SUB_REAL, ast_party_caller::ani, ast_party_caller::ani2, args, AST_APP_ARG, ast_callid_threadstorage_auto(), ast_channel_internal_fd_set(), ast_channel_tech_pvt_set(), ast_copy_string(), AST_DECLARE_APP_ARGS, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_changed(), AST_DEVSTATE_NOT_CACHABLE, ast_log, ast_module_ref, ast_module_unref, AST_NONSTANDARD_APP_ARGS, ast_party_id_presentation(), ast_strdupa, buf, dahdi_pvt::callingpres, dahdi_pvt::channel, dahdi_pvt::cid_ani2, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_subaddr, dahdi_pvt::cid_tag, dahdi_pvt::cid_ton, sig_pri_span::congestion_devstate, dahdi_new_callid_clean(), dahdi_set_hook(), dahdi_subchannel::dfd, dahdi_pvt::dialing, dahdi_pvt::dialstring, dahdi_pvt::digital, dahdi_pvt::dnid, dahdi_pvt::dsp, dahdi_pvt::dsp_features, errno, event2str(), exten, dahdi_pvt::exten, sig_ss7_linkset::fds, sig_pri_span::fds, sig_pri_callback::handle_dchan_exception, ast_party_caller::id, sig_pri_chan::inalarm, dahdi_pvt::law, sig_ss7_callback::lock_private, LOG_ERROR, LOG_NOTICE, LOG_WARNING, my_deadlock_avoidance_private(), my_dsp_reset_and_flush_digits(), my_get_orig_dialstring(), my_lock_private(), my_set_alarm(), my_set_dialing(), my_set_echocanceller(), my_set_outgoing(), my_unlock_private(), ast_party_id::name, sig_pri_chan::no_b_channel, NULL, NUM_SPANS, ast_party_id::number, sig_pri_span::numchans, dahdi_pvt::outgoing, dahdi_subchannel::owner, dahdi_pvt::owner, ast_party_number::plan, pri_event_alarm(), pri_event_noalarm(), sig_pri_span::pvts, dahdi_pvt::rdnis, S_COR, ast_module_info::self, sig_pri_is_alarm_ignored(), sig_pri_is_chan_available(), SIG_PRI_TONE_BUSY, SIG_PRI_TONE_CONGESTION, SIG_PRI_TONE_DIALRECALL, SIG_PRI_TONE_DIALTONE, SIG_PRI_TONE_INFO, SIG_PRI_TONE_RINGTONE, SIG_PRI_TONE_STUTTER, SIG_SS7_ALAW, SIG_SS7_DEFLAW, sig_ss7_link_alarm(), sig_ss7_link_noalarm(), SIG_SS7_TONE_BUSY, SIG_SS7_TONE_CONGESTION, SIG_SS7_TONE_DIALRECALL, SIG_SS7_TONE_DIALTONE, SIG_SS7_TONE_INFO, SIG_SS7_TONE_RINGTONE, SIG_SS7_TONE_STUTTER, SIG_SS7_ULAW, sig_ss7_linkset::span, sig_pri_span::span, ast_party_name::str, ast_party_number::str, ast_party_subaddress::str, SUB_REAL, ast_party_id::subaddress, dahdi_pvt::subs, ast_party_id::tag, ast_party_name::valid, ast_party_number::valid, and ast_party_subaddress::valid.

2701 {
2702  struct dahdi_pvt *p = pvt;
2703  return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK);
2704 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static int dahdi_set_hook(int fd, int hs)
Definition: chan_dahdi.c:4922

◆ my_play_tone()

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

Definition at line 2402 of file chan_dahdi.c.

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

2403 {
2404  struct dahdi_pvt *p = pvt;
2405  int index;
2406 
2407  index = analogsub_to_dahdisub(sub);
2408 
2409  return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone));
2410 }
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static int analog_tone_to_dahditone(enum analog_tone tone)
Definition: chan_dahdi.c:1106
struct stasis_forward * sub
Definition: res_corosync.c:240

◆ my_ring()

static int my_ring ( void *  pvt)
static

Definition at line 2573 of file chan_dahdi.c.

References dahdi_ring_phone().

2574 {
2575  struct dahdi_pvt *p = pvt;
2576 
2577  return dahdi_ring_phone(p);
2578 }
static int dahdi_ring_phone(struct dahdi_pvt *p)
Definition: chan_dahdi.c:7101

◆ my_send_callerid()

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

Definition at line 1547 of file chan_dahdi.c.

References ast_callerid_callwaiting_generate(), ast_callerid_generate(), ast_debug, ast_free, AST_LAW, ast_log, ast_malloc, ast_verb, dahdi_pvt::callwaitcas, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cidcwexpire, dahdi_pvt::cidlen, dahdi_pvt::cidpos, dahdi_pvt::cidspill, ast_party_caller::id, LOG_WARNING, MAX_CALLERID_SIZE, ast_party_id::name, ast_party_id::number, READ_SIZE, send_callerid(), ast_party_name::str, and ast_party_number::str.

1548 {
1549  struct dahdi_pvt *p = pvt;
1550 
1551  ast_debug(2, "Starting cid spill\n");
1552 
1553  if (p->cidspill) {
1554  ast_log(LOG_WARNING, "cidspill already exists??\n");
1555  ast_free(p->cidspill);
1556  }
1557 
1558  if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
1559  if (cwcid == 0) {
1561  caller->id.name.str,
1562  caller->id.number.str,
1563  AST_LAW(p));
1564  } else {
1565  ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n",
1566  caller->id.name.str, caller->id.number.str);
1567  p->callwaitcas = 0;
1568  p->cidcwexpire = 0;
1570  caller->id.name.str,
1571  caller->id.number.str,
1572  AST_LAW(p));
1573  p->cidlen += READ_SIZE * 4;
1574  }
1575  p->cidpos = 0;
1576  p->cid_suppress_expire = 0;
1577  send_callerid(p);
1578  }
1579  return 0;
1580 }
int cidpos
Position in the cidspill buffer to send out next.
Definition: chan_dahdi.h:552
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: chan_dahdi.h:575
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
#define LOG_WARNING
Definition: logger.h:274
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)&#39;s Caller*ID(tm) ...
Definition: callerid.c:1068
char * str
Subscriber name (Malloced)
Definition: channel.h:265
#define ast_verb(level,...)
Definition: logger.h:463
#define MAX_CALLERID_SIZE
Definition: callerid.h:50
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int cidlen
Length of the cidspill buffer containing samples.
Definition: chan_dahdi.h:554
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
#define AST_LAW(p)
Definition: chan_dahdi.c:521
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define READ_SIZE
Definition: chan_dahdi.c:673
#define ast_free(a)
Definition: astmm.h:182
static int send_callerid(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5051
int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format) ...
Definition: callerid.c:1063
int cidcwexpire
Definition: chan_dahdi.h:547
int cid_suppress_expire
Definition: chan_dahdi.h:548
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ my_set_alarm()

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

Definition at line 1908 of file chan_dahdi.c.

References dahdi_pvt::inalarm.

Referenced by my_on_hook().

1909 {
1910  struct dahdi_pvt *p = pvt;
1911 
1912  p->inalarm = in_alarm;
1913 }
unsigned int inalarm
TRUE if in an alarm condition.
Definition: chan_dahdi.h:286

◆ my_set_cadence()

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

Definition at line 1892 of file chan_dahdi.c.

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.

1893 {
1894  struct dahdi_pvt *p = pvt;
1895 
1896  /* Choose proper cadence */
1897  if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
1898  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
1899  ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast_channel_name(ast), strerror(errno));
1900  *cid_rings = cidrings[p->distinctivering - 1];
1901  } else {
1902  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
1903  ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast_channel_name(ast), strerror(errno));
1904  *cid_rings = p->sendcalleridafter;
1905  }
1906 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
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:580
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
int distinctivering
Definition: chan_dahdi.h:664
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX]
Definition: chan_dahdi.c:569
const char * ast_channel_name(const struct ast_channel *chan)
static int num_cadence
Definition: chan_dahdi.c:564
int sendcalleridafter
Send caller ID on FXS after this many rings. Set to 1 for US.
Definition: chan_dahdi.h:679

◆ my_set_callwaiting()

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

Definition at line 2009 of file chan_dahdi.c.

References dahdi_pvt::callwaiting.

2010 {
2011  struct dahdi_pvt *p = pvt;
2012 
2013  p->callwaiting = callwaiting_enable;
2014 }
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:202

◆ my_set_confirmanswer()

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

Definition at line 1993 of file chan_dahdi.c.

References dahdi_pvt::confirmanswer.

1994 {
1995  struct dahdi_pvt *p = pvt;
1996  p->confirmanswer = flag;
1997 }
long int flag
Definition: f2c.h:83
unsigned int confirmanswer
TRUE if to wait for a DTMF digit to confirm answer.
Definition: chan_dahdi.h:221

◆ my_set_dialing()

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

Definition at line 1915 of file chan_dahdi.c.

References dahdi_pvt::dialing.

Referenced by my_on_hook().

1916 {
1917  struct dahdi_pvt *p = pvt;
1918 
1919  p->dialing = is_dialing;
1920 }
unsigned int dialing
TRUE if in the process of dialing digits or sending something.
Definition: chan_dahdi.h:234

◆ my_set_echocanceller()

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

Definition at line 2559 of file chan_dahdi.c.

References dahdi_ec_disable(), dahdi_ec_enable(), and dahdi_ring_phone().

Referenced by my_on_hook().

2560 {
2561  struct dahdi_pvt *p = pvt;
2562 
2563  if (enable)
2564  dahdi_ec_enable(p);
2565  else
2566  dahdi_ec_disable(p);
2567 
2568  return 0;
2569 }
void dahdi_ec_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4638
void dahdi_ec_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4710

◆ my_set_inthreeway()

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

Definition at line 1852 of file chan_dahdi.c.

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

1853 {
1854  struct dahdi_pvt *p = pvt;
1855  int idx = analogsub_to_dahdisub(sub);
1856 
1857  p->subs[idx].inthreeway = inthreeway;
1858 }
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
unsigned int inthreeway
Definition: chan_dahdi.h:91
struct stasis_forward * sub
Definition: res_corosync.c:240

◆ my_set_linear_mode()

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

Definition at line 1840 of file chan_dahdi.c.

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

1841 {
1842  struct dahdi_pvt *p = pvt;
1843  int oldval;
1844  int idx = analogsub_to_dahdisub(sub);
1845 
1846  dahdi_setlinear(p->subs[idx].dfd, linear_mode);
1847  oldval = p->subs[idx].linear;
1848  p->subs[idx].linear = linear_mode ? 1 : 0;
1849  return oldval;
1850 }
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
unsigned int linear
Definition: chan_dahdi.h:90
static int dahdi_setlinear(int dfd, int linear)
Definition: chan_dahdi.c:4161
struct stasis_forward * sub
Definition: res_corosync.c:240

◆ my_set_needringing()

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

Definition at line 2595 of file chan_dahdi.c.

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

2596 {
2597  struct dahdi_pvt *p = pvt;
2599 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
int value
Definition: syslog.c:37
unsigned int needringing
Definition: chan_dahdi.h:83
#define SUB_REAL
Definition: chan_dahdi.h:57

◆ my_set_new_owner()

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

Definition at line 2037 of file chan_dahdi.c.

References dahdi_pvt::owner.

2038 {
2039  struct dahdi_pvt *p = pvt;
2040 
2041  p->owner = new_owner;
2042 }
struct ast_channel * owner
Definition: chan_dahdi.h:127

◆ my_set_outgoing()

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

Definition at line 1922 of file chan_dahdi.c.

References dahdi_pvt::digital, dahdi_pvt::inservice, dahdi_pvt::locallyblocked, dahdi_pvt::outgoing, and dahdi_pvt::remotelyblocked.

Referenced by my_on_hook().

1923 {
1924  struct dahdi_pvt *p = pvt;
1925 
1926  p->outgoing = is_outgoing;
1927 }
unsigned int outgoing
TRUE if we originated the call leg.
Definition: chan_dahdi.h:290

◆ my_set_polarity()

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

Definition at line 2601 of file chan_dahdi.c.

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(), and my_start_polarityswitch().

2602 {
2603  struct dahdi_pvt *p = pvt;
2604 
2605  if (p->channel == CHAN_PSEUDO) {
2606  return;
2607  }
2608  p->polarity = value;
2609  ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETPOLARITY, &value);
2610 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define CHAN_PSEUDO
Definition: chan_dahdi.c:556
int value
Definition: syslog.c:37
int polarity
Current line interface polarity. POLARITY_IDLE, POLARITY_REV.
Definition: chan_dahdi.h:681
#define SUB_REAL
Definition: chan_dahdi.h:57
int channel
Definition: chan_dahdi.h:538

◆ my_set_pulsedial()

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

Definition at line 2031 of file chan_dahdi.c.

References dahdi_pvt::pulsedial.

2032 {
2033  struct dahdi_pvt *p = pvt;
2034  p->pulsedial = flag;
2035 }
long int flag
Definition: f2c.h:83
unsigned int pulsedial
TRUE if a pulsed digit was detected. (Pulse dial phone detected)
Definition: chan_dahdi.h:318

◆ my_set_ringtimeout()

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

Definition at line 1965 of file chan_dahdi.c.

References dahdi_pvt::ringt.

1966 {
1967  struct dahdi_pvt *p = pvt;
1968  p->ringt = ringt;
1969 }
int ringt
Ring timeout timer??
Definition: chan_dahdi.h:556

◆ my_set_waitingfordt()

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

Definition at line 1971 of file chan_dahdi.c.

References ast_debug, ast_setstate(), AST_STATE_OFFHOOK, CANPROGRESSDETECT, dahdi_pvt::dsp, NULL, dahdi_pvt::waitfordialtone, and dahdi_pvt::waitingfordt.

1972 {
1973  struct dahdi_pvt *p = pvt;
1974 
1975  if (p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp) {
1976  ast_debug(1, "Defer dialing for %dms or dialtone\n", p->waitfordialtone);
1977  gettimeofday(&p->waitingfordt, NULL);
1979  }
1980 }
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct timeval waitingfordt
Definition: chan_dahdi.h:636
struct ast_dsp * dsp
Opaque DSP configuration structure.
Definition: chan_dahdi.h:639
int waitfordialtone
Number of milliseconds to wait for dialtone.
Definition: chan_dahdi.h:609
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
#define CANPROGRESSDETECT(p)
Definition: chan_dahdi.c:594

◆ my_start()

static int my_start ( void *  pvt)
static

Definition at line 2647 of file chan_dahdi.c.

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

2648 {
2649  struct dahdi_pvt *p = pvt;
2650  int x = DAHDI_START;
2651 
2652  return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
2653 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define SUB_REAL
Definition: chan_dahdi.h:57

◆ my_start_cid_detect()

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

Definition at line 1269 of file chan_dahdi.c.

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

1270 {
1271  struct dahdi_pvt *p = pvt;
1272  int index = SUB_REAL;
1274  if (!p->cs) {
1275  ast_log(LOG_ERROR, "Unable to alloc callerid\n");
1276  return -1;
1277  }
1278  bump_gains(p);
1279  dahdi_setlinear(p->subs[index].dfd, 0);
1280 
1281  return 0;
1282 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
int cid_signalling
Definition: chan_dahdi.h:541
#define ast_log
Definition: astobj2.c:42
static int bump_gains(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4895
#define LOG_ERROR
Definition: logger.h:285
#define SUB_REAL
Definition: chan_dahdi.h:57
struct callerid_state * cs
Definition: chan_dahdi.h:126
static int dahdi_setlinear(int dfd, int linear)
Definition: chan_dahdi.c:4161
struct callerid_state * callerid_new(int cid_signalling)
Create a callerID state machine.
Definition: callerid.c:129

◆ my_start_polarityswitch()

static void my_start_polarityswitch ( void *  pvt)
static

Definition at line 2612 of file chan_dahdi.c.

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

2613 {
2614  struct dahdi_pvt *p = pvt;
2615 
2617  my_set_polarity(pvt, 0);
2618  }
2619 }
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:183
unsigned int hanguponpolarityswitch
TRUE if the call will be considered "hung up" on a polarity reversal.
Definition: chan_dahdi.h:261
static void my_set_polarity(void *pvt, int value)
Definition: chan_dahdi.c:2601

◆ my_stop_callwait()

static int my_stop_callwait ( void *  pvt)
static

Definition at line 1499 of file chan_dahdi.c.

References dahdi_pvt::callwaitingrepeat, dahdi_pvt::cid_suppress_expire, dahdi_pvt::cidcwexpire, restore_conference(), save_conference(), and send_callerid().

1500 {
1501  struct dahdi_pvt *p = pvt;
1502  p->callwaitingrepeat = 0;
1503  p->cidcwexpire = 0;
1504  p->cid_suppress_expire = 0;
1505 
1506  return 0;
1507 }
int callwaitingrepeat
Definition: chan_dahdi.h:546
int cidcwexpire
Definition: chan_dahdi.h:547
int cid_suppress_expire
Definition: chan_dahdi.h:548

◆ my_stop_cid_detect()

static int my_stop_cid_detect ( void *  pvt)
static

Definition at line 1286 of file chan_dahdi.c.

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

1287 {
1288  struct dahdi_pvt *p = pvt;
1289  int index = SUB_REAL;
1290 
1291  if (p->cs) {
1292  callerid_free(p->cs);
1293  }
1294 
1295  /* Restore linear mode after Caller*ID processing */
1296  dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
1297  restore_gains(p);
1298 
1299  return 0;
1300 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static int restore_gains(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4909
unsigned int linear
Definition: chan_dahdi.h:90
#define SUB_REAL
Definition: chan_dahdi.h:57
struct callerid_state * cs
Definition: chan_dahdi.h:126
static int dahdi_setlinear(int dfd, int linear)
Definition: chan_dahdi.c:4161
void callerid_free(struct callerid_state *cid)
This function frees callerid_state cid.
Definition: callerid.c:734

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

References analogsub_to_dahdisub(), ast_channel_set_fd(), ast_channel::callid, dahdi_subchannel::chan, dahdi_new(), dahdi_new_callid_clean(), db, dahdi_subchannel::dfd, dahdi_subchannel::inthreeway, dahdi_subchannel::owner, dahdi_pvt::subs, and wakeup_sub().

2183 {
2184  struct dahdi_pvt *p = pvt;
2185  int da, db;
2186  int tchan;
2187  int tinthreeway;
2188 
2189  da = analogsub_to_dahdisub(a);
2190  db = analogsub_to_dahdisub(b);
2191 
2192  tchan = p->subs[da].chan;
2193  p->subs[da].chan = p->subs[db].chan;
2194  p->subs[db].chan = tchan;
2195 
2196  tinthreeway = p->subs[da].inthreeway;
2197  p->subs[da].inthreeway = p->subs[db].inthreeway;
2198  p->subs[db].inthreeway = tinthreeway;
2199 
2200  p->subs[da].owner = ast_a;
2201  p->subs[db].owner = ast_b;
2202 
2203  if (ast_a)
2204  ast_channel_set_fd(ast_a, 0, p->subs[da].dfd);
2205  if (ast_b)
2206  ast_channel_set_fd(ast_b, 0, p->subs[db].dfd);
2207 
2208  wakeup_sub(p, a);
2209  wakeup_sub(p, b);
2210 
2211  return;
2212 }
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static sqlite3 * db
static void wakeup_sub(struct dahdi_pvt *p, int a)
Definition: chan_dahdi.c:3481
struct ast_channel * owner
Definition: chan_dahdi.h:79
unsigned int inthreeway
Definition: chan_dahdi.h:91
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
static struct test_val b
static struct test_val a

◆ my_train_echocanceller()

static int my_train_echocanceller ( void *  pvt)
static

Definition at line 2675 of file chan_dahdi.c.

References dahdi_train_ec().

2676 {
2677  struct dahdi_pvt *p = pvt;
2678 
2679  dahdi_train_ec(p);
2680 
2681  return 0;
2682 }
static void dahdi_train_ec(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4693

◆ my_unallocate_sub()

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

Definition at line 2377 of file chan_dahdi.c.

References alloc_sub(), analogsub_to_dahdisub(), and unalloc_sub().

2378 {
2379  struct dahdi_pvt *p = pvt;
2380 
2381  return unalloc_sub(p, analogsub_to_dahdisub(analogsub));
2382 }
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
static int unalloc_sub(struct dahdi_pvt *p, int x)
Definition: chan_dahdi.c:4204

◆ my_unlock_private()

static void my_unlock_private ( void *  pvt)
static

Definition at line 1728 of file chan_dahdi.c.

References ast_mutex_unlock, and dahdi_pvt::lock.

Referenced by my_on_hook().

1729 {
1730  struct dahdi_pvt *p = pvt;
1731  ast_mutex_unlock(&p->lock);
1732 }
ast_mutex_t lock
Definition: chan_dahdi.h:125
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ my_wait_event()

static int my_wait_event ( void *  pvt)
static

Definition at line 2509 of file chan_dahdi.c.

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

2510 {
2511  struct dahdi_pvt *p = pvt;
2512 
2513  return dahdi_wait_event(p->subs[SUB_REAL].dfd);
2514 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static int dahdi_wait_event(int fd)
Avoid the silly dahdi_waitevent which ignores a bunch of events.
Definition: chan_dahdi.c:661
#define SUB_REAL
Definition: chan_dahdi.h:57

◆ my_wink()

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

Definition at line 1632 of file chan_dahdi.c.

References a, analogsub_to_dahdisub(), ast_log, dahdi_confmute(), dahdi_wink(), LOG_ERROR, muted, reset_conf(), SUB_REAL, and wakeup_sub().

1633 {
1634  struct dahdi_pvt *p = pvt;
1635  int index = analogsub_to_dahdisub(sub);
1636  if (index != SUB_REAL) {
1637  ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n");
1638  }
1639  return dahdi_wink(p, index);
1640 }
static int analogsub_to_dahdisub(enum analog_sub analogsub)
Definition: chan_dahdi.c:1126
static int dahdi_wink(struct dahdi_pvt *p, int index)
Definition: chan_dahdi.c:9419
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
#define SUB_REAL
Definition: chan_dahdi.h:57
struct stasis_forward * sub
Definition: res_corosync.c:240

◆ 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.
Returns
nothing

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

References ast_publish_mwi_state, ast_safe_system(), ast_strlen_zero, mwimonitornotify, and NULL.

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

3293 {
3294  char s[sizeof(mwimonitornotify) + 80];
3295 
3296  if (ast_strlen_zero(mailbox)) {
3297  return;
3298  }
3299 
3300  ast_publish_mwi_state(mailbox, NULL, thereornot, thereornot);
3302  snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
3303  ast_safe_system(s);
3304  }
3305 }
#define NULL
Definition: resample.c:96
#define ast_publish_mwi_state(mailbox, context, new_msgs, old_msgs)
Publish a MWI state update via stasis.
Definition: mwi.h:380
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: extconf.c:829
static char mwimonitornotify[PATH_MAX]
Definition: chan_dahdi.c:600

◆ parse_buffers_policy()

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

Definition at line 6878 of file chan_dahdi.c.

References ast_log, and LOG_WARNING.

Referenced by dahdi_func_write(), and process_dahdi().

6879 {
6880  int res;
6881  char policy_str[21] = "";
6882 
6883  if ((res = sscanf(parse, "%30d,%20s", num_buffers, policy_str)) != 2) {
6884  ast_log(LOG_WARNING, "Parsing buffer string '%s' failed.\n", parse);
6885  return 1;
6886  }
6887  if (*num_buffers < 0) {
6888  ast_log(LOG_WARNING, "Invalid buffer count given '%d'.\n", *num_buffers);
6889  return -1;
6890  }
6891  if (!strcasecmp(policy_str, "full")) {
6892  *policy = DAHDI_POLICY_WHEN_FULL;
6893  } else if (!strcasecmp(policy_str, "immediate")) {
6894  *policy = DAHDI_POLICY_IMMEDIATE;
6895 #if defined(HAVE_DAHDI_HALF_FULL)
6896  } else if (!strcasecmp(policy_str, "half")) {
6897  *policy = DAHDI_POLICY_HALF_FULL;
6898 #endif
6899  } else {
6900  ast_log(LOG_WARNING, "Invalid policy name given '%s'.\n", policy_str);
6901  return -1;
6902  }
6903 
6904  return 0;
6905 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872

◆ parse_busy_pattern()

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

Definition at line 17865 of file chan_dahdi.c.

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

17866 {
17867  int count_pattern = 0;
17868  int norval = 0;
17869  char *temp = NULL;
17870 
17871  for (; ;) {
17872  /* Scans the string for the next value in the pattern. If none, it checks to see if any have been entered so far. */
17873  if (!sscanf(v->value, "%30d", &norval) && count_pattern == 0) {
17874  ast_log(LOG_ERROR, "busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->lineno);
17875  break;
17876  }
17877 
17878  busy_cadence->pattern[count_pattern] = norval;
17879 
17880  count_pattern++;
17881  if (count_pattern == 4) {
17882  break;
17883  }
17884 
17885  temp = strchr(v->value, ',');
17886  if (temp == NULL) {
17887  break;
17888  }
17889  v->value = temp + 1;
17890  }
17891  busy_cadence->length = count_pattern;
17892 
17893  if (count_pattern % 2 != 0) {
17894  /* The pattern length must be divisible by two */
17895  ast_log(LOG_ERROR, "busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->lineno);
17896  }
17897 
17898 }
int pattern[4]
Definition: dsp.h:68
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285

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

References dahdi_pvt::accountcode, dahdi_pvt::adsi, dahdi_pvt::amaflags, ANALOG_FIRST_DIGIT_TIMEOUT, ANALOG_INTER_DIGIT_TIMEOUT, ANALOG_MATCH_DIGIT_TIMEOUT, 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::callgroup, dahdi_pvt::callprogress, CALLPROGRESS_FAX, CALLPROGRESS_FAX_INCOMING, CALLPROGRESS_FAX_OUTGOING, CALLPROGRESS_PROGRESS, dahdi_pvt::callreturn, dahdi_pvt::callwaiting, dahdi_pvt::callwaitingcallerid, dahdi_pvt::cancallforward, dahdi_pvt::canpark, dahdi_pvt::cc_params, dahdi_chan_conf::chan, CHAN_PSEUDO, dahdi_pvt::cid_name, dahdi_pvt::cid_num, dahdi_pvt::cid_rxgain, CID_SIG_BELL, CID_SIG_DTMF, CID_SIG_SMDI, CID_SIG_V23, CID_SIG_V23_JP, dahdi_pvt::cid_signalling, dahdi_pvt::cid_start, CID_START_DTMF_NOALERT, CID_START_POLARITY, CID_START_POLARITY_IN, CID_START_RING, dahdi_pvt::cid_tag, 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::destroy, 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, dahdi_chan_conf::ignore_failed_channels, dahdi_pvt::immediate, 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::manages_span_alarms, 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, dahdi_pvt::next, NULL, num_cadence, NUM_CADENCE_MAX, numbufs, 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, 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, dahdi_pvt::span, SS7_NAI_DYNAMIC, strcasestr(), dahdi_pvt::stripmsd, strsep(), dahdi_pvt::threewaycalling, 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().

17901 {
17902  struct dahdi_pvt *tmp;
17903  int y;
17904  struct ast_variable *dahdichan = NULL;
17905 
17906  for (; v; v = v->next) {
17907  if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
17908  continue;
17909 
17910  /* Create the interface list */
17911  if (!strcasecmp(v->name, "channel") || !strcasecmp(v->name, "channels")) {
17913  ast_log(LOG_WARNING, "Channel '%s' ignored.\n", v->value);
17914  continue;
17915  }
17916  if (build_channels(confp, v->value, reload, v->lineno)) {
17917  if (confp->ignore_failed_channels) {
17918  ast_log(LOG_WARNING, "Channel '%s' failure ignored: ignore_failed_channels.\n", v->value);
17919  continue;
17920  } else {
17921  return -1;
17922  }
17923  }
17924  ast_debug(1, "Channel '%s' configured.\n", v->value);
17925  } else if (!strcasecmp(v->name, "ignore_failed_channels")) {
17926  confp->ignore_failed_channels = ast_true(v->value);
17927  } else if (!strcasecmp(v->name, "buffers")) {
17928  if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) {
17929  ast_log(LOG_WARNING, "Using default buffer policy.\n");
17930  confp->chan.buf_no = numbufs;
17931  confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE;
17932  }
17933  } else if (!strcasecmp(v->name, "faxbuffers")) {
17934  if (!parse_buffers_policy(v->value, &confp->chan.faxbuf_no, &confp->chan.faxbuf_policy)) {
17935  confp->chan.usefaxbuffers = 1;
17936  }
17937  } else if (!strcasecmp(v->name, "dahdichan")) {
17938  /* Only process the last dahdichan value. */
17939  dahdichan = v;
17940  } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
17942  } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
17944  } else if (!strcasecmp(v->name, "dring1context")) {
17946  } else if (!strcasecmp(v->name, "dring2context")) {
17948  } else if (!strcasecmp(v->name, "dring3context")) {
17950  } else if (!strcasecmp(v->name, "dring1range")) {
17951  confp->chan.drings.ringnum[0].range = atoi(v->value);
17952  } else if (!strcasecmp(v->name, "dring2range")) {
17953  confp->chan.drings.ringnum[1].range = atoi(v->value);
17954  } else if (!strcasecmp(v->name, "dring3range")) {
17955  confp->chan.drings.ringnum[2].range = atoi(v->value);
17956  } else if (!strcasecmp(v->name, "dring1")) {
17957  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]);
17958  } else if (!strcasecmp(v->name, "dring2")) {
17959  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]);
17960  } else if (!strcasecmp(v->name, "dring3")) {
17961  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]);
17962  } else if (!strcasecmp(v->name, "usecallerid")) {
17963  confp->chan.use_callerid = ast_true(v->value);
17964  } else if (!strcasecmp(v->name, "cidsignalling")) {
17965  if (!strcasecmp(v->value, "bell"))
17966  confp->chan.cid_signalling = CID_SIG_BELL;
17967  else if (!strcasecmp(v->value, "v23"))
17968  confp->chan.cid_signalling = CID_SIG_V23;
17969  else if (!strcasecmp(v->value, "dtmf"))
17970  confp->chan.cid_signalling = CID_SIG_DTMF;
17971  else if (!strcasecmp(v->value, "smdi"))
17972  confp->chan.cid_signalling = CID_SIG_SMDI;
17973  else if (!strcasecmp(v->value, "v23_jp"))
17975  else if (ast_true(v->value))
17976  confp->chan.cid_signalling = CID_SIG_BELL;
17977  } else if (!strcasecmp(v->name, "cidstart")) {
17978  if (!strcasecmp(v->value, "ring"))
17979  confp->chan.cid_start = CID_START_RING;
17980  else if (!strcasecmp(v->value, "polarity_in"))
17982  else if (!strcasecmp(v->value, "polarity"))
17984  else if (!strcasecmp(v->value, "dtmf"))
17986  else if (ast_true(v->value))
17987  confp->chan.cid_start = CID_START_RING;
17988  } else if (!strcasecmp(v->name, "threewaycalling")) {
17989  confp->chan.threewaycalling = ast_true(v->value);
17990  } else if (!strcasecmp(v->name, "cancallforward")) {
17991  confp->chan.cancallforward = ast_true(v->value);
17992  } else if (!strcasecmp(v->name, "relaxdtmf")) {
17993  if (ast_true(v->value))
17995  else
17996  confp->chan.dtmfrelax = 0;
17997  } else if (!strcasecmp(v->name, "mailbox")) {
17998  ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
17999  } else if (!strcasecmp(v->name, "description")) {
18000  ast_copy_string(confp->chan.description, v->value, sizeof(confp->chan.description));
18001  } else if (!strcasecmp(v->name, "hasvoicemail")) {
18002  if (ast_true(v->value) && ast_strlen_zero(confp->chan.mailbox)) {
18003  /*
18004  * hasvoicemail is a users.conf legacy voicemail enable method.
18005  * hasvoicemail is only going to work for app_voicemail mailboxes.
18006  */
18007  if (strchr(cat, '@')) {
18008  ast_copy_string(confp->chan.mailbox, cat, sizeof(confp->chan.mailbox));
18009  } else {
18010  snprintf(confp->chan.mailbox, sizeof(confp->chan.mailbox),
18011  "%s@default", cat);
18012  }
18013  }
18014  } else if (!strcasecmp(v->name, "adsi")) {
18015  confp->chan.adsi = ast_true(v->value);
18016  } else if (!strcasecmp(v->name, "usesmdi")) {
18017  confp->chan.use_smdi = ast_true(v->value);
18018  } else if (!strcasecmp(v->name, "smdiport")) {
18019  ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
18020  } else if (!strcasecmp(v->name, "transfer")) {
18021  confp->chan.transfer = ast_true(v->value);
18022  } else if (!strcasecmp(v->name, "canpark")) {
18023  confp->chan.canpark = ast_true(v->value);
18024  } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
18025  confp->chan.echocanbridged = ast_true(v->value);
18026  } else if (!strcasecmp(v->name, "busydetect")) {
18027  confp->chan.busydetect = ast_true(v->value);
18028  } else if (!strcasecmp(v->name, "busycount")) {
18029  confp->chan.busycount = atoi(v->value);
18030  } else if (!strcasecmp(v->name, "busypattern")) {
18031  parse_busy_pattern(v, &confp->chan.busy_cadence);
18032  } else if (!strcasecmp(v->name, "callprogress")) {
18034  if (ast_true(v->value))
18036  } else if (!strcasecmp(v->name, "waitfordialtone")) {
18037  confp->chan.waitfordialtone = atoi(v->value);
18038  } else if (!strcasecmp(v->name, "dialtone_detect")) {
18039  if (!strcasecmp(v->value, "always")) {
18040  confp->chan.dialtone_detect = -1;
18041  } else if (ast_true(v->value)) {
18043  } else if (ast_false(v->value)) {
18044  confp->chan.dialtone_detect = 0;
18045  } else {
18046  confp->chan.dialtone_detect = ast_strlen_zero(v->value) ? 0 : (8 * atoi(v->value)) / READ_SIZE;
18047  }
18048  } else if (!strcasecmp(v->name, "faxdetect")) {
18049  confp->chan.callprogress &= ~CALLPROGRESS_FAX;
18050  if (!strcasecmp(v->value, "incoming")) {
18052  } else if (!strcasecmp(v->value, "outgoing")) {
18054  } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
18056  } else if (!strcasecmp(v->name, "faxdetect_timeout")) {
18057  if (sscanf(v->value, "%30u", &confp->chan.faxdetect_timeout) != 1) {
18058  confp->chan.faxdetect_timeout = 0;
18059  }
18060  } else if (!strcasecmp(v->name, "firstdigit_timeout")) {
18061  if (sscanf(v->value, "%30d", &confp->chan.firstdigit_timeout) != 1
18062  || confp->chan.firstdigit_timeout <= 0) {
18064  }
18065  } else if (!strcasecmp(v->name, "interdigit_timeout")) {
18066  if (sscanf(v->value, "%30d", &confp->chan.interdigit_timeout) != 1
18067  || confp->chan.interdigit_timeout <= 0) {
18069  }
18070  } else if (!strcasecmp(v->name, "matchdigit_timeout")) {
18071  if (sscanf(v->value, "%30d", &confp->chan.matchdigit_timeout) != 1
18072  || confp->chan.matchdigit_timeout <= 0) {
18074  }
18075  } else if (!strcasecmp(v->name, "echocancel")) {
18076  process_echocancel(confp, v->value, v->lineno);
18077  } else if (!strcasecmp(v->name, "echotraining")) {
18078  if (sscanf(v->value, "%30d", &y) == 1) {
18079  if ((y < 10) || (y > 4000)) {
18080  ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d.\n", v->lineno);
18081  } else {
18082  confp->chan.echotraining = y;
18083  }
18084  } else if (ast_true(v->value)) {
18085  confp->chan.echotraining = 400;
18086  } else
18087  confp->chan.echotraining = 0;
18088  } else if (!strcasecmp(v->name, "hidecallerid")) {
18089  confp->chan.hidecallerid = ast_true(v->value);
18090  } else if (!strcasecmp(v->name, "hidecalleridname")) {
18091  confp->chan.hidecalleridname = ast_true(v->value);
18092  } else if (!strcasecmp(v->name, "pulsedial")) {
18093  confp->chan.pulse = ast_true(v->value);
18094  } else if (!strcasecmp(v->name, "callreturn")) {
18095  confp->chan.callreturn = ast_true(v->value);
18096  } else if (!strcasecmp(v->name, "callwaiting")) {
18097  confp->chan.callwaiting = ast_true(v->value);
18098  } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
18099  confp->chan.callwaitingcallerid = ast_true(v->value);
18100  } else if (!strcasecmp(v->name, "context")) {
18101  ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
18102  } else if (!strcasecmp(v->name, "language")) {
18103  ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
18104  } else if (!strcasecmp(v->name, "progzone")) {
18105  ast_copy_string(progzone, v->value, sizeof(progzone));
18106  } else if (!strcasecmp(v->name, "mohinterpret")
18107  ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
18108  ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
18109  } else if (!strcasecmp(v->name, "mohsuggest")) {
18110  ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
18111  } else if (!strcasecmp(v->name, "parkinglot")) {
18112  ast_copy_string(confp->chan.parkinglot, v->value, sizeof(confp->chan.parkinglot));
18113  } else if (!strcasecmp(v->name, "stripmsd")) {
18114  ast_log(LOG_NOTICE, "Configuration option \"%s\" has been deprecated. Please use dialplan instead\n", v->name);
18115  confp->chan.stripmsd = atoi(v->value);
18116  } else if (!strcasecmp(v->name, "jitterbuffers")) {
18117  numbufs = atoi(v->value);
18118  } else if (!strcasecmp(v->name, "group")) {
18119  confp->chan.group = ast_get_group(v->value);
18120  } else if (!strcasecmp(v->name, "callgroup")) {
18121  if (!strcasecmp(v->value, "none"))
18122  confp->chan.callgroup = 0;
18123  else
18124  confp->chan.callgroup = ast_get_group(v->value);
18125  } else if (!strcasecmp(v->name, "pickupgroup")) {
18126  if (!strcasecmp(v->value, "none"))
18127  confp->chan.pickupgroup = 0;
18128  else
18129  confp->chan.pickupgroup = ast_get_group(v->value);
18130  } else if (!strcasecmp(v->name, "namedcallgroup")) {
18132  } else if (!strcasecmp(v->name, "namedpickupgroup")) {
18134  } else if (!strcasecmp(v->name, "setvar")) {
18135  if (v->value) {
18136  char *varval = NULL;
18137  struct ast_variable *tmpvar;
18138  char varname[strlen(v->value) + 1];
18139  strcpy(varname, v->value); /* safe */
18140  if ((varval = strchr(varname, '='))) {
18141  *varval++ = '\0';
18142  if ((tmpvar = ast_variable_new(varname, varval, ""))) {
18143  if (ast_variable_list_replace(&confp->chan.vars, tmpvar)) {
18144  tmpvar->next = confp->chan.vars;
18145  confp->chan.vars = tmpvar;
18146  }
18147  }
18148  }
18149  }
18150  } else if (!strcasecmp(v->name, "immediate")) {
18151  confp->chan.immediate = ast_true(v->value);
18152  } else if (!strcasecmp(v->name, "transfertobusy")) {
18153  confp->chan.transfertobusy = ast_true(v->value);
18154  } else if (!strcasecmp(v->name, "mwimonitor")) {
18155  confp->chan.mwimonitor_neon = 0;
18156  confp->chan.mwimonitor_fsk = 0;
18157  confp->chan.mwimonitor_rpas = 0;
18158  if (strcasestr(v->value, "fsk")) {
18159  confp->chan.mwimonitor_fsk = 1;
18160  }
18161  if (strcasestr(v->value, "rpas")) {
18162  confp->chan.mwimonitor_rpas = 1;
18163  }
18164  if (strcasestr(v->value, "neon")) {
18165  confp->chan.mwimonitor_neon = 1;
18166  }
18167  /* If set to true or yes, assume that simple fsk is desired */
18168  if (ast_true(v->value)) {
18169  confp->chan.mwimonitor_fsk = 1;
18170  }
18171  } else if (!strcasecmp(v->name, "hwrxgain")) {
18172  confp->chan.hwrxgain_enabled = 0;
18173  if (strcasecmp(v->value, "disabled")) {
18174  if (sscanf(v->value, "%30f", &confp->chan.hwrxgain) == 1) {
18175  confp->chan.hwrxgain_enabled = 1;
18176  } else {
18177  ast_log(LOG_WARNING, "Invalid hwrxgain: %s at line %d.\n", v->value, v->lineno);
18178  }
18179  }
18180  } else if (!strcasecmp(v->name, "hwtxgain")) {
18181  confp->chan.hwtxgain_enabled = 0;
18182  if (strcasecmp(v->value, "disabled")) {
18183  if (sscanf(v->value, "%30f", &confp->chan.hwtxgain) == 1) {
18184  confp->chan.hwtxgain_enabled = 1;
18185  } else {
18186  ast_log(LOG_WARNING, "Invalid hwtxgain: %s at line %d.\n", v->value, v->lineno);
18187  }
18188  }
18189  } else if (!strcasecmp(v->name, "cid_rxgain")) {
18190  if (sscanf(v->value, "%30f", &confp->chan.cid_rxgain) != 1) {
18191  ast_log(LOG_WARNING, "Invalid cid_rxgain: %s at line %d.\n", v->value, v->lineno);
18192  }
18193  } else if (!strcasecmp(v->name, "rxgain")) {
18194  if (sscanf(v->value, "%30f", &confp->chan.rxgain) != 1) {
18195  ast_log(LOG_WARNING, "Invalid rxgain: %s at line %d.\n", v->value, v->lineno);
18196  }
18197  } else if (!strcasecmp(v->name, "txgain")) {
18198  if (sscanf(v->value, "%30f", &confp->chan.txgain) != 1) {
18199  ast_log(LOG_WARNING, "Invalid txgain: %s at line %d.\n", v->value, v->lineno);
18200  }
18201  } else if (!strcasecmp(v->name, "txdrc")) {
18202  if (sscanf(v->value, "%f", &confp->chan.txdrc) != 1) {
18203  ast_log(LOG_WARNING, "Invalid txdrc: %s\n", v->value);
18204  }
18205  } else if (!strcasecmp(v->name, "rxdrc")) {
18206  if (sscanf(v->value, "%f", &confp->chan.rxdrc) != 1) {
18207  ast_log(LOG_WARNING, "Invalid rxdrc: %s\n", v->value);
18208  }
18209  } else if (!strcasecmp(v->name, "tonezone")) {
18210  if (sscanf(v->value, "%30d", &confp->chan.tonezone) != 1) {
18211  ast_log(LOG_WARNING, "Invalid tonezone: %s at line %d.\n", v->value, v->lineno);
18212  }
18213  } else if (!strcasecmp(v->name, "callerid")) {
18214  if (!strcasecmp(v->value, "asreceived")) {
18215  confp->chan.cid_num[0] = '\0';
18216  confp->chan.cid_name[0] = '\0';
18217  } else {
18218  ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
18219  }
18220  } else if (!strcasecmp(v->name, "fullname")) {
18221  ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
18222  } else if (!strcasecmp(v->name, "cid_number")) {
18223  ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
18224  } else if (!strcasecmp(v->name, "cid_tag")) {
18225  ast_copy_string(confp->chan.cid_tag, v->value, sizeof(confp->chan.cid_tag));
18226  } else if (!strcasecmp(v->name, "useincomingcalleridondahditransfer")) {
18227  confp->chan.dahditrcallerid = ast_true(v->value);
18228  } else if (!strcasecmp(v->name, "restrictcid")) {
18229  confp->chan.restrictcid = ast_true(v->value);
18230  } else if (!strcasecmp(v->name, "usecallingpres")) {
18231  confp->chan.use_callingpres = ast_true(v->value);
18232  } else if (!strcasecmp(v->name, "accountcode")) {
18233  ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
18234  } else if (!strcasecmp(v->name, "amaflags")) {
18236  if (y < 0)
18237  ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d.\n", v->value, v->lineno);
18238  else
18239  confp->chan.amaflags = y;
18240  } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
18241  confp->chan.polarityonanswerdelay = atoi(v->value);
18242  } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
18244  } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
18246  } else if (!strcasecmp(v->name, "sendcalleridafter")) {
18247  confp->chan.sendcalleridafter = atoi(v->value);
18248  } else if (!strcasecmp(v->name, "mwimonitornotify")) {
18250  } else if (ast_cc_is_config_param(v->name)) {
18251  ast_cc_set_param(confp->chan.cc_params, v->name, v->value);
18252  } else if (!strcasecmp(v->name, "mwisendtype")) {
18253 #ifndef HAVE_DAHDI_LINEREVERSE_VMWI /* backward compatibility for older dahdi VMWI implementation */
18254  if (!strcasecmp(v->value, "rpas")) { /* Ring Pulse Alert Signal */
18255  mwisend_rpas = 1;
18256  } else {
18257  mwisend_rpas = 0;
18258  }
18259 #else
18260  /* Default is fsk, to turn it off you must specify nofsk */
18261  memset(&confp->chan.mwisend_setting, 0, sizeof(confp->chan.mwisend_setting));
18262  if (strcasestr(v->value, "nofsk")) { /* NoFSK */
18263  confp->chan.mwisend_fsk = 0;
18264  } else { /* Default FSK */
18265  confp->chan.mwisend_fsk = 1;
18266  }
18267  if (strcasestr(v->value, "rpas")) { /* Ring Pulse Alert Signal, normally followed by FSK */
18268  confp->chan.mwisend_rpas = 1;
18269  } else {
18270  confp->chan.mwisend_rpas = 0;
18271  }
18272  if (strcasestr(v->value, "lrev")) { /* Line Reversal */
18273  confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV;
18274  }
18275  if (strcasestr(v->value, "hvdc")) { /* HV 90VDC */
18276  confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC;
18277  }
18278  if ( (strcasestr(v->value, "neon")) || (strcasestr(v->value, "hvac")) ) { /* 90V DC pulses */
18279  confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC;
18280  }
18281 #endif
18282  } else if (reload != 1) {
18283  if (!strcasecmp(v->name, "signalling") || !strcasecmp(v->name, "signaling")) {
18284  int orig_radio = confp->chan.radio;
18285  int orig_outsigmod = confp->chan.outsigmod;
18286  int orig_auto = confp->is_sig_auto;
18287 
18288  confp->chan.radio = 0;
18289  confp->chan.outsigmod = -1;
18290  confp->is_sig_auto = 0;
18291  if (!strcasecmp(v->value, "em")) {
18292  confp->chan.sig = SIG_EM;
18293  } else if (!strcasecmp(v->value, "em_e1")) {
18294  confp->chan.sig = SIG_EM_E1;
18295  } else if (!strcasecmp(v->value, "em_w")) {
18296  confp->chan.sig = SIG_EMWINK;
18297  } else if (!strcasecmp(v->value, "fxs_ls")) {
18298  confp->chan.sig = SIG_FXSLS;
18299  } else if (!strcasecmp(v->value, "fxs_gs")) {
18300  confp->chan.sig = SIG_FXSGS;
18301  } else if (!strcasecmp(v->value, "fxs_ks")) {
18302  confp->chan.sig = SIG_FXSKS;
18303  } else if (!strcasecmp(v->value, "fxo_ls")) {
18304  confp->chan.sig = SIG_FXOLS;
18305  } else if (!strcasecmp(v->value, "fxo_gs")) {
18306  confp->chan.sig = SIG_FXOGS;
18307  } else if (!strcasecmp(v->value, "fxo_ks")) {
18308  confp->chan.sig = SIG_FXOKS;
18309  } else if (!strcasecmp(v->value, "fxs_rx")) {
18310  confp->chan.sig = SIG_FXSKS;
18311  confp->chan.radio = 1;
18312  } else if (!strcasecmp(v->value, "fxo_rx")) {
18313  confp->chan.sig = SIG_FXOLS;
18314  confp->chan.radio = 1;
18315  } else if (!strcasecmp(v->value, "fxs_tx")) {
18316  confp->chan.sig = SIG_FXSLS;
18317  confp->chan.radio = 1;
18318  } else if (!strcasecmp(v->value, "fxo_tx")) {
18319  confp->chan.sig = SIG_FXOGS;
18320  confp->chan.radio = 1;
18321  } else if (!strcasecmp(v->value, "em_rx")) {
18322  confp->chan.sig = SIG_EM;
18323  confp->chan.radio = 1;
18324  } else if (!strcasecmp(v->value, "em_tx")) {
18325  confp->chan.sig = SIG_EM;
18326  confp->chan.radio = 1;
18327  } else if (!strcasecmp(v->value, "em_rxtx")) {
18328  confp->chan.sig = SIG_EM;
18329  confp->chan.radio = 2;
18330  } else if (!strcasecmp(v->value, "em_txrx")) {
18331  confp->chan.sig = SIG_EM;
18332  confp->chan.radio = 2;
18333  } else if (!strcasecmp(v->value, "sf")) {
18334  confp->chan.sig = SIG_SF;
18335  } else if (!strcasecmp(v->value, "sf_w")) {
18336  confp->chan.sig = SIG_SFWINK;
18337  } else if (!strcasecmp(v->value, "sf_featd")) {
18338  confp->chan.sig = SIG_FEATD;
18339  } else if (!strcasecmp(v->value, "sf_featdmf")) {
18340  confp->chan.sig = SIG_FEATDMF;
18341  } else if (!strcasecmp(v->value, "sf_featb")) {
18342  confp->chan.sig = SIG_SF_FEATB;
18343  } else if (!strcasecmp(v->value, "sf")) {
18344  confp->chan.sig = SIG_SF;
18345  } else if (!strcasecmp(v->value, "sf_rx")) {
18346  confp->chan.sig = SIG_SF;
18347  confp->chan.radio = 1;
18348  } else if (!strcasecmp(v->value, "sf_tx")) {
18349  confp->chan.sig = SIG_SF;
18350  confp->chan.radio = 1;
18351  } else if (!strcasecmp(v->value, "sf_rxtx")) {
18352  confp->chan.sig = SIG_SF;
18353  confp->chan.radio = 2;
18354  } else if (!strcasecmp(v->value, "sf_txrx")) {
18355  confp->chan.sig = SIG_SF;
18356  confp->chan.radio = 2;
18357  } else if (!strcasecmp(v->value, "featd")) {
18358  confp->chan.sig = SIG_FEATD;
18359  } else if (!strcasecmp(v->value, "featdmf")) {
18360  confp->chan.sig = SIG_FEATDMF;
18361  } else if (!strcasecmp(v->value, "featdmf_ta")) {
18362  confp->chan.sig = SIG_FEATDMF_TA;
18363  } else if (!strcasecmp(v->value, "e911")) {
18364  confp->chan.sig = SIG_E911;
18365  } else if (!strcasecmp(v->value, "fgccama")) {
18366  confp->chan.sig = SIG_FGC_CAMA;
18367  } else if (!strcasecmp(v->value, "fgccamamf")) {
18368  confp->chan.sig = SIG_FGC_CAMAMF;
18369  } else if (!strcasecmp(v->value, "featb")) {
18370  confp->chan.sig = SIG_FEATB;
18371 #ifdef HAVE_PRI
18372  } else if (!strcasecmp(v->value, "pri_net")) {
18373  confp->chan.sig = SIG_PRI;
18374  confp->pri.pri.nodetype = PRI_NETWORK;
18375  } else if (!strcasecmp(v->value, "pri_cpe")) {
18376  confp->chan.sig = SIG_PRI;
18377  confp->pri.pri.nodetype = PRI_CPE;
18378  } else if (!strcasecmp(v->value, "bri_cpe")) {
18379  confp->chan.sig = SIG_BRI;
18380  confp->pri.pri.nodetype = PRI_CPE;
18381  } else if (!strcasecmp(v->value, "bri_net")) {
18382  confp->chan.sig = SIG_BRI;
18383  confp->pri.pri.nodetype = PRI_NETWORK;
18384  } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) {
18385  confp->chan.sig = SIG_BRI_PTMP;
18386  confp->pri.pri.nodetype = PRI_CPE;
18387  } else if (!strcasecmp(v->value, "bri_net_ptmp")) {
18388 #if defined(HAVE_PRI_CALL_HOLD)
18389  confp->chan.sig = SIG_BRI_PTMP;
18390  confp->pri.pri.nodetype = PRI_NETWORK;
18391 #else
18392  ast_log(LOG_WARNING, "How cool would it be if someone implemented this mode! For now, sucks for you. (line %d)\n", v->lineno);
18393 #endif /* !defined(HAVE_PRI_CALL_HOLD) */
18394 #endif
18395 #if defined(HAVE_SS7)
18396  } else if (!strcasecmp(v->value, "ss7")) {
18397  confp->chan.sig = SIG_SS7;
18398 #endif /* defined(HAVE_SS7) */
18399 #ifdef HAVE_OPENR2
18400  } else if (!strcasecmp(v->value, "mfcr2")) {
18401  confp->chan.sig = SIG_MFCR2;
18402 #endif
18403  } else if (!strcasecmp(v->value, "auto")) {
18404  confp->is_sig_auto = 1;
18405  } else {
18406  confp->chan.outsigmod = orig_outsigmod;
18407  confp->chan.radio = orig_radio;
18408  confp->is_sig_auto = orig_auto;
18409  ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno);
18410  }
18411  } else if (!strcasecmp(v->name, "outsignalling") || !strcasecmp(v->name, "outsignaling")) {
18412  if (!strcasecmp(v->value, "em")) {
18413  confp->chan.outsigmod = SIG_EM;
18414  } else if (!strcasecmp(v->value, "em_e1")) {
18415  confp->chan.outsigmod = SIG_EM_E1;
18416  } else if (!strcasecmp(v->value, "em_w")) {
18417  confp->chan.outsigmod = SIG_EMWINK;
18418  } else if (!strcasecmp(v->value, "sf")) {
18419  confp->chan.outsigmod = SIG_SF;
18420  } else if (!strcasecmp(v->value, "sf_w")) {
18421  confp->chan.outsigmod = SIG_SFWINK;
18422  } else if (!strcasecmp(v->value, "sf_featd")) {
18423  confp->chan.outsigmod = SIG_FEATD;
18424  } else if (!strcasecmp(v->value, "sf_featdmf")) {
18425  confp->chan.outsigmod = SIG_FEATDMF;
18426  } else if (!strcasecmp(v->value, "sf_featb")) {
18427  confp->chan.outsigmod = SIG_SF_FEATB;
18428  } else if (!strcasecmp(v->value, "sf")) {
18429  confp->chan.outsigmod = SIG_SF;
18430  } else if (!strcasecmp(v->value, "featd")) {
18431  confp->chan.outsigmod = SIG_FEATD;
18432  } else if (!strcasecmp(v->value, "featdmf")) {
18433  confp->chan.outsigmod = SIG_FEATDMF;
18434  } else if (!strcasecmp(v->value, "featdmf_ta")) {
18435  confp->chan.outsigmod = SIG_FEATDMF_TA;
18436  } else if (!strcasecmp(v->value, "e911")) {
18437  confp->chan.outsigmod = SIG_E911;
18438  } else if (!strcasecmp(v->value, "fgccama")) {
18439  confp->chan.outsigmod = SIG_FGC_CAMA;
18440  } else if (!strcasecmp(v->value, "fgccamamf")) {
18441  confp->chan.outsigmod = SIG_FGC_CAMAMF;
18442  } else if (!strcasecmp(v->value, "featb")) {
18443  confp->chan.outsigmod = SIG_FEATB;
18444  } else {
18445  ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno);
18446  }
18447 #ifdef HAVE_PRI
18448  } else if (!strcasecmp(v->name, "pridialplan")) {
18449  if (!strcasecmp(v->value, "national")) {
18450  confp->pri.pri.dialplan = PRI_NATIONAL_ISDN + 1;
18451  } else if (!strcasecmp(v->value, "unknown")) {
18452  confp->pri.pri.dialplan = PRI_UNKNOWN + 1;
18453  } else if (!strcasecmp(v->value, "private")) {
18454  confp->pri.pri.dialplan = PRI_PRIVATE + 1;
18455  } else if (!strcasecmp(v->value, "international")) {
18456  confp->pri.pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
18457  } else if (!strcasecmp(v->value, "local")) {
18458  confp->pri.pri.dialplan = PRI_LOCAL_ISDN + 1;
18459  } else if (!strcasecmp(v->value, "dynamic")) {
18460  confp->pri.pri.dialplan = -1;
18461  } else if (!strcasecmp(v->value, "redundant")) {
18462  confp->pri.pri.dialplan = -2;
18463  } else {
18464  ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
18465  }
18466  } else if (!strcasecmp(v->name, "prilocaldialplan")) {
18467  if (!strcasecmp(v->value, "national")) {
18468  confp->pri.pri.localdialplan = PRI_NATIONAL_ISDN + 1;
18469  } else if (!strcasecmp(v->value, "unknown")) {
18470  confp->pri.pri.localdialplan = PRI_UNKNOWN + 1;
18471  } else if (!strcasecmp(v->value, "private")) {
18472  confp->pri.pri.localdialplan = PRI_PRIVATE + 1;
18473  } else if (!strcasecmp(v->value, "international")) {
18474  confp->pri.pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
18475  } else if (!strcasecmp(v->value, "local")) {
18476  confp->pri.pri.localdialplan = PRI_LOCAL_ISDN + 1;
18477  } else if (!strcasecmp(v->value, "from_channel")) {
18478  confp->pri.pri.localdialplan = 0;
18479  } else if (!strcasecmp(v->value, "dynamic")) {
18480  confp->pri.pri.localdialplan = -1;
18481  } else if (!strcasecmp(v->value, "redundant")) {
18482  confp->pri.pri.localdialplan = -2;
18483  } else {
18484  ast_log(LOG_WARNING, "Unknown PRI localdialplan '%s' at line %d.\n", v->value, v->lineno);
18485  }
18486  } else if (!strcasecmp(v->name, "pricpndialplan")) {
18487  if (!strcasecmp(v->value, "national")) {
18488  confp->pri.pri.cpndialplan = PRI_NATIONAL_ISDN + 1;
18489  } else if (!strcasecmp(v->value, "unknown")) {
18490  confp->pri.pri.cpndialplan = PRI_UNKNOWN + 1;
18491  } else if (!strcasecmp(v->value, "private")) {
18492  confp->pri.pri.cpndialplan = PRI_PRIVATE + 1;
18493  } else if (!strcasecmp(v->value, "international")) {
18494  confp->pri.pri.cpndialplan = PRI_INTERNATIONAL_ISDN + 1;
18495  } else if (!strcasecmp(v->value, "local")) {
18496  confp->pri.pri.cpndialplan = PRI_LOCAL_ISDN + 1;
18497  } else if (!strcasecmp(v->value, "from_channel")) {
18498  confp->pri.pri.cpndialplan = 0;
18499  } else if (!strcasecmp(v->value, "dynamic")) {
18500  confp->pri.pri.cpndialplan = -1;
18501  } else if (!strcasecmp(v->value, "redundant")) {
18502  confp->pri.pri.cpndialplan = -2;
18503  } else {
18504  ast_log(LOG_WARNING, "Unknown PRI cpndialplan '%s' at line %d.\n", v->value, v->lineno);
18505  }
18506  } else if (!strcasecmp(v->name, "switchtype")) {
18507  if (!strcasecmp(v->value, "national"))
18508  confp->pri.pri.switchtype = PRI_SWITCH_NI2;
18509  else if (!strcasecmp(v->value, "ni1"))
18510  confp->pri.pri.switchtype = PRI_SWITCH_NI1;
18511  else if (!strcasecmp(v->value, "dms100"))
18512  confp->pri.pri.switchtype = PRI_SWITCH_DMS100;
18513  else if (!strcasecmp(v->value, "4ess"))
18514  confp->pri.pri.switchtype = PRI_SWITCH_ATT4ESS;
18515  else if (!strcasecmp(v->value, "5ess"))
18516  confp->pri.pri.switchtype = PRI_SWITCH_LUCENT5E;
18517  else if (!strcasecmp(v->value, "euroisdn"))
18518  confp->pri.pri.switchtype = PRI_SWITCH_EUROISDN_E1;
18519  else if (!strcasecmp(v->value, "qsig"))
18520  confp->pri.pri.switchtype = PRI_SWITCH_QSIG;
18521  else {
18522  ast_log(LOG_ERROR, "Unknown switchtype '%s' at line %d.\n", v->value, v->lineno);
18523  return -1;
18524  }
18525  } else if (!strcasecmp(v->name, "msn")) {
18526  ast_copy_string(confp->pri.pri.msn_list, v->value,
18527  sizeof(confp->pri.pri.msn_list));
18528  } else if (!strcasecmp(v->name, "nsf")) {
18529  if (!strcasecmp(v->value, "sdn"))
18530  confp->pri.pri.nsf = PRI_NSF_SDN;
18531  else if (!strcasecmp(v->value, "megacom"))
18532  confp->pri.pri.nsf = PRI_NSF_MEGACOM;
18533  else if (!strcasecmp(v->value, "tollfreemegacom"))
18534  confp->pri.pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;
18535  else if (!strcasecmp(v->value, "accunet"))
18536  confp->pri.pri.nsf = PRI_NSF_ACCUNET;
18537  else if (!strcasecmp(v->value, "none"))
18538  confp->pri.pri.nsf = PRI_NSF_NONE;
18539  else {
18540  ast_log(LOG_WARNING, "Unknown network-specific facility '%s' at line %d.\n", v->value, v->lineno);
18541  confp->pri.pri.nsf = PRI_NSF_NONE;
18542  }
18543  } else if (!strcasecmp(v->name, "priindication")) {
18544  if (!strcasecmp(v->value, "outofband"))
18545  confp->chan.priindication_oob = 1;
18546  else if (!strcasecmp(v->value, "inband"))
18547  confp->chan.priindication_oob = 0;
18548  else
18549  ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d.\n",
18550  v->value, v->lineno);
18551  } else if (!strcasecmp(v->name, "priexclusive")) {
18552  confp->chan.priexclusive = ast_true(v->value);
18553  } else if (!strcasecmp(v->name, "internationalprefix")) {
18554  ast_copy_string(confp->pri.pri.internationalprefix, v->value, sizeof(confp->pri.pri.internationalprefix));
18555  } else if (!strcasecmp(v->name, "nationalprefix")) {
18556  ast_copy_string(confp->pri.pri.nationalprefix, v->value, sizeof(confp->pri.pri.nationalprefix));
18557  } else if (!strcasecmp(v->name, "localprefix")) {
18558  ast_copy_string(confp->pri.pri.localprefix, v->value, sizeof(confp->pri.pri.localprefix));
18559  } else if (!strcasecmp(v->name, "privateprefix")) {
18560  ast_copy_string(confp->pri.pri.privateprefix, v->value, sizeof(confp->pri.pri.privateprefix));
18561  } else if (!strcasecmp(v->name, "unknownprefix")) {
18562  ast_copy_string(confp->pri.pri.unknownprefix, v->value, sizeof(confp->pri.pri.unknownprefix));
18563  } else if (!strcasecmp(v->name, "resetinterval")) {
18564  if (!strcasecmp(v->value, "never"))
18565  confp->pri.pri.resetinterval = -1;
18566  else if (atoi(v->value) >= 60)
18567  confp->pri.pri.resetinterval = atoi(v->value);
18568  else
18569  ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n",
18570  v->value, v->lineno);
18571  } else if (!strcasecmp(v->name, "force_restart_unavailable_chans")) {
18572  confp->pri.pri.force_restart_unavailable_chans = ast_true(v->value);
18573  } else if (!strcasecmp(v->name, "minunused")) {
18574  confp->pri.pri.minunused = atoi(v->value);
18575  } else if (!strcasecmp(v->name, "minidle")) {
18576  confp->pri.pri.minidle = atoi(v->value);
18577  } else if (!strcasecmp(v->name, "idleext")) {
18578  ast_copy_string(confp->pri.pri.idleext, v->value, sizeof(confp->pri.pri.idleext));
18579  } else if (!strcasecmp(v->name, "idledial")) {
18580  ast_copy_string(confp->pri.pri.idledial, v->value, sizeof(confp->pri.pri.idledial));
18581  } else if (!strcasecmp(v->name, "overlapdial")) {
18582  if (ast_true(v->value)) {
18583  confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
18584  } else if (!strcasecmp(v->value, "incoming")) {
18585  confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_INCOMING;
18586  } else if (!strcasecmp(v->value, "outgoing")) {
18587  confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_OUTGOING;
18588  } else if (!strcasecmp(v->value, "both") || ast_true(v->value)) {
18589  confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
18590  } else {
18591  confp->pri.pri.overlapdial = DAHDI_OVERLAPDIAL_NONE;
18592  }
18593 #ifdef HAVE_PRI_PROG_W_CAUSE
18594  } else if (!strcasecmp(v->name, "qsigchannelmapping")) {
18595  if (!strcasecmp(v->value, "logical")) {
18596  confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_LOGICAL;
18597  } else if (!strcasecmp(v->value, "physical")) {
18598  confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL;
18599  } else {
18600  confp->pri.pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL;
18601  }
18602 #endif
18603  } else if (!strcasecmp(v->name, "discardremoteholdretrieval")) {
18604  confp->pri.pri.discardremoteholdretrieval = ast_true(v->value);
18605 #if defined(HAVE_PRI_SERVICE_MESSAGES)
18606  } else if (!strcasecmp(v->name, "service_message_support")) {
18607  /* assuming switchtype for this channel group has been configured already */
18608  if ((confp->pri.pri.switchtype == PRI_SWITCH_ATT4ESS
18609  || confp->pri.pri.switchtype == PRI_SWITCH_LUCENT5E
18610  || confp->pri.pri.switchtype == PRI_SWITCH_NI2) && ast_true(v->value)) {
18611  confp->pri.pri.enable_service_message_support = 1;
18612  } else {
18613  confp->pri.pri.enable_service_message_support = 0;
18614  }
18615 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
18616 #ifdef HAVE_PRI_INBANDDISCONNECT
18617  } else if (!strcasecmp(v->name, "inbanddisconnect")) {
18618  confp->pri.pri.inbanddisconnect = ast_true(v->value);
18619 #endif
18620  } else if (!strcasecmp(v->name, "pritimer")) {
18621 #ifdef PRI_GETSET_TIMERS
18622  char tmp[20];
18623  char *timerc;
18624  char *c;
18625  int timer;
18626  int timeridx;
18627 
18628  ast_copy_string(tmp, v->value, sizeof(tmp));
18629  c = tmp;
18630  timerc = strsep(&c, ",");
18631  if (!ast_strlen_zero(timerc) && !ast_strlen_zero(c)) {
18632  timeridx = pri_timer2idx(timerc);
18633  timer = atoi(c);
18634  if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) {
18636  "'%s' is not a valid ISDN timer at line %d.\n", timerc,
18637  v->lineno);
18638  } else if (!timer) {
18640  "'%s' is not a valid value for ISDN timer '%s' at line %d.\n",
18641  c, timerc, v->lineno);
18642  } else {
18643  confp->pri.pri.pritimers[timeridx] = timer;
18644  }
18645  } else {
18647  "'%s' is not a valid ISDN timer configuration string at line %d.\n",
18648  v->value, v->lineno);
18649  }
18650 #endif /* PRI_GETSET_TIMERS */
18651  } else if (!strcasecmp(v->name, "facilityenable")) {
18652  confp->pri.pri.facilityenable = ast_true(v->value);
18653 #if defined(HAVE_PRI_AOC_EVENTS)
18654  } else if (!strcasecmp(v->name, "aoc_enable")) {
18655  confp->pri.pri.aoc_passthrough_flag = 0;
18656  if (strchr(v->value, 's') || strchr(v->value, 'S')) {
18657  confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_S;
18658  }
18659  if (strchr(v->value, 'd') || strchr(v->value, 'D')) {
18660  confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_D;
18661  }
18662  if (strchr(v->value, 'e') || strchr(v->value, 'E')) {
18663  confp->pri.pri.aoc_passthrough_flag |= SIG_PRI_AOC_GRANT_E;
18664  }
18665  } else if (!strcasecmp(v->name, "aoce_delayhangup")) {
18666  confp->pri.pri.aoce_delayhangup = ast_true(v->value);
18667 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
18668 #if defined(HAVE_PRI_CALL_HOLD)
18669  } else if (!strcasecmp(v->name, "hold_disconnect_transfer")) {
18670  confp->pri.pri.hold_disconnect_transfer = ast_true(v->value);
18671 #endif /* defined(HAVE_PRI_CALL_HOLD) */
18672  } else if (!strcasecmp(v->name, "moh_signaling")
18673  || !strcasecmp(v->name, "moh_signalling")) {
18674  if (!strcasecmp(v->value, "moh")) {
18675  confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_MOH;
18676  } else if (!strcasecmp(v->value, "notify")) {
18677  confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_NOTIFY;
18678 #if defined(HAVE_PRI_CALL_HOLD)
18679  } else if (!strcasecmp(v->value, "hold")) {
18680  confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_HOLD;
18681 #endif /* defined(HAVE_PRI_CALL_HOLD) */
18682  } else {
18683  confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_MOH;
18684  }
18685 #if defined(HAVE_PRI_CCSS)
18686  } else if (!strcasecmp(v->name, "cc_ptmp_recall_mode")) {
18687  if (!strcasecmp(v->value, "global")) {
18688  confp->pri.pri.cc_ptmp_recall_mode = 0;/* globalRecall */
18689  } else if (!strcasecmp(v->value, "specific")) {
18690  confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */
18691  } else {
18692  confp->pri.pri.cc_ptmp_recall_mode = 1;/* specificRecall */
18693  }
18694  } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_req")) {
18695  if (!strcasecmp(v->value, "release")) {
18696  confp->pri.pri.cc_qsig_signaling_link_req = 0;/* release */
18697  } else if (!strcasecmp(v->value, "retain")) {
18698  confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */
18699  } else if (!strcasecmp(v->value, "do_not_care")) {
18700  confp->pri.pri.cc_qsig_signaling_link_req = 2;/* do-not-care */
18701  } else {
18702  confp->pri.pri.cc_qsig_signaling_link_req = 1;/* retain */
18703  }
18704  } else if (!strcasecmp(v->name, "cc_qsig_signaling_link_rsp")) {
18705  if (!strcasecmp(v->value, "release")) {
18706  confp->pri.pri.cc_qsig_signaling_link_rsp = 0;/* release */
18707  } else if (!strcasecmp(v->value, "retain")) {
18708  confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */
18709  } else {
18710  confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */
18711  }
18712 #endif /* defined(HAVE_PRI_CCSS) */
18713 #if defined(HAVE_PRI_CALL_WAITING)
18714  } else if (!strcasecmp(v->name, "max_call_waiting_calls")) {
18715  confp->pri.pri.max_call_waiting_calls = atoi(v->value);
18716  if (confp->pri.pri.max_call_waiting_calls < 0) {
18717  /* Negative values are not allowed. */
18718  confp->pri.pri.max_call_waiting_calls = 0;
18719  }
18720  } else if (!strcasecmp(v->name, "allow_call_waiting_calls")) {
18721  confp->pri.pri.allow_call_waiting_calls = ast_true(v->value);
18722 #endif /* defined(HAVE_PRI_CALL_WAITING) */
18723 #if defined(HAVE_PRI_MWI)
18724  } else if (!strcasecmp(v->name, "mwi_mailboxes")) {
18725  ast_copy_string(confp->pri.pri.mwi_mailboxes, v->value,
18726  sizeof(confp->pri.pri.mwi_mailboxes));
18727  } else if (!strcasecmp(v->name, "mwi_vm_boxes")) {
18728  ast_copy_string(confp->pri.pri.mwi_vm_boxes, v->value,
18729  sizeof(confp->pri.pri.mwi_vm_boxes));
18730  } else if (!strcasecmp(v->name, "mwi_vm_numbers")) {
18731  ast_copy_string(confp->pri.pri.mwi_vm_numbers, v->value,
18732  sizeof(confp->pri.pri.mwi_vm_numbers));
18733 #endif /* defined(HAVE_PRI_MWI) */
18734  } else if (!strcasecmp(v->name, "append_msn_to_cid_tag")) {
18735  confp->pri.pri.append_msn_to_user_tag = ast_true(v->value);
18736  } else if (!strcasecmp(v->name, "inband_on_setup_ack")) {
18737  confp->pri.pri.inband_on_setup_ack = ast_true(v->value);
18738  } else if (!strcasecmp(v->name, "inband_on_proceeding")) {
18739  confp->pri.pri.inband_on_proceeding = ast_true(v->value);
18740 #if defined(HAVE_PRI_DISPLAY_TEXT)
18741  } else if (!strcasecmp(v->name, "display_send")) {
18742  confp->pri.pri.display_flags_send = dahdi_display_text_option(v->value);
18743  } else if (!strcasecmp(v->name, "display_receive")) {
18744  confp->pri.pri.display_flags_receive = dahdi_display_text_option(v->value);
18745 #endif /* defined(HAVE_PRI_DISPLAY_TEXT) */
18746 #if defined(HAVE_PRI_MCID)
18747  } else if (!strcasecmp(v->name, "mcid_send")) {
18748  confp->pri.pri.mcid_send = ast_true(v->value);
18749 #endif /* defined(HAVE_PRI_MCID) */
18750 #if defined(HAVE_PRI_DATETIME_SEND)
18751  } else if (!strcasecmp(v->name, "datetime_send")) {
18752  confp->pri.pri.datetime_send = dahdi_datetime_send_option(v->value);
18753 #endif /* defined(HAVE_PRI_DATETIME_SEND) */
18754  } else if (!strcasecmp(v->name, "layer1_presence")) {
18755  if (!strcasecmp(v->value, "required")) {
18756  confp->pri.pri.layer1_ignored = 0;
18757  } else if (!strcasecmp(v->value, "ignore")) {
18758  confp->pri.pri.layer1_ignored = 1;
18759  } else {
18760  /* Default */
18761  confp->pri.pri.layer1_ignored = 0;
18762  }
18763 #if defined(HAVE_PRI_L2_PERSISTENCE)
18764  } else if (!strcasecmp(v->name, "layer2_persistence")) {
18765  if (!strcasecmp(v->value, "keep_up")) {
18766  confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_KEEP_UP;
18767  } else if (!strcasecmp(v->value, "leave_down")) {
18768  confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_LEAVE_DOWN;
18769  } else {
18770  confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_DEFAULT;
18771  }
18772 #endif /* defined(HAVE_PRI_L2_PERSISTENCE) */
18773  } else if (!strcasecmp(v->name, "colp_send")) {
18774  if (!strcasecmp(v->value, "block")) {
18775  confp->pri.pri.colp_send = SIG_PRI_COLP_BLOCK;
18776  } else if (!strcasecmp(v->value, "connect")) {
18777  confp->pri.pri.colp_send = SIG_PRI_COLP_CONNECT;
18778  } else if (!strcasecmp(v->value, "update")) {
18779  confp->pri.pri.colp_send = SIG_PRI_COLP_UPDATE;
18780  } else {
18781  confp->pri.pri.colp_send = SIG_PRI_COLP_UPDATE;
18782  }
18783 #endif /* HAVE_PRI */
18784 #if defined(HAVE_SS7)
18785  } else if (!strcasecmp(v->name, "ss7type")) {
18786  if (!strcasecmp(v->value, "itu")) {
18787  cur_ss7type = SS7_ITU;
18788  } else if (!strcasecmp(v->value, "ansi")) {
18789  cur_ss7type = SS7_ANSI;
18790  } else {
18791  ast_log(LOG_WARNING, "'%s' is an unknown ss7 switch type at line %d.!\n", v->value, v->lineno);
18792  }
18793  } else if (!strcasecmp(v->name, "slc")) {
18794  cur_slc = atoi(v->value);
18795  } else if (!strcasecmp(v->name, "linkset")) {
18796  cur_linkset = atoi(v->value);
18797  } else if (!strcasecmp(v->name, "pointcode")) {
18798  cur_pointcode = parse_pointcode(v->value);
18799  } else if (!strcasecmp(v->name, "adjpointcode")) {
18800  cur_adjpointcode = parse_pointcode(v->value);
18801  } else if (!strcasecmp(v->name, "defaultdpc")) {
18802  cur_defaultdpc = parse_pointcode(v->value);
18803  } else if (!strcasecmp(v->name, "cicbeginswith")) {
18804  cur_cicbeginswith = atoi(v->value);
18805  } else if (!strcasecmp(v->name, "networkindicator")) {
18806  if (!strcasecmp(v->value, "national")) {
18807  cur_networkindicator = SS7_NI_NAT;
18808  } else if (!strcasecmp(v->value, "national_spare")) {
18809  cur_networkindicator = SS7_NI_NAT_SPARE;
18810  } else if (!strcasecmp(v->value, "international")) {
18811  cur_networkindicator = SS7_NI_INT;
18812  } else if (!strcasecmp(v->value, "international_spare")) {
18813  cur_networkindicator = SS7_NI_INT_SPARE;
18814  } else {
18815  cur_networkindicator = -1;
18816  }
18817  } else if (!strcasecmp(v->name, "ss7_internationalprefix")) {
18818  ast_copy_string(confp->ss7.ss7.internationalprefix, v->value, sizeof(confp->ss7.ss7.internationalprefix));
18819  } else if (!strcasecmp(v->name, "ss7_nationalprefix")) {
18820  ast_copy_string(confp->ss7.ss7.nationalprefix, v->value, sizeof(confp->ss7.ss7.nationalprefix));
18821  } else if (!strcasecmp(v->name, "ss7_subscriberprefix")) {
18822  ast_copy_string(confp->ss7.ss7.subscriberprefix, v->value, sizeof(confp->ss7.ss7.subscriberprefix));
18823  } else if (!strcasecmp(v->name, "ss7_unknownprefix")) {
18824  ast_copy_string(confp->ss7.ss7.unknownprefix, v->value, sizeof(confp->ss7.ss7.unknownprefix));
18825  } else if (!strcasecmp(v->name, "ss7_networkroutedprefix")) {
18826  ast_copy_string(confp->ss7.ss7.networkroutedprefix, v->value, sizeof(confp->ss7.ss7.networkroutedprefix));
18827  } else if (!strcasecmp(v->name, "ss7_called_nai")) {
18828  if (!strcasecmp(v->value, "national")) {
18829  confp->ss7.ss7.called_nai = SS7_NAI_NATIONAL;
18830  } else if (!strcasecmp(v->value, "international")) {
18831  confp->ss7.ss7.called_nai = SS7_NAI_INTERNATIONAL;
18832  } else if (!strcasecmp(v->value, "subscriber")) {
18833  confp->ss7.ss7.called_nai = SS7_NAI_SUBSCRIBER;
18834  } else if (!strcasecmp(v->value, "unknown")) {
18835  confp->ss7.ss7.called_nai = SS7_NAI_UNKNOWN;
18836  } else if (!strcasecmp(v->value, "dynamic")) {
18837  confp->ss7.ss7.called_nai = SS7_NAI_DYNAMIC;
18838  } else {
18839  ast_log(LOG_WARNING, "Unknown SS7 called_nai '%s' at line %d.\n", v->value, v->lineno);
18840  }
18841  } else if (!strcasecmp(v->name, "ss7_calling_nai")) {
18842  if (!strcasecmp(v->value, "national")) {
18843  confp->ss7.ss7.calling_nai = SS7_NAI_NATIONAL;
18844  } else if (!strcasecmp(v->value, "international")) {
18845  confp->ss7.ss7.calling_nai = SS7_NAI_INTERNATIONAL;
18846  } else if (!strcasecmp(v->value, "subscriber")) {
18847  confp->ss7.ss7.calling_nai = SS7_NAI_SUBSCRIBER;
18848  } else if (!strcasecmp(v->value, "unknown")) {
18849  confp->ss7.ss7.calling_nai = SS7_NAI_UNKNOWN;
18850  } else if (!strcasecmp(v->value, "dynamic")) {
18851  confp->ss7.ss7.calling_nai = SS7_NAI_DYNAMIC;
18852  } else {
18853  ast_log(LOG_WARNING, "Unknown SS7 calling_nai '%s' at line %d.\n", v->value, v->lineno);
18854  }
18855  } else if (!strcasecmp(v->name, "sigchan")) {
18856  int sigchan, res;
18857  sigchan = atoi(v->value);
18858  res = linkset_addsigchan(sigchan);
18859  if (res < 0) {
18860  return -1;
18861  }
18862  } else if (!strcasecmp(v->name, "ss7_explicitacm")) {
18863  struct dahdi_ss7 *link;
18864  link = ss7_resolve_linkset(cur_linkset);
18865  if (!link) {
18866  ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
18867  return -1;
18868  }
18869  if (ast_true(v->value)) {
18870  link->ss7.flags |= LINKSET_FLAG_EXPLICITACM;
18871  } else {
18872  link->ss7.flags &= ~LINKSET_FLAG_EXPLICITACM;
18873  }
18874  } else if (!strcasecmp(v->name, "ss7_autoacm")) {
18875  struct dahdi_ss7 *link;
18876  link = ss7_resolve_linkset(cur_linkset);
18877  if (!link) {
18878  ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
18879  return -1;
18880  }
18881  if (ast_true(v->value)) {
18882  link->ss7.flags |= LINKSET_FLAG_AUTOACM;
18883  } else {
18884  link->ss7.flags &= ~LINKSET_FLAG_AUTOACM;
18885  }
18886  } else if (!strcasecmp(v->name, "ss7_initialhwblo")) {
18887  struct dahdi_ss7 *link;
18888  link = ss7_resolve_linkset(cur_linkset);
18889  if (!link) {
18890  ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
18891  return -1;
18892  }
18893  if (ast_true(v->value)) {
18894  link->ss7.flags |= LINKSET_FLAG_INITIALHWBLO;
18895  } else {
18896  link->ss7.flags &= ~LINKSET_FLAG_INITIALHWBLO;
18897  }
18898  } else if (!strcasecmp(v->name, "ss7_use_echocontrol")) {
18899  struct dahdi_ss7 *link;
18900  link = ss7_resolve_linkset(cur_linkset);
18901  if (!link) {
18902  ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
18903  return -1;
18904  }
18905  if (ast_true(v->value)) {
18906  link->ss7.flags |= LINKSET_FLAG_USEECHOCONTROL;
18907  } else {
18908  link->ss7.flags &= ~LINKSET_FLAG_USEECHOCONTROL;
18909  }
18910  } else if (!strcasecmp(v->name, "ss7_default_echocontrol")) {
18911  struct dahdi_ss7 *link;
18912  link = ss7_resolve_linkset(cur_linkset);
18913  if (!link) {
18914  ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
18915  return -1;
18916  }
18917  if (ast_true(v->value)) {
18918  link->ss7.flags |= LINKSET_FLAG_DEFAULTECHOCONTROL;
18919  } else {
18920  link->ss7.flags &= ~LINKSET_FLAG_DEFAULTECHOCONTROL;
18921  }
18922  } else if (!strncasecmp(v->name, "isup_timer.", 11)) {
18923  struct dahdi_ss7 *link;
18924  link = ss7_resolve_linkset(cur_linkset);
18925  if (!link) {
18926  ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
18927  return -1;
18928  }
18929  if (!link->ss7.ss7) {
18930  ast_log(LOG_ERROR, "Please specify isup timers after sigchan!\n");
18931  } else if (!ss7_set_isup_timer(link->ss7.ss7, strstr(v->name, ".") + 1, atoi(v->value))) {
18932  ast_log(LOG_ERROR, "Invalid isup timer %s\n", v->name);
18933  }
18934  } else if (!strncasecmp(v->name, "mtp3_timer.", 11)) {
18935  struct dahdi_ss7 *link;
18936  link = ss7_resolve_linkset(cur_linkset);
18937  if (!link) {
18938  ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
18939  return -1;
18940  }
18941  if (!link->ss7.ss7) {
18942  ast_log(LOG_ERROR, "Please specify mtp3 timers after sigchan!\n");
18943  } else if (!ss7_set_mtp3_timer(link->ss7.ss7, strstr(v->name, ".") + 1, atoi(v->value))) {
18944  ast_log(LOG_ERROR, "Invalid mtp3 timer %s\n", v->name);
18945  }
18946  } else if (!strcasecmp(v->name, "inr_if_no_calling")) {
18947  struct dahdi_ss7 *link;
18948  link = ss7_resolve_linkset(cur_linkset);
18949  if (!link) {
18950  ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
18951  return -1;
18952  }
18953  if (!link->ss7.ss7) {
18954  ast_log(LOG_ERROR, "Please specify inr_if_no_calling after sigchan!\n");
18955  } else if (ast_true(v->value)) {
18956  ss7_set_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
18957  } else {
18958  ss7_clear_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
18959  }
18960  } else if (!strcasecmp(v->name, "non_isdn_access")) {
18961  struct dahdi_ss7 *link;
18962  link = ss7_resolve_linkset(cur_linkset);
18963  if (!link) {
18964  ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
18965  return -1;
18966  }
18967  if (!link->ss7.ss7) {
18968  ast_log(LOG_ERROR, "Please specify non_isdn_access after sigchan!\n");
18969  } else if (ast_true(v->value)) {
18970  ss7_clear_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
18971  } else {
18972  ss7_set_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
18973  }
18974  } else if (!strcasecmp(v->name, "sls_shift")) {
18975  struct dahdi_ss7 *link;
18976  int sls_shift = atoi(v->value);
18977 
18978  if (sls_shift < 0 || sls_shift > 7) {
18979  ast_log(LOG_ERROR, "Invalid sls_shift value. Must be between 0 and 7\n");
18980  return -1;
18981  }
18982 
18983  link = ss7_resolve_linkset(cur_linkset);
18984  if (!link) {
18985  ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
18986  return -1;
18987  }
18988  if (!link->ss7.ss7) {
18989  ast_log(LOG_ERROR, "Please specify sls_shift after sigchan!\n");
18990  } else {
18991  ss7_set_sls_shift(link->ss7.ss7, sls_shift);
18992  }
18993  } else if (!strcasecmp(v->name, "cause_location")) {
18994  struct dahdi_ss7 *link;
18995  int cause_location = atoi(v->value);
18996 
18997  if (cause_location < 0 || cause_location > 15) {
18998  ast_log(LOG_ERROR, "Invalid cause_location value. Must be between 0 and 15\n");
18999  return -1;
19000  }
19001  link = ss7_resolve_linkset(cur_linkset);
19002  if (!link) {
19003  ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
19004  return -1;
19005  }
19006  if (!link->ss7.ss7) {
19007  ast_log(LOG_ERROR, "Please specify cause_location after sigchan!\n");
19008  } else {
19009  ss7_set_cause_location(link->ss7.ss7, cause_location);
19010  }
19011 #endif /* defined(HAVE_SS7) */
19012 #ifdef HAVE_OPENR2
19013  } else if (!strcasecmp(v->name, "mfcr2_advanced_protocol_file")) {
19014  ast_copy_string(confp->mfcr2.r2proto_file, v->value, sizeof(confp->mfcr2.r2proto_file));
19015  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);
19016  } else if (!strcasecmp(v->name, "mfcr2_logdir")) {
19017  ast_copy_string(confp->mfcr2.logdir, v->value, sizeof(confp->mfcr2.logdir));
19018  } else if (!strcasecmp(v->name, "mfcr2_variant")) {
19019  confp->mfcr2.variant = openr2_proto_get_variant(v->value);
19020  if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) {
19021  ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d, defaulting to ITU.\n", v->value, v->lineno);
19022  confp->mfcr2.variant = OR2_VAR_ITU;
19023  }
19024  } else if (!strcasecmp(v->name, "mfcr2_mfback_timeout")) {
19025  confp->mfcr2.mfback_timeout = atoi(v->value);
19026  if (!confp->mfcr2.mfback_timeout) {
19027  ast_log(LOG_WARNING, "MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n");
19028  confp->mfcr2.mfback_timeout = -1;
19029  } else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) {
19030  ast_log(LOG_WARNING, "MF timeout less than 500ms is not recommended, you have been warned!\n");
19031  }
19032  } else if (!strcasecmp(v->name, "mfcr2_metering_pulse_timeout")) {
19033  confp->mfcr2.metering_pulse_timeout = atoi(v->value);
19034  if (confp->mfcr2.metering_pulse_timeout > 500) {
19035  ast_log(LOG_WARNING, "Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n");
19036  }
19037 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
19038  } else if (!strcasecmp(v->name, "mfcr2_dtmf_detection")) {
19039  confp->mfcr2.dtmf_detection = ast_true(v->value) ? 1 : 0;
19040  } else if (!strcasecmp(v->name, "mfcr2_dtmf_dialing")) {
19041  confp->mfcr2.dtmf_dialing = ast_true(v->value) ? 1 : 0;
19042  } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_on")) {
19043  confp->mfcr2.dtmf_time_on = atoi(v->value);
19044  } else if (!strcasecmp(v->name, "mfcr2_dtmf_time_off")) {
19045  confp->mfcr2.dtmf_time_off = atoi(v->value);
19046 #endif
19047 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
19048  } else if (!strcasecmp(v->name, "mfcr2_dtmf_end_timeout")) {
19049  confp->mfcr2.dtmf_end_timeout = atoi(v->value);
19050 #endif
19051  } else if (!strcasecmp(v->name, "mfcr2_get_ani_first")) {
19052  confp->mfcr2.get_ani_first = ast_true(v->value) ? 1 : 0;
19053  } else if (!strcasecmp(v->name, "mfcr2_double_answer")) {
19054  confp->mfcr2.double_answer = ast_true(v->value) ? 1 : 0;
19055  } else if (!strcasecmp(v->name, "mfcr2_charge_calls")) {
19056  confp->mfcr2.charge_calls = ast_true(v->value) ? 1 : 0;
19057  } else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) {
19058  confp->mfcr2.accept_on_offer = ast_true(v->value) ? 1 : 0;
19059  } else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) {
19060  confp->mfcr2.allow_collect_calls = ast_true(v->value) ? 1 : 0;
19061  } else if (!strcasecmp(v->name, "mfcr2_forced_release")) {
19062  confp->mfcr2.forced_release = ast_true(v->value) ? 1 : 0;
19063  } else if (!strcasecmp(v->name, "mfcr2_immediate_accept")) {
19064  confp->mfcr2.immediate_accept = ast_true(v->value) ? 1 : 0;
19065 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
19066  } else if (!strcasecmp(v->name, "mfcr2_skip_category")) {
19067  confp->mfcr2.skip_category_request = ast_true(v->value) ? 1 : 0;
19068 #endif
19069  } else if (!strcasecmp(v->name, "mfcr2_call_files")) {
19070  confp->mfcr2.call_files = ast_true(v->value) ? 1 : 0;
19071  } else if (!strcasecmp(v->name, "mfcr2_max_ani")) {
19072  confp->mfcr2.max_ani = atoi(v->value);
19073  if (confp->mfcr2.max_ani >= AST_MAX_EXTENSION) {
19074  confp->mfcr2.max_ani = AST_MAX_EXTENSION - 1;
19075  }
19076  } else if (!strcasecmp(v->name, "mfcr2_max_dnis")) {
19077  confp->mfcr2.max_dnis = atoi(v->value);
19078  if (confp->mfcr2.max_dnis >= AST_MAX_EXTENSION) {
19079  confp->mfcr2.max_dnis = AST_MAX_EXTENSION - 1;
19080  }
19081  } else if (!strcasecmp(v->name, "mfcr2_category")) {
19082  confp->mfcr2.category = openr2_proto_get_category(v->value);
19083  if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) {
19084  confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
19085  ast_log(LOG_WARNING, "Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n",
19086  v->value, v->lineno);
19087  }
19088  } else if (!strcasecmp(v->name, "mfcr2_logging")) {
19089  openr2_log_level_t tmplevel;
19090  char *clevel;
19091  char *logval;
19092  char copy[strlen(v->value) + 1];
19093  strcpy(copy, v->value); /* safe */
19094  logval = copy;
19095  while (logval) {
19096  clevel = strsep(&logval,",");
19097  if (-1 == (tmplevel = openr2_log_get_level(clevel))) {
19098  ast_log(LOG_WARNING, "Ignoring invalid logging level: '%s' at line %d.\n", clevel, v->lineno);
19099  continue;
19100  }
19101  confp->mfcr2.loglevel |= tmplevel;
19102  }
19103 #endif /* HAVE_OPENR2 */
19104  } else if (!strcasecmp(v->name, "cadence")) {
19105  /* setup to scan our argument */
19106  int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
19107  int i;
19108  struct dahdi_ring_cadence new_cadence;
19109  int cid_location = -1;
19110  int firstcadencepos = 0;
19111  char original_args[80];
19112  int cadence_is_ok = 1;
19113 
19114  ast_copy_string(original_args, v->value, sizeof(original_args));
19115  /* 16 cadences allowed (8 pairs) */
19116  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]);
19117 
19118  /* Cadence must be even (on/off) */
19119  if (element_count % 2 == 1) {
19120  ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s at line %d.\n", original_args, v->lineno);
19121  cadence_is_ok = 0;
19122  }
19123 
19124  /* This check is only needed to satisfy the compiler that element_count can't cause an out of bounds */
19125  if (element_count > ARRAY_LEN(c)) {
19126  element_count = ARRAY_LEN(c);
19127  }
19128 
19129  /* Ring cadences cannot be negative */
19130  for (i = 0; i < element_count; i++) {
19131  if (c[i] == 0) {
19132  ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s at line %d.\n", original_args, v->lineno);
19133  cadence_is_ok = 0;
19134  break;
19135  } else if (c[i] < 0) {
19136  if (i % 2 == 1) {
19137  /* Silence duration, negative possibly okay */
19138  if (cid_location == -1) {
19139  cid_location = i;
19140  c[i] *= -1;
19141  } else {
19142  ast_log(LOG_ERROR, "CID location specified twice: %s at line %d.\n", original_args, v->lineno);
19143  cadence_is_ok = 0;
19144  break;
19145  }
19146  } else {
19147  if (firstcadencepos == 0) {
19148  firstcadencepos = i; /* only recorded to avoid duplicate specification */
19149  /* duration will be passed negative to the DAHDI driver */
19150  } else {
19151  ast_log(LOG_ERROR, "First cadence position specified twice: %s at line %d.\n", original_args, v->lineno);
19152  cadence_is_ok = 0;
19153  break;
19154  }
19155  }
19156  }
19157  }
19158 
19159  /* Substitute our scanned cadence */
19160  for (i = 0; i < 16; i++) {
19161  new_cadence.ringcadence[i] = c[i];
19162  }
19163 
19164  if (cadence_is_ok) {
19165  /* ---we scanned it without getting annoyed; now some sanity checks--- */
19166  if (element_count < 2) {
19167  ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s at line %d.\n", original_args, v->lineno);
19168  } else {
19169  if (cid_location == -1) {
19170  /* user didn't say; default to first pause */
19171  cid_location = 1;
19172  } else {
19173  /* convert element_index to cidrings value */
19174  cid_location = (cid_location + 1) / 2;
19175  }
19176  /* ---we like their cadence; try to install it--- */
19178  /* this is the first user-defined cadence; clear the default user cadences */
19179  num_cadence = 0;
19180  if ((num_cadence+1) >= NUM_CADENCE_MAX)
19181  ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s at line %d.\n", NUM_CADENCE_MAX, original_args, v->lineno);
19182  else {
19183  cadences[num_cadence] = new_cadence;
19184  cidrings[num_cadence++] = cid_location;
19185  ast_verb(3, "cadence 'r%d' added: %s\n",num_cadence,original_args);
19186  }
19187  }
19188  }
19189  } else if (!strcasecmp(v->name, "ringtimeout")) {
19190  ringt_base = (atoi(v->value) * 8) / READ_SIZE;
19191  } else if (!strcasecmp(v->name, "prewink")) {
19192  confp->timing.prewinktime = atoi(v->value);
19193  } else if (!strcasecmp(v->name, "preflash")) {
19194  confp->timing.preflashtime = atoi(v->value);
19195  } else if (!strcasecmp(v->name, "wink")) {
19196  confp->timing.winktime = atoi(v->value);
19197  } else if (!strcasecmp(v->name, "flash")) {
19198  confp->timing.flashtime = atoi(v->value);
19199  } else if (!strcasecmp(v->name, "start")) {
19200  confp->timing.starttime = atoi(v->value);
19201  } else if (!strcasecmp(v->name, "rxwink")) {
19202  confp->timing.rxwinktime = atoi(v->value);
19203  } else if (!strcasecmp(v->name, "rxflash")) {
19204  confp->timing.rxflashtime = atoi(v->value);
19205  } else if (!strcasecmp(v->name, "debounce")) {
19206  confp->timing.debouncetime = atoi(v->value);
19207  } else if (!strcasecmp(v->name, "toneduration")) {
19208  int toneduration;
19209  int ctlfd;
19210  int res;
19211  struct dahdi_dialparams dps;
19212 
19213  ctlfd = open("/dev/dahdi/ctl", O_RDWR);
19214  if (ctlfd == -1) {
19215  ast_log(LOG_ERROR, "Unable to open /dev/dahdi/ctl to set toneduration at line %d.\n", v->lineno);
19216  return -1;
19217  }
19218 
19219  toneduration = atoi(v->value);
19220  if (toneduration > -1) {
19221  memset(&dps, 0, sizeof(dps));
19222 
19223  dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
19224  res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps);
19225  if (res < 0) {
19226  ast_log(LOG_ERROR, "Invalid tone duration: %d ms at line %d: %s\n", toneduration, v->lineno, strerror(errno));
19227  close(ctlfd);
19228  return -1;
19229  }
19230  }
19231  close(ctlfd);
19232  } else if (!strcasecmp(v->name, "defaultcic")) {
19234  } else if (!strcasecmp(v->name, "defaultozz")) {
19236  } else if (!strcasecmp(v->name, "mwilevel")) {
19237  mwilevel = atoi(v->value);
19238  } else if (!strcasecmp(v->name, "dtmfcidlevel")) {
19239  dtmfcid_level = atoi(v->value);
19240  } else if (!strcasecmp(v->name, "reportalarms")) {
19241  if (!strcasecmp(v->value, "all"))
19243  if (!strcasecmp(v->value, "none"))
19244  report_alarms = 0;
19245  else if (!strcasecmp(v->value, "channels"))
19247  else if (!strcasecmp(v->value, "spans"))
19249  }
19250  } else if (!(options & PROC_DAHDI_OPT_NOWARN) )
19251  ast_log(LOG_WARNING, "Ignoring any changes to '%s' (on reload) at line %d.\n", v->name, v->lineno);
19252  }
19253 
19254  if (dahdichan) {
19255  /* Process the deferred dahdichan value. */
19256  if (build_channels(confp, dahdichan->value, reload, dahdichan->lineno)) {
19257  if (confp->ignore_failed_channels) {
19259  "Dahdichan '%s' failure ignored: ignore_failed_channels.\n",
19260  dahdichan->value);
19261  } else {
19262  return -1;
19263  }
19264  }
19265  }
19266 
19267  /*
19268  * Since confp has already filled individual dahdi_pvt objects with channels
19269  * at this point, clear the variables in confp's pvt.
19270  */
19271  if (confp->chan.vars) {
19273  confp->chan.vars = NULL;
19274  }
19275 
19276  /* mark the first channels of each DAHDI span to watch for their span alarms */
19277  for (tmp = iflist, y=-1; tmp; tmp = tmp->next) {
19278  if (!tmp->destroy && tmp->span != y) {
19279  tmp->manages_span_alarms = 1;
19280  y = tmp->span;
19281  } else {
19282  tmp->manages_span_alarms = 0;
19283  }
19284  }
19285 
19286  /*< \todo why check for the pseudo in the per-channel section.
19287  * Any actual use for manual setup of the pseudo channel? */
19288  if (!has_pseudo && reload != 1 && !(options & PROC_DAHDI_OPT_NOCHAN)) {
19289  /* use the default configuration for a channel, so
19290  that any settings from real configured channels
19291  don't "leak" into the pseudo channel config
19292  */
19294 
19295  if (conf.chan.cc_params) {
19296  tmp = mkintf(CHAN_PSEUDO, &conf, reload);
19297  } else {
19298  tmp = NULL;
19299  }
19300  if (tmp) {
19301  ast_verb(3, "Automatically generated pseudo channel\n");
19302  has_pseudo = 1;
19303  } else {
19304  ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
19305  }
19307  }
19308 
19309  /* Since named callgroup and named pickup group are ref'd to dahdi_pvt at this point, unref container in confp's pvt. */
19312 
19313  return 0;
19314 }
int outsigmod
Definition: chan_dahdi.h:149
struct ast_variable * next
struct ringContextData ringContext[3]
Definition: chan_dahdi.h:71
int matchdigit_timeout
Time (ms) to wait, in case of ambiguous match (in an analog phone)
Definition: chan_dahdi.h:635
char description[32]
A description for the channel configuration.
Definition: chan_dahdi.h:449
int dtmfrelax
Definition: chan_dahdi.h:665
unsigned int priexclusive
TRUE if PRI B channels are always exclusively selected.
Definition: chan_dahdi.h:311
int faxbuf_no
Definition: chan_dahdi.h:141
#define DAHDI_OVERLAPDIAL_INCOMING
Definition: sig_pri.h:255
#define PROC_DAHDI_OPT_NOWARN
Definition: chan_dahdi.c:17863
unsigned int cancallforward
TRUE if support for call forwarding enabled. Dial *72 to enable call forwarding. Dial *73 to disable ...
Definition: chan_dahdi.h:214
struct ast_namedgroups * named_pickupgroups
Named pickup groups this belongs to.
Definition: chan_dahdi.h:532
int tonezone
Definition: chan_dahdi.h:166
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:202
#define REPORT_CHANNEL_ALARMS
Definition: chan_dahdi.c:615
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int firstdigit_timeout
Time (ms) to detect first digit (in an analog phone)
Definition: chan_dahdi.h:625
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1092
void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
Free memory from CCSS configuration params.
Definition: ccss.c:693
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#define SIG_FXOGS
Definition: chan_dahdi.h:735
static int report_alarms
Definition: chan_dahdi.c:617
char parkinglot[AST_MAX_EXTENSION]
Definition: chan_dahdi.h:471
int cid_signalling
Definition: chan_dahdi.h:541
unsigned int callwaitingcallerid
TRUE if send caller ID for Call Waiting.
Definition: chan_dahdi.h:207
static int dtmfcid_level
Definition: chan_dahdi.c:613
int interdigit_timeout
Time (ms) to detect following digits (in an analog phone)
Definition: chan_dahdi.h:630
static void parse_busy_pattern(struct ast_variable *v, struct ast_dsp_busy_pattern *busy_cadence)
Definition: chan_dahdi.c:17865
int cid_start
Definition: chan_dahdi.h:542
#define CID_SIG_SMDI
Definition: callerid.h:63
static struct dahdi_chan_conf dahdi_chan_conf_default(void)
Definition: chan_dahdi.c:869
static int parse_buffers_policy(const char *parse, int *num_buffers, int *policy)
Definition: chan_dahdi.c:6878
int ast_cc_is_config_param(const char *const name)
Is this a CCSS configuration parameter?
Definition: ccss.c:846
#define LOG_WARNING
Definition: logger.h:274
static int usedistinctiveringdetection
Definition: chan_dahdi.c:607
float txdrc
Definition: chan_dahdi.h:163
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
#define SIG_EM
Definition: chan_dahdi.h:722
#define LINKSET_FLAG_INITIALHWBLO
Definition: sig_ss7.h:69
static int tmp()
Definition: bt_open.c:389
#define NUM_CADENCE_MAX
Definition: chan_dahdi.c:563
#define LINKSET_FLAG_USEECHOCONTROL
Definition: sig_ss7.h:70
Structure for variables, used for configurations and for channel variables.
int buf_no
Definition: chan_dahdi.h:139
unsigned int dahditrcallerid
TRUE if we should use the callerid from incoming call on dahdi transfer.
Definition: chan_dahdi.h:365
unsigned int usefaxbuffers
Definition: chan_dahdi.h:252
unsigned int immediate
TRUE if the channel should be answered immediately without attempting to gather any digits...
Definition: chan_dahdi.h:284
#define CID_START_POLARITY
Definition: callerid.h:66
#define SIG_FXOKS
Definition: chan_dahdi.h:736
#define SIG_FEATB
Definition: chan_dahdi.h:726
float cid_rxgain
Amount of gain to increase during caller id.
Definition: chan_dahdi.h:157
#define ANALOG_MATCH_DIGIT_TIMEOUT
Default time (ms) to wait, in case of ambiguous match.
Definition: sig_analog.h:42
#define CHAN_PSEUDO
Definition: chan_dahdi.c:556
#define DAHDI_OVERLAPDIAL_OUTGOING
Definition: sig_pri.h:254
#define SIG_BRI_PTMP
Definition: chan_dahdi.h:747
struct ast_dsp_busy_pattern busy_cadence
Busy cadence pattern description.
Definition: chan_dahdi.h:599
#define CID_SIG_BELL
Definition: callerid.h:59
unsigned int transfertobusy
TRUE if allowed to flash-transfer to busy channels.
Definition: chan_dahdi.h:370
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define SIG_FEATDMF_TA
Definition: chan_dahdi.h:728
static struct test_val c
#define SIG_PRI_AOC_GRANT_S
Definition: sig_pri.h:53
#define CALLPROGRESS_PROGRESS
Definition: chan_dahdi.c:558
#define CID_START_POLARITY_IN
Definition: callerid.h:67
#define NULL
Definition: resample.c:96
unsigned int adsi
TRUE if ADSI (Analog Display Services Interface) available.
Definition: chan_dahdi.h:177
float txgain
Software Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:161
unsigned int hidecalleridname
TRUE if hide just the name not the number for legacy PBX use.
Definition: chan_dahdi.h:276
#define SS7_NAI_DYNAMIC
Definition: sig_ss7.h:66
#define ast_verb(level,...)
Definition: logger.h:463
#define DAHDI_OVERLAPDIAL_NONE
Definition: sig_pri.h:253
#define REPORT_SPAN_ALARMS
Definition: chan_dahdi.c:616
static char defaultozz[64]
Definition: chan_dahdi.c:597
static int mwilevel
Definition: chan_dahdi.c:612
#define SIG_SF
Definition: chan_dahdi.h:737
unsigned int pulse
TRUE if we will pulse dial.
Definition: chan_dahdi.h:316
#define ast_strlen_zero(foo)
Definition: strings.h:52
ast_group_t pickupgroup
Bitmapped pickup groups this belongs to.
Definition: chan_dahdi.h:522
All configuration options for statsd client.
Definition: res_statsd.c:95
char cid_name[AST_MAX_EXTENSION]
Caller ID name from an incoming call.
Definition: chan_dahdi.h:488
#define DAHDI_CHAN_MAPPING_PHYSICAL
Definition: sig_pri.h:249
unsigned int hwtxgain_enabled
TRUE if hardware Tx gain set by Asterisk.
Definition: chan_dahdi.h:422
struct dahdi_params timing
Definition: chan_dahdi.c:844
static int mwisend_rpas
Definition: chan_dahdi.c:602
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
Definition: channel.c:4405
#define SIG_EMWINK
Definition: chan_dahdi.h:723
static char progzone[10]
Definition: chan_dahdi.c:605
#define CALLPROGRESS_FAX_OUTGOING
Definition: chan_dahdi.c:559
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:183
#define DSP_DIGITMODE_RELAXDTMF
Definition: dsp.h:37
#define SIG_FGC_CAMAMF
Definition: chan_dahdi.h:730
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
char smdi_port[SMDI_MAX_FILENAME_LEN]
The serial port to listen for SMDI data on.
Definition: chan_dahdi.c:853
unsigned int hanguponpolarityswitch
TRUE if the call will be considered "hung up" on a polarity reversal.
Definition: chan_dahdi.h:261
static int user_has_defined_cadences
Definition: chan_dahdi.c:565
unsigned int callreturn
TRUE if call return is enabled. (*69, if your dialplan doesn&#39;t catch this first)
Definition: chan_dahdi.h:195
unsigned int transfer
TRUE if call transfer is enabled.
Definition: chan_dahdi.h:339
#define SIG_BRI
Definition: chan_dahdi.h:746
struct ast_cc_config_params * cc_params
Definition: chan_dahdi.h:710
int amaflags
Definition: chan_dahdi.h:646
char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Voice mailbox location.
Definition: chan_dahdi.h:654
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
#define SIG_FEATD
Definition: chan_dahdi.h:724
int echotraining
Echo training time. 0 = disabled.
Definition: chan_dahdi.h:587
#define LINKSET_FLAG_EXPLICITACM
Definition: sig_ss7.h:68
#define AST_MAX_EXTENSION
Definition: channel.h:135
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:580
static int ringt_base
Configured ring timeout base.
Definition: chan_dahdi.c:690
float rxdrc
Definition: chan_dahdi.h:164
char contextData[AST_MAX_CONTEXT]
Definition: chan_dahdi.h:67
int ring[3]
Definition: chan_dahdi.h:63
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:804
unsigned int busydetect
TRUE if busy detection is enabled. (Listens for the beep-beep busy pattern.)
Definition: chan_dahdi.h:189
unsigned int mwimonitor_fsk
TRUE if the FXO port monitors for fsk type MWI indications from the other end.
Definition: chan_dahdi.h:380
#define ast_variable_new(name, value, filename)
ast_group_t ast_get_group(const char *s)
Definition: channel.c:7718
unsigned int use_callingpres
TRUE if we will use the calling presentation setting from the Asterisk channel for outgoing calls...
Definition: chan_dahdi.h:354
char cid_tag[AST_MAX_EXTENSION]
Caller ID tag from incoming call.
Definition: chan_dahdi.h:484
#define SIG_PRI
Definition: chan_dahdi.h:745
unsigned int use_smdi
TRUE if SMDI (Simplified Message Desk Interface) is enabled.
Definition: chan_dahdi.h:432
#define DEFAULT_DIALTONE_DETECT_TIMEOUT
Definition: chan_dahdi.c:684
#define SIG_SS7
Definition: chan_dahdi.h:750
#define SIG_E911
Definition: chan_dahdi.h:727
static int numbufs
Definition: chan_dahdi.c:610
static int reload(void)
Definition: chan_dahdi.c:19898
#define CID_SIG_V23_JP
Definition: callerid.h:62
int busycount
Number of times to see "busy" tone before hanging up.
Definition: chan_dahdi.h:594
struct ast_namedgroups * ast_get_namedgroups(const char *s)
Create an ast_namedgroups set with group names from comma separated string.
Definition: channel.c:7775
#define LOG_ERROR
Definition: logger.h:285
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
#define PROC_DAHDI_OPT_NOCHAN
Definition: chan_dahdi.c:17861
char mohinterpret[MAX_MUSICCLASS]
The configured music-on-hold class to use for calls.
Definition: chan_dahdi.h:465
char cid_num[AST_MAX_EXTENSION]
Caller ID number from an incoming call.
Definition: chan_dahdi.h:479
#define DAHDI_OVERLAPDIAL_BOTH
Definition: sig_pri.h:256
unsigned int use_callerid
TRUE if caller ID is used on this channel.
Definition: chan_dahdi.h:347
int errno
static int has_pseudo
Definition: chan_dahdi.c:567
#define CID_SIG_DTMF
Definition: callerid.h:61
static void process_echocancel(struct dahdi_chan_conf *confp, const char *data, unsigned int line)
Definition: chan_dahdi.c:17728
#define SIG_FXSGS
Definition: chan_dahdi.h:732
#define READ_SIZE
Definition: chan_dahdi.c:673
#define LOG_NOTICE
Definition: logger.h:263
char * strcasestr(const char *, const char *)
static struct ast_jb_conf global_jbconf
Definition: chan_dahdi.c:505
unsigned int faxdetect_timeout
The number of seconds into call to disable fax detection. (0 = disabled)
Definition: chan_dahdi.h:620
unsigned int restrictcid
TRUE if caller ID is restricted.
Definition: chan_dahdi.h:325
char context[AST_MAX_CONTEXT]
The configured context for incoming calls.
Definition: chan_dahdi.h:444
Channel configuration from chan_dahdi.conf . This struct is used for parsing the [channels] section o...
Definition: chan_dahdi.c:831
unsigned int threewaycalling
TRUE if three way calling is enabled.
Definition: chan_dahdi.h:330
#define SIG_SFWINK
Definition: chan_dahdi.h:738
int stripmsd
Number of most significant digits/characters to strip from the dialed number.
Definition: chan_dahdi.h:568
struct ast_namedgroups * named_callgroups
Named call groups this belongs to.
Definition: chan_dahdi.h:527
#define SIG_FGC_CAMA
Definition: chan_dahdi.h:729
#define SIG_SF_FEATB
Definition: chan_dahdi.h:741
#define SIG_MFCR2
Definition: chan_dahdi.h:753
int buf_policy
Definition: chan_dahdi.h:140
#define SIG_FXSKS
Definition: chan_dahdi.h:733
#define CID_START_RING
Definition: callerid.h:65
unsigned int mwimonitor_neon
TRUE if the FXO port monitors for neon type MWI indications from the other end.
Definition: chan_dahdi.h:375
#define ANALOG_FIRST_DIGIT_TIMEOUT
Default time (ms) to detect first digit.
Definition: sig_analog.h:38
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX]
Definition: chan_dahdi.c:569
int waitfordialtone
Number of milliseconds to wait for dialtone.
Definition: chan_dahdi.h:609
#define CALLPROGRESS_FAX_INCOMING
Definition: chan_dahdi.c:560
float hwtxgain
Hardware Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:155
char * strsep(char **str, const char *delims)
static int distinctiveringaftercid
Definition: chan_dahdi.c:608
struct dahdi_distRings drings
Distinctive Ring data.
Definition: chan_dahdi.h:438
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static struct dahdi_pvt * iflist
Definition: chan_dahdi.c:801
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: main/utils.c:1968
int ignore_failed_channels
Definition: chan_dahdi.c:847
struct dahdi_pvt chan
Definition: chan_dahdi.c:832
#define SIG_FXSLS
Definition: chan_dahdi.h:731
struct ast_variable * vars
Channel variable list with associated values to set when a channel is created.
Definition: chan_dahdi.h:537
unsigned int priindication_oob
TRUE if PRI congestion/busy indications are sent out-of-band.
Definition: chan_dahdi.h:306
#define ANALOG_INTER_DIGIT_TIMEOUT
Default time (ms) to detect following digits.
Definition: sig_analog.h:40
unsigned int hidecallerid
TRUE if the outgoing caller ID is blocked/hidden.
Definition: chan_dahdi.h:270
int faxbuf_policy
Definition: chan_dahdi.h:142
unsigned int echocanbridged
TRUE if echo cancellation enabled when bridged.
Definition: chan_dahdi.h:246
int polarityonanswerdelay
Minimal time period (ms) between the answer polarity switch and hangup polarity switch.
Definition: chan_dahdi.h:672
float rxgain
Software Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:159
#define DAHDI_CHAN_MAPPING_LOGICAL
Definition: sig_pri.h:250
#define NUM_SPANS
Definition: chan_dahdi.c:553
#define SIG_PRI_AOC_GRANT_E
Definition: sig_pri.h:55
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
Definition: channel.c:7832
static struct test_options options
static struct dahdi_pvt * mkintf(int channel, const struct dahdi_chan_conf *conf, int reloading)
Definition: chan_dahdi.c:12095
static char defaultcic[64]
Definition: chan_dahdi.c:596
#define LINKSET_FLAG_DEFAULTECHOCONTROL
Definition: sig_ss7.h:71
#define SIG_FXOLS
Definition: chan_dahdi.h:734
int radio
Nonzero if the signaling type is sent over a radio.
Definition: chan_dahdi.h:148
#define CID_START_DTMF_NOALERT
Definition: callerid.h:68
#define SIG_FEATDMF
Definition: chan_dahdi.h:725
static struct ast_timer * timer
Definition: chan_iax2.c:360
static int num_cadence
Definition: chan_dahdi.c:564
int callprogress
Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
Definition: chan_dahdi.h:604
float hwrxgain
Hardware Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:153
char language[MAX_LANGUAGE]
Language configured for calls.
Definition: chan_dahdi.h:460
unsigned int hwrxgain_enabled
TRUE if hardware Rx gain set by Asterisk.
Definition: chan_dahdi.h:420
static int build_channels(struct dahdi_chan_conf *conf, const char *value, int reload, int lineno)
Definition: chan_dahdi.c:17667
ast_group_t group
Bitmapped groups this belongs to.
Definition: chan_dahdi.h:505
int dialtone_detect
Number of frames to watch for dialtone in incoming calls.
Definition: chan_dahdi.h:614
#define SIG_PRI_AOC_GRANT_D
Definition: sig_pri.h:54
static char mwimonitornotify[PATH_MAX]
Definition: chan_dahdi.c:600
int sendcalleridafter
Send caller ID on FXS after this many rings. Set to 1 for US.
Definition: chan_dahdi.h:679
ast_group_t callgroup
Bitmapped call groups this belongs to.
Definition: chan_dahdi.h:517
#define LINKSET_FLAG_AUTOACM
Definition: sig_ss7.h:72
unsigned int canpark
TRUE if support for call parking is enabled.
Definition: chan_dahdi.h:219
#define SIG_EM_E1
Definition: chan_dahdi.h:742
struct distRingData ringnum[3]
Definition: chan_dahdi.h:70
char mohsuggest[MAX_MUSICCLASS]
Suggested music-on-hold class for peer channel to use for calls.
Definition: chan_dahdi.h:470
#define CALLPROGRESS_FAX
Definition: chan_dahdi.c:561
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_dahdi.h:645
#define CID_SIG_V23
Definition: callerid.h:60
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:386

◆ process_echocancel()

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

Definition at line 17728 of file chan_dahdi.c.

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

Referenced by process_dahdi().

17729 {
17730  char *parse = ast_strdupa(data);
17731  char *params[DAHDI_MAX_ECHOCANPARAMS + 1];
17732  unsigned int param_count;
17733  unsigned int x;
17734 
17735  if (!(param_count = ast_app_separate_args(parse, ',', params, ARRAY_LEN(params))))
17736  return;
17737 
17738  memset(&confp->chan.echocancel, 0, sizeof(confp->chan.echocancel));
17739 
17740  /* first parameter is tap length, process it here */
17741 
17742  x = ast_strlen_zero(params[0]) ? 0 : atoi(params[0]);
17743 
17744  if ((x == 32) || (x == 64) || (x == 128) || (x == 256) || (x == 512) || (x == 1024))
17745  confp->chan.echocancel.head.tap_length = x;
17746  else if ((confp->chan.echocancel.head.tap_length = ast_true(params[0])))
17747  confp->chan.echocancel.head.tap_length = 128;
17748 
17749  /* now process any remaining parameters */
17750 
17751  for (x = 1; x < param_count; x++) {
17752  struct {
17753  char *name;
17754  char *value;
17755  } param;
17756 
17757  if (ast_app_separate_args(params[x], '=', (char **) &param, 2) < 1) {
17758  ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %u: '%s'\n", line, params[x]);
17759  continue;
17760  }
17761 
17762  if (ast_strlen_zero(param.name) || (strlen(param.name) > sizeof(confp->chan.echocancel.params[0].name)-1)) {
17763  ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %u: '%s'\n", line, param.name);
17764  continue;
17765  }
17766 
17767  strcpy(confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].name, param.name);
17768 
17769  if (param.value) {
17770  if (sscanf(param.value, "%30d", &confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].value) != 1) {
17771  ast_log(LOG_WARNING, "Invalid echocancel parameter value supplied at line %u: '%s'\n", line, param.value);
17772  continue;
17773  }
17774  }
17775  confp->chan.echocancel.head.param_count++;
17776  }
17777 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:274
char * name
Definition: chan_dahdi.c:4361
int value
Definition: syslog.c:37
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
struct dahdi_pvt::@110 echocancel
Echo cancel parameters.
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
struct dahdi_echocanparam params[DAHDI_MAX_ECHOCANPARAMS]
Definition: chan_dahdi.h:581
struct dahdi_echocanparams head
Definition: chan_dahdi.h:580
struct dahdi_pvt chan
Definition: chan_dahdi.c:832
#define ast_app_separate_args(a, b, c, d)

◆ publish_channel_alarm()

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

Definition at line 7345 of file chan_dahdi.c.

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

7346 {
7347  RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
7348  RAII_VAR(struct ast_str *, dahdi_chan, ast_str_create(32), ast_free);
7349  if (!dahdi_chan) {
7350  return;
7351  }
7352 
7353  ast_str_set(&dahdi_chan, 0, "%d", channel);
7354  body = ast_json_pack("{s: s, s: s}",
7355  "DAHDIChannel", ast_str_buffer(dahdi_chan),
7356  "Alarm", alarm_txt);
7357  if (!body) {
7358  return;
7359  }
7360 
7362 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Definition: muted.c:95
#define NULL
Definition: resample.c:96
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:1065
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#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:911
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
Abstract JSON element (object, array, string, int, ...).
void ast_manager_publish_event(const char *type, int class_type, struct ast_json *obj)
Publish an event to AMI.
Definition: manager.c:1903
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ publish_channel_alarm_clear()

static void publish_channel_alarm_clear ( int  channel)
static

Definition at line 3506 of file chan_dahdi.c.

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

Referenced by handle_clear_alarms().

3507 {
3508  RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
3509  RAII_VAR(struct ast_str *, dahdi_chan, ast_str_create(32), ast_free);
3510  if (!dahdi_chan) {
3511  return;
3512  }
3513 
3514  ast_str_set(&dahdi_chan, 0, "%d", channel);
3515  ast_log(LOG_NOTICE, "Alarm cleared on channel DAHDI/%d\n", channel);
3516  body = ast_json_pack("{s: s}", "DAHDIChannel", ast_str_buffer(dahdi_chan));
3517  if (!body) {
3518  return;
3519  }
3520 
3521  ast_manager_publish_event("AlarmClear", EVENT_FLAG_SYSTEM, body);
3522 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Definition: muted.c:95
#define NULL
Definition: resample.c:96
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:1065
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_log
Definition: astobj2.c:42
#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:911
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define LOG_NOTICE
Definition: logger.h:263
#define ast_free(a)
Definition: astmm.h:182
Abstract JSON element (object, array, string, int, ...).
void ast_manager_publish_event(const char *type, int class_type, struct ast_json *obj)
Publish an event to AMI.
Definition: manager.c:1903
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

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

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

1773 {
1774  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
1775 
1776  ast_assert(dahdi_channel != NULL);
1777 
1778  blob = ast_json_pack("{s: I, s: i, s: s}",
1779  "group", (ast_json_int_t)group,
1780  "span", span,
1781  "channel", dahdi_channel);
1782  if (!blob) {
1783  return;
1784  }
1785 
1786  ast_channel_lock(chan);
1787  ast_channel_publish_blob(chan, dahdichannel_type(), blob);
1788  ast_channel_unlock(chan);
1789 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
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:695
#define NULL
Definition: resample.c:96
#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:911
#define ast_channel_unlock(chan)
Definition: channel.h:2946
Abstract JSON element (object, array, string, int, ...).
void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message.

◆ publish_dnd_state()

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

Definition at line 9437 of file chan_dahdi.c.

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

9438 {
9439  RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
9440  RAII_VAR(struct ast_str *, dahdichan, ast_str_create(32), ast_free);
9441  if (!dahdichan) {
9442  return;
9443  }
9444 
9445  ast_str_set(&dahdichan, 0, "%d", channel);
9446 
9447  body = ast_json_pack("{s: s, s: s}",
9448  "DAHDIChannel", ast_str_buffer(dahdichan),
9449  "Status", status);
9450  if (!body) {
9451  return;
9452  }
9453 
9454  ast_manager_publish_event("DNDState", EVENT_FLAG_SYSTEM, body);
9455 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Definition: muted.c:95
#define NULL
Definition: resample.c:96
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:1065
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#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:911
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
Abstract JSON element (object, array, string, int, ...).
jack_status_t status
Definition: app_jack.c:146
void ast_manager_publish_event(const char *type, int class_type, struct ast_json *obj)
Publish an event to AMI.
Definition: manager.c:1903
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ publish_span_alarm()

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

Definition at line 7331 of file chan_dahdi.c.

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

Referenced by handle_alarms().

7332 {
7333  RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
7334 
7335  body = ast_json_pack("{s: i, s: s}",
7336  "Span", span,
7337  "Alarm", alarm_txt);
7338  if (!body) {
7339  return;
7340  }
7341 
7342  ast_manager_publish_event("SpanAlarm", EVENT_FLAG_SYSTEM, body);
7343 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define NULL
Definition: resample.c:96
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#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:911
Abstract JSON element (object, array, string, int, ...).
void ast_manager_publish_event(const char *type, int class_type, struct ast_json *obj)
Publish an event to AMI.
Definition: manager.c:1903

◆ publish_span_alarm_clear()

static void publish_span_alarm_clear ( int  span)
static

Definition at line 3524 of file chan_dahdi.c.

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

Referenced by handle_clear_alarms().

3525 {
3526  RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
3527 
3528  ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", span);
3529  body = ast_json_pack("{s: i}", "Span", span);
3530  if (!body) {
3531  return;
3532  }
3533 
3534  ast_manager_publish_event("SpanAlarmClear", EVENT_FLAG_SYSTEM, body);
3535 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define NULL
Definition: resample.c:96
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_log
Definition: astobj2.c:42
#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:911
#define LOG_NOTICE
Definition: logger.h:263
Abstract JSON element (object, array, string, int, ...).
void ast_manager_publish_event(const char *type, int class_type, struct ast_json *obj)
Publish an event to AMI.
Definition: manager.c:1903

◆ release_doomed_pris()

static void release_doomed_pris ( void  )
static

Definition at line 1156 of file chan_dahdi.c.

References ast_calloc, ast_debug, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, LOG_WARNING, and sig_pri_span::span.

Referenced by do_monitor().

1157 {
1158 #ifdef HAVE_PRI
1159  struct doomed_pri *entry;
1160 
1161  AST_LIST_LOCK(&doomed_pris);
1162  while ((entry = AST_LIST_REMOVE_HEAD(&doomed_pris, list))) {
1163  /* The span destruction must be done with this lock not held */
1164  AST_LIST_UNLOCK(&doomed_pris);
1165  ast_debug(4, "Destroying span %d from doomed queue.\n",
1166  entry->pri->span);
1167  pri_destroy_span(entry->pri);
1168  ast_free(entry);
1169  AST_LIST_LOCK(&doomed_pris);
1170  }
1171  AST_LIST_UNLOCK(&doomed_pris);
1172 #endif
1173 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_free(a)
Definition: astmm.h:182
Definition: search.h:40

◆ reload()

static int reload ( void  )
static

Definition at line 19898 of file chan_dahdi.c.

References ast_log, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CHANNEL_DRIVER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, load_module(), LOG_WARNING, setup_dahdi(), tdesc, and unload_module().

Referenced by dahdi_destroy_channel_range().

19899 {
19900  int res = 0;
19901 
19902  res = setup_dahdi(1);
19903  if (res) {
19904  ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n");
19905  return -1;
19906  }
19907  return 0;
19908 }
#define LOG_WARNING
Definition: logger.h:274
static int setup_dahdi(int reload)
Definition: chan_dahdi.c:19642
#define ast_log
Definition: astobj2.c:42

◆ reset_conf()

static int reset_conf ( struct dahdi_pvt p)
static

Definition at line 4569 of file chan_dahdi.c.

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

Referenced by dahdi_hangup(), my_all_subchannels_hungup(), and my_wink().

4570 {
4571  p->confno = -1;
4572  memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
4573  if (p->subs[SUB_REAL].dfd > -1) {
4574  struct dahdi_confinfo zi;
4575 
4576  memset(&zi, 0, sizeof(zi));
4577  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi))
4578  ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno));
4579  }
4580  return 0;
4581 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
int confno
Definition: chan_dahdi.h:510
int channel
Definition: chan_dahdi.h:538
struct dahdi_confinfo curconf
Definition: chan_dahdi.h:92

◆ restart_monitor()

static int restart_monitor ( void  )
static

Definition at line 11770 of file chan_dahdi.c.

References ast_calloc, ast_config_AST_LOG_DIR, ast_debug, AST_LIST_EMPTY, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_MOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_strlen_zero, channels, do_monitor(), errno, LOG_ERROR, LOG_WARNING, monitor_thread, monlock, NULL, NUM_SPANS, sig_pri_span::pvts, SIG_PRI_NUM_DCHANS, dahdi_pvt::span, tmp(), and sig_pri_span::trunkgroup.

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

11771 {
11772  /* If we're supposed to be stopped -- stay stopped */
11774  return 0;
11776  if (monitor_thread == pthread_self()) {
11778  ast_log(LOG_WARNING, "Cannot kill myself\n");
11779  return -1;
11780  }
11782  /* Wake up the thread */
11783  pthread_kill(monitor_thread, SIGURG);
11784  } else {
11785  /* Start a new monitor */
11788  ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
11789  return -1;
11790  }
11791  }
11793  return 0;
11794 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
static ast_mutex_t monlock
Protect the monitoring thread, so only one process can kill or start it, and not when it&#39;s doing some...
Definition: chan_dahdi.c:636
#define ast_log
Definition: astobj2.c:42
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:640
#define AST_PTHREADT_NULL
Definition: lock.h:66
static void * do_monitor(void *data)
Definition: chan_dahdi.c:11482
#define LOG_ERROR
Definition: logger.h:285
#define AST_PTHREADT_STOP
Definition: lock.h:67
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ restore_conference()

static int restore_conference ( struct dahdi_pvt p)
static

Definition at line 5002 of file chan_dahdi.c.

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

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

5003 {
5004  int res;
5005  if (p->saveconf.confmode) {
5006  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf);
5007  p->saveconf.confmode = 0;
5008  if (res) {
5009  ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
5010  return -1;
5011  }
5012  ast_debug(1, "Restored conferencing\n");
5013  }
5014  return 0;
5015 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct dahdi_confinfo saveconf
Definition: chan_dahdi.h:132
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57

◆ restore_gains()

static int restore_gains ( struct dahdi_pvt p)
static

Definition at line 4909 of file chan_dahdi.c.

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

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

4910 {
4911  int res;
4912 
4913  res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
4914  if (res) {
4915  ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
4916  return -1;
4917  }
4918 
4919  return 0;
4920 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
float txdrc
Definition: chan_dahdi.h:163
int law
Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW.
Definition: chan_dahdi.h:509
float txgain
Software Tx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:161
#define ast_log
Definition: astobj2.c:42
float rxdrc
Definition: chan_dahdi.h:164
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law)
Definition: chan_dahdi.c:4890
float rxgain
Software Rx gain set by chan_dahdi.conf.
Definition: chan_dahdi.h:159

◆ revert_fax_buffers()

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

Definition at line 5970 of file chan_dahdi.c.

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

Referenced by dahdi_hangup().

5971 {
5972  if (p->bufferoverrideinuse) {
5973  /* faxbuffers are in use, revert them */
5974  struct dahdi_bufferinfo bi = {
5975  .txbufpolicy = p->buf_policy,
5976  .rxbufpolicy = p->buf_policy,
5977  .bufsize = p->bufsize,
5978  .numbufs = p->buf_no
5979  };
5980  int bpres;
5981 
5982  if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
5983  ast_log(LOG_WARNING, "Channel '%s' unable to revert buffer policy: %s\n", ast_channel_name(ast), strerror(errno));
5984  }
5985  p->bufferoverrideinuse = 0;
5986  return bpres;
5987  }
5988 
5989  return -1;
5990 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
int buf_no
Definition: chan_dahdi.h:139
int bufsize
Definition: chan_dahdi.h:138
unsigned int bufferoverrideinuse
Definition: chan_dahdi.h:254
#define ast_log
Definition: astobj2.c:42
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
int buf_policy
Definition: chan_dahdi.h:140
const char * ast_channel_name(const struct ast_channel *chan)

◆ save_conference()

static int save_conference ( struct dahdi_pvt p)
static

Definition at line 4976 of file chan_dahdi.c.

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

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

4977 {
4978  struct dahdi_confinfo c;
4979  int res;
4980  if (p->saveconf.confmode) {
4981  ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
4982  return -1;
4983  }
4984  p->saveconf.chan = 0;
4985  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf);
4986  if (res) {
4987  ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
4988  p->saveconf.confmode = 0;
4989  return -1;
4990  }
4991  memset(&c, 0, sizeof(c));
4992  c.confmode = DAHDI_CONF_NORMAL;
4993  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c);
4994  if (res) {
4995  ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
4996  return -1;
4997  }
4998  ast_debug(1, "Disabled conferencing\n");
4999  return 0;
5000 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
static struct test_val c
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct dahdi_confinfo saveconf
Definition: chan_dahdi.h:132
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57

◆ send_callerid()

static int send_callerid ( struct dahdi_pvt p)
static

Definition at line 5051 of file chan_dahdi.c.

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

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

5052 {
5053  /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
5054  int res;
5055  /* Take out of linear mode if necessary */
5056  if (p->subs[SUB_REAL].linear) {
5057  p->subs[SUB_REAL].linear = 0;
5058  dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
5059  }
5060  while (p->cidpos < p->cidlen) {
5061  res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
5062  ast_debug(4, "writing callerid at pos %d of %d, res = %d\n", p->cidpos, p->cidlen, res);
5063  if (res < 0) {
5064  if (errno == EAGAIN)
5065  return 0;
5066  else {
5067  ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
5068  return -1;
5069  }
5070  }
5071  if (!res)
5072  return 0;
5073  p->cidpos += res;
5074  }
5076  ast_free(p->cidspill);
5077  p->cidspill = NULL;
5078  if (p->callwaitcas) {
5079  /* Wait for CID/CW to expire */
5082  } else
5083  restore_conference(p);
5084  return 0;
5085 }
int cidpos
Position in the cidspill buffer to send out next.
Definition: chan_dahdi.h:552
#define CIDCW_EXPIRE_SAMPLES
Definition: chan_dahdi.c:681
int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: chan_dahdi.h:575
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define CALLWAITING_SUPPRESS_SAMPLES
Definition: chan_dahdi.c:680
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int cidlen
Length of the cidspill buffer containing samples.
Definition: chan_dahdi.h:554
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
unsigned int linear
Definition: chan_dahdi.h:90
int errno
#define SUB_REAL
Definition: chan_dahdi.h:57
static int restore_conference(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5002
#define ast_free(a)
Definition: astmm.h:182
static int dahdi_setlinear(int dfd, int linear)
Definition: chan_dahdi.c:4161
int cidcwexpire
Definition: chan_dahdi.h:547
int cid_suppress_expire
Definition: chan_dahdi.h:548

◆ send_cwcidspill()

static int send_cwcidspill ( struct dahdi_pvt p)
static

Definition at line 5017 of file chan_dahdi.c.

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

Referenced by dahdi_handle_dtmf().

5018 {
5019  p->callwaitcas = 0;
5020  p->cidcwexpire = 0;
5021  p->cid_suppress_expire = 0;
5022  if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
5023  return -1;
5025  /* Make sure we account for the end */
5026  p->cidlen += READ_SIZE * 4;
5027  p->cidpos = 0;
5028  send_callerid(p);
5029  ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
5030  return 0;
5031 }
int cidpos
Position in the cidspill buffer to send out next.
Definition: chan_dahdi.h:552
int callwaitcas
TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
Definition: chan_dahdi.h:575
char callwait_name[AST_MAX_EXTENSION]
Call waiting name.
Definition: chan_dahdi.h:496
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)&#39;s Caller*ID(tm) ...
Definition: callerid.c:1068
#define ast_verb(level,...)
Definition: logger.h:463
#define MAX_CALLERID_SIZE
Definition: callerid.h:50
int cidlen
Length of the cidspill buffer containing samples.
Definition: chan_dahdi.h:554
unsigned char * cidspill
Analog caller ID waveform sample buffer.
Definition: chan_dahdi.h:550
#define AST_LAW(p)
Definition: chan_dahdi.c:521
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define READ_SIZE
Definition: chan_dahdi.c:673
static int send_callerid(struct dahdi_pvt *p)
Definition: chan_dahdi.c:5051
int cidcwexpire
Definition: chan_dahdi.h:547
int cid_suppress_expire
Definition: chan_dahdi.h:548
char callwait_num[AST_MAX_EXTENSION]
Call waiting number.
Definition: chan_dahdi.h:494

◆ set_actual_gain()

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

Definition at line 4890 of file chan_dahdi.c.

References set_actual_rxgain(), and set_actual_txgain().

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

4891 {
4892  return set_actual_txgain(fd, txgain, txdrc, law) | set_actual_rxgain(fd, rxgain, rxdrc, law);
4893 }
static int set_actual_txgain(int fd, float gain, float drc, int law)
Definition: chan_dahdi.c:4856
static int set_actual_rxgain(int fd, float gain, float drc, int law)
Definition: chan_dahdi.c:4873

◆ set_actual_rxgain()

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

Definition at line 4873 of file chan_dahdi.c.

References ast_debug, errno, and fill_rxgain().

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

4874 {
4875  struct dahdi_gains g;
4876  int res;
4877 
4878  memset(&g, 0, sizeof(g));
4879  res = ioctl(fd, DAHDI_GETGAINS, &g);
4880  if (res) {
4881  ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
4882  return res;
4883  }
4884 
4885  fill_rxgain(&g, gain, drc, law);
4886 
4887  return ioctl(fd, DAHDI_SETGAINS, &g);
4888 }
static void fill_rxgain(struct dahdi_gains *g, float gain, float drc, int law)
Definition: chan_dahdi.c:4808
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int errno

◆ set_actual_txgain()

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

Definition at line 4856 of file chan_dahdi.c.

References ast_debug, errno, and fill_txgain().

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

4857 {
4858  struct dahdi_gains g;
4859  int res;
4860 
4861  memset(&g, 0, sizeof(g));
4862  res = ioctl(fd, DAHDI_GETGAINS, &g);
4863  if (res) {
4864  ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
4865  return res;
4866  }
4867 
4868  fill_txgain(&g, gain, drc, law);
4869 
4870  return ioctl(fd, DAHDI_SETGAINS, &g);
4871 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int errno
static void fill_txgain(struct dahdi_gains *g, float gain, float drc, int law)
Definition: chan_dahdi.c:4758

◆ set_hwgain()

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

Definition at line 4728 of file chan_dahdi.c.

Referenced by dahdi_set_hwgain(), and mkintf().

4729 {
4730  struct dahdi_hwgain hwgain;
4731 
4732  hwgain.newgain = gain * 10.0;
4733  hwgain.tx = tx_direction;
4734  return ioctl(fd, DAHDI_SET_HWGAIN, &hwgain) < 0;
4735 }

◆ setup_dahdi()

static int setup_dahdi ( int  reload)
static

Definition at line 19642 of file chan_dahdi.c.

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

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

19643 {
19644  int res;
19645  struct dahdi_chan_conf default_conf = dahdi_chan_conf_default();
19646  struct dahdi_chan_conf base_conf = dahdi_chan_conf_default();
19648 
19649  if (default_conf.chan.cc_params && base_conf.chan.cc_params && conf.chan.cc_params) {
19650  res = setup_dahdi_int(reload, &default_conf, &base_conf, &conf);
19651  } else {
19652  res = -1;
19653  }
19657 
19658  return res;
19659 }
void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
Free memory from CCSS configuration params.
Definition: ccss.c:693
static struct dahdi_chan_conf dahdi_chan_conf_default(void)
Definition: chan_dahdi.c:869
All configuration options for statsd client.
Definition: res_statsd.c:95
struct ast_cc_config_params * cc_params
Definition: chan_dahdi.h:710
static int reload(void)
Definition: chan_dahdi.c:19898
Channel configuration from chan_dahdi.conf . This struct is used for parsing the [channels] section o...
Definition: chan_dahdi.c:831
struct dahdi_pvt chan
Definition: chan_dahdi.c:832
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:19348

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

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(), global_jbconf, iflock, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mwimonitornotify, ast_variable::name, ast_variable::next, NULL, NUM_SPANS, PROC_DAHDI_OPT_NOCHAN, PROC_DAHDI_OPT_NOWARN, process_dahdi(), sig_pri_span::pvts, restart_monitor(), SIG_PRI_NUM_DCHANS, sig_pri_start_pri(), ss7_linkset(), and ast_variable::value.

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

19349 {
19350  struct ast_config *cfg;
19351  struct ast_config *ucfg;
19352  struct ast_variable *v;
19353  struct ast_flags config_flags = { reload == 1 ? CONFIG_FLAG_FILEUNCHANGED : 0 };
19354  const char *chans;
19355  const char *cat;
19356  int res;
19357 
19358 #ifdef HAVE_PRI
19359  char *c;
19360  int spanno;
19361  int i;
19362  int logicalspan;
19363  int trunkgroup;
19364  int dchannels[SIG_PRI_NUM_DCHANS];
19365 #endif
19366  int have_cfg_now;
19367  static int had_cfg_before = 1;/* So initial load will complain if we don't have cfg. */
19368 
19369  cfg = ast_config_load(config, config_flags);
19370  have_cfg_now = !!cfg;
19371  if (!cfg) {
19372  /* Error if we have no config file */
19373  if (had_cfg_before) {
19374  ast_log(LOG_ERROR, "Unable to load config %s\n", config);
19375  ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
19376  }
19377  cfg = ast_config_new();/* Dummy config */
19378  if (!cfg) {
19379  return 0;
19380  }
19381  ucfg = ast_config_load("users.conf", config_flags);
19382  if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
19383  ast_config_destroy(cfg);
19384  return 0;
19385  }
19386  if (ucfg == CONFIG_STATUS_FILEINVALID) {
19387  ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n");
19388  ast_config_destroy(cfg);
19389  return 0;
19390  }
19391  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
19392  ucfg = ast_config_load("users.conf", config_flags);
19393  if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
19394  return 0;
19395  }
19396  if (ucfg == CONFIG_STATUS_FILEINVALID) {
19397  ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n");
19398  return 0;
19399  }
19400  ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
19401  cfg = ast_config_load(config, config_flags);
19402  have_cfg_now = !!cfg;
19403  if (!cfg) {
19404  if (had_cfg_before) {
19405  /* We should have been able to load the config. */
19406  ast_log(LOG_ERROR, "Bad. Unable to load config %s\n", config);
19407  ast_config_destroy(ucfg);
19408  return 0;
19409  }
19410  cfg = ast_config_new();/* Dummy config */
19411  if (!cfg) {
19412  ast_config_destroy(ucfg);
19413  return 0;
19414  }
19415  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
19416  ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config);
19417  ast_config_destroy(ucfg);
19418  return 0;
19419  }
19420  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
19421  ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config);
19422  return 0;
19423  } else {
19424  ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
19425  ucfg = ast_config_load("users.conf", config_flags);
19426  if (ucfg == CONFIG_STATUS_FILEINVALID) {
19427  ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n");
19428  ast_config_destroy(cfg);
19429  return 0;
19430  }
19431  }
19432  had_cfg_before = have_cfg_now;
19433 
19434  /* It's a little silly to lock it, but we might as well just to be sure */
19436 #ifdef HAVE_PRI
19437  if (reload != 1) {
19438  /* Process trunkgroups first */
19439  v = ast_variable_browse(cfg, "trunkgroups");
19440  while (v) {
19441  if (!strcasecmp(v->name, "trunkgroup")) {
19442  trunkgroup = atoi(v->value);
19443  if (trunkgroup > 0) {
19444  if ((c = strchr(v->value, ','))) {
19445  i = 0;
19446  memset(dchannels, 0, sizeof(dchannels));
19447  while (c && (i < SIG_PRI_NUM_DCHANS)) {
19448  dchannels[i] = atoi(c + 1);
19449  if (dchannels[i] < 0) {
19450  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);
19451  } else
19452  i++;
19453  c = strchr(c + 1, ',');
19454  }
19455  if (i) {
19456  if (pri_create_trunkgroup(trunkgroup, dchannels)) {
19457  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);
19458  } else
19459  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");
19460  } else
19461  ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
19462  } else
19463  ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
19464  } else
19465  ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->lineno);
19466  } else if (!strcasecmp(v->name, "spanmap")) {
19467  spanno = atoi(v->value);
19468  if (spanno > 0) {
19469  if ((c = strchr(v->value, ','))) {
19470  trunkgroup = atoi(c + 1);
19471  if (trunkgroup > 0) {
19472  if ((c = strchr(c + 1, ',')))
19473  logicalspan = atoi(c + 1);
19474  else
19475  logicalspan = 0;
19476  if (logicalspan >= 0) {
19477  if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
19478  ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
19479  } else
19480  ast_verb(2, "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
19481  } else
19482  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);
19483  } else
19484  ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of chan_dahdi.conf\n", v->lineno);
19485  } else
19486  ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of chan_dahdi.conf\n", v->lineno);
19487  } else
19488  ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of chan_dahdi.conf\n", v->lineno);
19489  } else {
19490  ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
19491  }
19492  v = v->next;
19493  }
19494  }
19495 #endif
19496 
19497  /* Copy the default jb config over global_jbconf */
19498  memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf));
19499 
19500  mwimonitornotify[0] = '\0';
19501 
19502  v = ast_variable_browse(cfg, "channels");
19503  if ((res = process_dahdi(base_conf,
19504  "" /* Must be empty for the channels category. Silly voicemail mailbox. */,
19505  v, reload, 0))) {
19507  ast_config_destroy(cfg);
19508  if (ucfg) {
19509  ast_config_destroy(ucfg);
19510  }
19511  return res;
19512  }
19513 
19514  /* Now get configuration from all normal sections in chan_dahdi.conf: */
19515  for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
19516  /* [channels] and [trunkgroups] are used. Let's also reserve
19517  * [globals] and [general] for future use
19518  */
19519  if (!strcasecmp(cat, "general") ||
19520  !strcasecmp(cat, "trunkgroups") ||
19521  !strcasecmp(cat, "globals") ||
19522  !strcasecmp(cat, "channels")) {
19523  continue;
19524  }
19525 
19526  chans = ast_variable_retrieve(cfg, cat, "dahdichan");
19527  if (ast_strlen_zero(chans)) {
19528  /* Section is useless without a dahdichan value present. */
19529  continue;
19530  }
19531 
19532  /* Copy base_conf to conf. */
19533  deep_copy_dahdi_chan_conf(conf, base_conf);
19534 
19535  if ((res = process_dahdi(conf, cat, ast_variable_browse(cfg, cat), reload, PROC_DAHDI_OPT_NOCHAN))) {
19537  ast_config_destroy(cfg);
19538  if (ucfg) {
19539  ast_config_destroy(ucfg);
19540  }
19541  return res;
19542  }
19543  }
19544 
19545  ast_config_destroy(cfg);
19546 
19547  if (ucfg) {
19548  /* Reset base_conf, so things don't leak from chan_dahdi.conf */
19549  deep_copy_dahdi_chan_conf(base_conf, default_conf);
19550  process_dahdi(base_conf,
19551  "" /* Must be empty for the general category. Silly voicemail mailbox. */,
19552  ast_variable_browse(ucfg, "general"), 1, 0);
19553 
19554  for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
19555  if (!strcasecmp(cat, "general")) {
19556  continue;
19557  }
19558 
19559  chans = ast_variable_retrieve(ucfg, cat, "dahdichan");
19560  if (ast_strlen_zero(chans)) {
19561  /* Section is useless without a dahdichan value present. */
19562  continue;
19563  }
19564 
19565  /* Copy base_conf to conf. */
19566  deep_copy_dahdi_chan_conf(conf, base_conf);
19567 
19568  if ((res = process_dahdi(conf, cat, ast_variable_browse(ucfg, cat), reload, PROC_DAHDI_OPT_NOCHAN | PROC_DAHDI_OPT_NOWARN))) {
19569  ast_config_destroy(ucfg);
19571  return res;
19572  }
19573  }
19574  ast_config_destroy(ucfg);
19575  }
19577 
19578 #ifdef HAVE_PRI
19579  if (reload != 1) {
19580  int x;
19581  for (x = 0; x < NUM_SPANS; x++) {
19582  if (pris[x].pri.pvts[0] &&
19583  pris[x].pri.master == AST_PTHREADT_NULL) {
19584  prepare_pri(pris + x);
19585  if (sig_pri_start_pri(&pris[x].pri)) {
19586  ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
19587  return -1;
19588  } else
19589  ast_verb(2, "Starting D-Channel on span %d\n", x + 1);
19590  }
19591  }
19592  }
19593 #endif
19594 #if defined(HAVE_SS7)
19595  if (reload != 1) {
19596  int x;
19597  for (x = 0; x < NUM_SPANS; x++) {
19598  if (linksets[x].ss7.ss7) {
19599  if (ast_pthread_create(&linksets[x].ss7.master, NULL, ss7_linkset, &linksets[x].ss7)) {
19600  ast_log(LOG_ERROR, "Unable to start SS7 linkset on span %d\n", x + 1);
19601  return -1;
19602  } else
19603  ast_verb(2, "Starting SS7 linkset on span %d\n", x + 1);
19604  }
19605  }
19606  }
19607 #endif /* defined(HAVE_SS7) */
19608 #ifdef HAVE_OPENR2
19609  if (reload != 1) {
19610  struct r2link_entry *cur;
19611  int x = 0;
19612  AST_LIST_LOCK(&r2links);
19613  AST_LIST_TRAVERSE(&r2links, cur, list) {
19614  struct dahdi_mfcr2 *r2 = &cur->mfcr2;
19615  if (r2->r2master == AST_PTHREADT_NULL) {
19616  if (ast_pthread_create(&r2->r2master, NULL, mfcr2_monitor, r2)) {
19617  ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1);
19618  return -1;
19619  } else {
19620  ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1);
19621  }
19622  x++;
19623  }
19624  }
19625  AST_LIST_UNLOCK(&r2links);
19626  }
19627 #endif
19628  /* And start the monitor for the first time */
19629  restart_monitor();
19630  return 0;
19631 }
struct ast_variable * next
#define PROC_DAHDI_OPT_NOWARN
Definition: chan_dahdi.c:17863
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static struct ast_jb_conf default_jbconf
Definition: chan_dahdi.c:497
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define CONFIG_STATUS_FILEINVALID
Structure for variables, used for configurations and for channel variables.
#define ast_mutex_lock(a)
Definition: lock.h:187
static struct test_val c
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
static const char config[]
Definition: chan_dahdi.c:548
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int restart_monitor(void)
Definition: chan_dahdi.c:11770
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
#define AST_PTHREADT_NULL
Definition: lock.h:66
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt&#39;s)
Definition: chan_dahdi.c:625
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: extconf.c:3276
#define CONFIG_STATUS_FILEUNCHANGED
static int reload(void)
Definition: chan_dahdi.c:19898
#define LOG_ERROR
Definition: logger.h:285
#define PROC_DAHDI_OPT_NOCHAN
Definition: chan_dahdi.c:17861
static void deep_copy_dahdi_chan_conf(struct dahdi_chan_conf *dest, const struct dahdi_chan_conf *src)
Definition: chan_dahdi.c:19326
#define SIG_PRI_NUM_DCHANS
Definition: sig_pri.h:241
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static struct ast_jb_conf global_jbconf
Definition: chan_dahdi.c:505
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:559
int sig_pri_start_pri(struct sig_pri_span *pri)
Structure used to handle boolean flags.
Definition: utils.h:199
#define ast_clear_flag(p, flag)
Definition: utils.h:77
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
#define NUM_SPANS
Definition: chan_dahdi.c:553
static char mwimonitornotify[PATH_MAX]
Definition: chan_dahdi.c:600
void * ss7_linkset(void *data)
static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct ast_variable *v, int reload, int options)
Definition: chan_dahdi.c:17900
#define ast_mutex_unlock(a)
Definition: lock.h:188
static struct chans chans

◆ sigtype_to_signalling()

static int sigtype_to_signalling ( int  sigtype)
static

Definition at line 12076 of file chan_dahdi.c.

References sigtype.

Referenced by mkintf().

12077 {
12078  return sigtype;
12079 }
enum analog_sigtype sigtype
Definition: sig_analog.c:69

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL()

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( dahdichannel_type  ,
to_ami = dahdichannel_to_ami 
)

Referenced by dahdichannel_to_ami().

◆ swap_subs()

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

Definition at line 4058 of file chan_dahdi.c.

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

4059 {
4060  int tchan;
4061  int tinthreeway;
4062  struct ast_channel *towner;
4063 
4064  ast_debug(1, "Swapping %d and %d\n", a, b);
4065 
4066  tchan = p->subs[a].chan;
4067  towner = p->subs[a].owner;
4068  tinthreeway = p->subs[a].inthreeway;
4069 
4070  p->subs[a].chan = p->subs[b].chan;
4071  p->subs[a].owner = p->subs[b].owner;
4072  p->subs[a].inthreeway = p->subs[b].inthreeway;
4073 
4074  p->subs[b].chan = tchan;
4075  p->subs[b].owner = towner;
4076  p->subs[b].inthreeway = tinthreeway;
4077 
4078  if (p->subs[a].owner)
4079  ast_channel_set_fd(p->subs[a].owner, 0, p->subs[a].dfd);
4080  if (p->subs[b].owner)
4081  ast_channel_set_fd(p->subs[b].owner, 0, p->subs[b].dfd);
4082  wakeup_sub(p, a);
4083  wakeup_sub(p, b);
4084 }
Main Channel structure associated with a channel.
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
static void wakeup_sub(struct dahdi_pvt *p, int a)
Definition: chan_dahdi.c:3481
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_channel * owner
Definition: chan_dahdi.h:79
unsigned int inthreeway
Definition: chan_dahdi.h:91
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
static struct test_val b
static struct test_val a

◆ unalloc_sub()

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

Definition at line 4204 of file chan_dahdi.c.

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

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

4205 {
4206  if (!x) {
4207  ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
4208  return -1;
4209  }
4210  ast_debug(1, "Released sub %d of channel %d\n", x, p->channel);
4211  dahdi_close_sub(p, x);
4212  p->subs[x].linear = 0;
4213  p->subs[x].chan = 0;
4214  p->subs[x].owner = NULL;
4215  p->subs[x].inthreeway = 0;
4216  p->polarity = POLARITY_IDLE;
4217  memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
4218  return 0;
4219 }
#define POLARITY_IDLE
Definition: chan_dahdi.c:792
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
static void dahdi_close_sub(struct dahdi_pvt *chan_pvt, int sub_num)
Definition: chan_dahdi.c:4139
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int polarity
Current line interface polarity. POLARITY_IDLE, POLARITY_REV.
Definition: chan_dahdi.h:681
struct ast_channel * owner
Definition: chan_dahdi.h:79
unsigned int linear
Definition: chan_dahdi.h:90
unsigned int inthreeway
Definition: chan_dahdi.h:91
char x
Definition: extconf.c:81
int channel
Definition: chan_dahdi.h:538
struct dahdi_confinfo curconf
Definition: chan_dahdi.h:92

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 17651 of file chan_dahdi.c.

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

Referenced by reload().

17652 {
17653 #if defined(HAVE_PRI) || defined(HAVE_SS7)
17654  int y;
17655 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
17656 #ifdef HAVE_PRI
17657  for (y = 0; y < NUM_SPANS; y++)
17658  ast_mutex_destroy(&pris[y].pri.lock);
17659 #endif
17660 #if defined(HAVE_SS7)
17661  for (y = 0; y < NUM_SPANS; y++)
17662  ast_mutex_destroy(&linksets[y].ss7.lock);
17663 #endif /* defined(HAVE_SS7) */
17664  return __unload_module();
17665 }
static int __unload_module(void)
Definition: chan_dahdi.c:17540
#define NUM_SPANS
Definition: chan_dahdi.c:553
#define ast_mutex_destroy(a)
Definition: lock.h:186

◆ wakeup_sub()

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

Definition at line 3481 of file chan_dahdi.c.

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

Referenced by my_swap_subchannels(), my_wink(), and swap_subs().

3482 {
3483  dahdi_lock_sub_owner(p, a);
3484  if (p->subs[a].owner) {
3487  }
3488 }
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
struct ast_channel * owner
Definition: chan_dahdi.h:79
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_frame ast_null_frame
Definition: main/frame.c:79
static void dahdi_lock_sub_owner(struct dahdi_pvt *pvt, int sub_idx)
Definition: chan_dahdi.c:3465
static struct test_val a

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 19922 of file chan_dahdi.c.

◆ alarm

int alarm

Definition at line 4360 of file chan_dahdi.c.

Referenced by alarm2str(), and handle_clear_alarms().

◆ alarms

struct { ... } alarms[]

Referenced by alarm2str().

◆ analog_callbacks

struct analog_callback analog_callbacks

Global analog callbacks to the upper layer.

Definition at line 3355 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 588 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 19922 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 580 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 548 of file chan_dahdi.c.

Referenced by setup_dahdi_int().

◆ dahdi_cli

struct ast_cli_entry dahdi_cli[]
static

Definition at line 16220 of file chan_dahdi.c.

◆ dahdi_tech

struct ast_channel_tech dahdi_tech
static

Definition at line 1030 of file chan_dahdi.c.

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

◆ defaultcic

char defaultcic[64] = ""
static

Definition at line 596 of file chan_dahdi.c.

Referenced by process_dahdi().

◆ defaultozz

char defaultozz[64] = ""
static

Definition at line 597 of file chan_dahdi.c.

Referenced by process_dahdi().

◆ distinctiveringaftercid

int distinctiveringaftercid = 0
static

Definition at line 608 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 613 of file chan_dahdi.c.

Referenced by do_monitor(), and process_dahdi().

◆ events

const char* const events[]
static

Definition at line 4337 of file chan_dahdi.c.

Referenced by event2str().

◆ global_jbconf

struct ast_jb_conf global_jbconf
static

Definition at line 505 of file chan_dahdi.c.

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

◆ has_pseudo

int has_pseudo
static

Definition at line 567 of file chan_dahdi.c.

Referenced by build_channels(), and process_dahdi().

◆ ifcount

int ifcount = 0
static

Definition at line 628 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 802 of file chan_dahdi.c.

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

◆ iflist

struct dahdi_pvt* iflist = NULL
static

Main interface list start

Definition at line 801 of file chan_dahdi.c.

Referenced by dahdi_cc_callback(), dahdi_request(), destroy_all_channels(), and determine_starting_point().

◆ iflock

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

◆ lbostr

const char* const lbostr[]
static

Definition at line 484 of file chan_dahdi.c.

Referenced by 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 640 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 636 of file chan_dahdi.c.

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

◆ mwilevel

int mwilevel = 512
static

Definition at line 612 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 600 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 602 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 564 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 610 of file chan_dahdi.c.

Referenced by dahdi_chan_conf_default(), and process_dahdi().

◆ progzone

char progzone[10] = ""
static

Definition at line 605 of file chan_dahdi.c.

Referenced by dahdi_new(), and process_dahdi().

◆ report_alarms

int report_alarms = REPORT_CHANNEL_ALARMS
static

Definition at line 617 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 643 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 690 of file chan_dahdi.c.

Referenced by mkintf(), and process_dahdi().

◆ round_robin

struct dahdi_pvt* round_robin[32]
static

Round robin search locations.

Definition at line 3429 of file chan_dahdi.c.

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

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

◆ tdesc

const char tdesc[] = "DAHDI Telephony"
static

Definition at line 527 of file chan_dahdi.c.

Referenced by reload().

◆ usedistinctiveringdetection

int usedistinctiveringdetection = 0
static

Definition at line 607 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 565 of file chan_dahdi.c.

Referenced by process_dahdi().