57#if defined(__NetBSD__) || defined(__FreeBSD__)
60#include <sys/sysmacros.h>
76#error "Upgrade your libpri"
82#if !defined(LIBSS7_ABI_COMPATIBILITY)
83#error "Upgrade your libss7"
84#elif LIBSS7_ABI_COMPATIBILITY != 2
85#error "Your installed libss7 is not compatible"
89#if defined(HAVE_OPENR2)
91#define SIG_MFCR2_MAX_CHANNELS 672
733#define SMDI_MD_WAIT_TIMEOUT 1500
736"0 db (CSU)/0-133 feet (DSX-1)",
737"133-266 feet (DSX-1)",
738"266-399 feet (DSX-1)",
739"399-533 feet (DSX-1)",
740"533-655 feet (DSX-1)",
752 .resync_threshold = 1000,
770#define DEFAULT_CIDRINGS 1
772#define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? ast_format_alaw : ast_format_ulaw)
776#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))
779#define IS_FXO_SIG(p) (((p)->sig == SIG_FXOKS) || ((p)->sig == SIG_FXOLS) || ((p)->sig == SIG_FXOGS))
780#define CHAN_IS_FXO_SIG(sig) (sig == SIG_FXOKS || sig == SIG_FXOLS || sig == SIG_FXOGS)
782static const char tdesc[] =
"DAHDI Telephony"
783#if defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2)
785 #if defined(HAVE_PRI)
788 #if defined(HAVE_SS7)
789 #if defined(HAVE_PRI)
794 #if defined(HAVE_OPENR2)
795 #if defined(HAVE_PRI) || defined(HAVE_SS7)
803static const char config[] =
"chan_dahdi.conf";
806#define NUM_SPANS DAHDI_MAX_SPANS
811#define CHAN_PSEUDO -2
813#define CALLPROGRESS_PROGRESS 1
814#define CALLPROGRESS_FAX_OUTGOING 2
815#define CALLPROGRESS_FAX_INCOMING 4
816#define CALLPROGRESS_FAX (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
818#define NUM_CADENCE_MAX 25
825 { { 125, 125, 2000, 4000 } },
826 { { 250, 250, 500, 1000, 250, 250, 500, 4000 } },
827 { { 125, 125, 125, 125, 125, 4000 } },
828 { { 1000, 500, 2500, 5000 } },
845#define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
846 (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
848#define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) )
849#define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) )
856#ifndef HAVE_DAHDI_LINEREVERSE_VMWI
870#define REPORT_CHANNEL_ALARMS 1
871#define REPORT_SPAN_ALARMS 2
875static int pridebugfd = -1;
876static char pridebugfilename[1024] =
"";
910 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
919 i = DAHDI_IOMUX_SIGEVENT;
920 if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
922 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
930#define MASK_AVAIL (1 << 0)
931#define MASK_INUSE (1 << 1)
933#define CALLWAITING_SILENT_SAMPLES ((300 * 8) / READ_SIZE)
934#define CALLWAITING_REPEAT_SAMPLES ((10000 * 8) / READ_SIZE)
935#define CALLWAITING_SUPPRESS_SAMPLES ((100 * 8) / READ_SIZE)
936#define CIDCW_EXPIRE_SAMPLES ((500 * 8) / READ_SIZE)
937#define MIN_MS_SINCE_FLASH ((2000) )
938#define DEFAULT_RINGT ((8000 * 8) / READ_SIZE)
939#define DEFAULT_DIALTONE_DETECT_TIMEOUT ((10000 * 8) / READ_SIZE)
953static struct dahdi_ss7 linksets[
NUM_SPANS];
955static int cur_ss7type = -1;
956static int cur_slc = -1;
957static int cur_linkset = -1;
958static int cur_pointcode = -1;
959static int cur_cicbeginswith = -1;
960static int cur_adjpointcode = -1;
961static int cur_networkindicator = -1;
962static int cur_defaultdpc = -1;
966struct dahdi_mfcr2_conf {
967 openr2_variant_t variant;
969 int metering_pulse_timeout;
972#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
976#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
977 int dtmf_end_timeout;
979 signed int get_ani_first:2;
980#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
981 signed int skip_category_request:2;
983 unsigned int call_files:1;
984 unsigned int allow_collect_calls:1;
985 unsigned int charge_calls:1;
986 unsigned int accept_on_offer:1;
987 unsigned int forced_release:1;
988 unsigned int double_answer:1;
989 signed int immediate_accept:2;
990#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
991 signed int dtmf_dialing:2;
992 signed int dtmf_detection:2;
994 char logdir[OR2_MAX_PATH];
995 char r2proto_file[OR2_MAX_PATH];
996 openr2_log_level_t loglevel;
997 openr2_calling_party_category_t category;
1004 openr2_context_t *protocol_context;
1009 struct dahdi_mfcr2_conf
conf;
1012struct r2link_entry {
1013 struct dahdi_mfcr2 mfcr2;
1021static int r2links_count = 0;
1029 int mastertrunkgroup;
1036#if defined(HAVE_PRI_CCSS)
1038static const char dahdi_pri_cc_type[] =
"DAHDI/PRI";
1047#define POLARITY_IDLE 0
1048#define POLARITY_REV 1
1059#if defined(HAVE_PRI)
1068static struct dahdi_parms_pseudo {
1073} dahdi_pseudo_parms;
1089 struct dahdi_pri pri;
1092#if defined(HAVE_SS7)
1093 struct dahdi_ss7 ss7;
1097 struct dahdi_mfcr2_conf mfcr2;
1132 .nsf = PRI_NSF_NONE,
1133 .switchtype = PRI_SWITCH_NI2,
1134 .dialplan = PRI_UNKNOWN + 1,
1135 .localdialplan = PRI_NATIONAL_ISDN + 1,
1136 .nodetype = PRI_CPE,
1139#if defined(HAVE_PRI_CCSS)
1140 .cc_ptmp_recall_mode = 1,
1141 .cc_qsig_signaling_link_req = 1,
1142 .cc_qsig_signaling_link_rsp = 1,
1148 .internationalprefix =
"",
1149 .nationalprefix =
"",
1151 .privateprefix =
"",
1152 .unknownprefix =
"",
1154 .resetinterval = -1,
1157#if defined(HAVE_SS7)
1159 .called_nai = SS7_NAI_NATIONAL,
1160 .calling_nai = SS7_NAI_NATIONAL,
1161 .internationalprefix =
"",
1162 .nationalprefix =
"",
1163 .subscriberprefix =
"",
1164 .unknownprefix =
"",
1165 .networkroutedprefix =
""
1170 .variant = OR2_VAR_ITU,
1171 .mfback_timeout = -1,
1172 .metering_pulse_timeout = -1,
1175 .get_ani_first = -1,
1176#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
1177 .skip_category_request = -1,
1180 .allow_collect_calls = 0,
1182 .accept_on_offer = 1,
1183 .forced_release = 0,
1185 .immediate_accept = -1,
1186#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
1188 .dtmf_detection = -1,
1189 .dtmf_time_on = OR2_DEFAULT_DTMF_ON,
1190 .dtmf_time_off = OR2_DEFAULT_DTMF_OFF,
1192#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
1193 .dtmf_end_timeout = -1,
1197 .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
1198 .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
1202 .context =
"default",
1207 .mohinterpret =
"default",
1210 .transfertobusy = 1,
1213 .ani_info_digits = 2,
1214 .ani_wink_time = 1000,
1215 .ani_timeout = 10000,
1219 .dahditrcallerid = 0,
1228 .echocancel.head.tap_length = 1,
1236#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1239 .polarityonanswerdelay = 600,
1243 .buf_policy = DAHDI_POLICY_IMMEDIATE,
1262 .ignore_failed_channels = 1,
1263 .smdi_port =
"/dev/ttyS0",
1272 const char *
data,
int *cause);
1293 .description =
tdesc,
1314#define GET_CHANNEL(p) ((p)->channel)
1371 return DAHDI_TONE_RINGTONE;
1373 return DAHDI_TONE_STUTTER;
1375 return DAHDI_TONE_CONGESTION;
1377 return DAHDI_TONE_DIALTONE;
1379 return DAHDI_TONE_DIALRECALL;
1381 return DAHDI_TONE_INFO;
1391 switch (analogsub) {
1420 struct doomed_pri *entry;
1426 ast_debug(4,
"Destroying span %d from doomed queue.\n",
1428 pri_destroy_span(entry->pri);
1447static void pri_queue_for_destruction(
struct sig_pri_span *pri)
1449 struct doomed_pri *entry;
1453 if (entry->pri == pri) {
1458 entry =
ast_calloc(
sizeof(
struct doomed_pri), 1);
1466 ast_debug(4,
"Queue span %d for destruction.\n", pri->
span);
1489 struct dahdi_dialoperation zo = {
1495 for (offset = 0; offset <
sizeof(zo.dialstr) - 1; ++offset) {
1502 if (offset >=
sizeof(zo.dialstr) - 3) {
1506 zo.dialstr[offset] =
'w';
1508 zo.dialstr[offset] =
'w';
1511 zo.dialstr[offset] = *pos++;
1515 ast_debug(1,
"Channel %d: Dial str '%s' expanded to '%s' sent to DAHDI_DIAL.\n",
1516 pvt->
channel, dial_str, zo.dialstr);
1567 struct pollfd poller;
1571 unsigned char buf[256];
1576 poller.events = POLLPRI | POLLIN;
1579 res = poll(&poller, 1, timeout);
1581 if (poller.revents & POLLPRI) {
1586 if (poller.revents & POLLIN) {
1598 if (analog_p->
ringt > 0) {
1599 if (!(--analog_p->
ringt)) {
1662 unsigned char buf[256];
1670 int checkaftercid = 0;
1671 const char *matched_context;
1675 if (ringdata ==
NULL) {
1676 ringdata = curRingData;
1684 for (receivedRingT = 0; receivedRingT <
RING_PATTERNS; receivedRingT++)
1685 ringdata[receivedRingT] = 0;
1689 ast_verb(3,
"Detecting post-CID distinctive ring\n");
1693 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
1694 res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i);
1700 if (i & DAHDI_IOMUX_SIGEVENT) {
1703 if (res == DAHDI_EVENT_NOALARM) {
1706 }
else if (res == DAHDI_EVENT_RINGOFFHOOK) {
1708 ringdata[receivedRingT] = analog_p->
ringt;
1719 }
else if (i & DAHDI_IOMUX_READ) {
1722 if (
errno != ELAST) {
1729 if (analog_p->
ringt > 0) {
1730 if (!(--analog_p->
ringt)) {
1739 ast_verb(3,
"Detected ring pattern: %d,%d,%d\n", ringdata[0], ringdata[1], ringdata[2]);
1741 for (counter = 0; counter < 3; counter++) {
1745 ast_verb(3,
"Checking %d,%d,%d with +/- %d range\n",
1750 for (counter1 = 0; counter1 < 3; counter1++) {
1754 ast_verb(3,
"Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
1755 ringdata[counter1]);
1757 }
else if (ring - range <= ringdata[counter1] && ringdata[counter1] <= ring + range) {
1758 ast_verb(3,
"Ring pattern %d is in range: %d to %d\n",
1759 ringdata[counter1], ring - range, ring + range);
1767 if (distMatches == 3) {
1770 ast_verb(3,
"Matched Distinctive Ring context %s\n", matched_context);
1776 if (strcmp(p->
context, matched_context) != 0) {
1864 ast_verb(3,
"CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n",
1940 ast_log(
LOG_ERROR,
"We used a sub other than SUB_REAL (incorrect assumption sir)\n");
1957 ast_debug(1,
"%s DTMF digit: 0x%02X '%c' on %s\n",
1967 struct dahdi_bufferinfo bi = {
1974 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
2012 ast_debug(1,
"Already in a fax extension, not redirecting\n");
2021 *dest = &p->
subs[idx].
f;
2051 if (!channel_string) {
2061 "DAHDIGroup: %llu\r\n"
2063 "DAHDIChannel: %s\r\n",
2084 "channel", dahdi_channel);
2108 snprintf(ch_name,
sizeof(ch_name),
"no-media (%d)", p->
channel);
2111 strcpy(ch_name,
"pseudo");
2114 snprintf(ch_name,
sizeof(ch_name),
"%d", p->
channel);
2128static void my_ami_channel_event(
void *pvt,
struct ast_channel *chan)
2188 return p->
subs[dahdi_sub].
dfd;
2231#if defined(HAVE_PRI) || defined(HAVE_SS7)
2232static void my_set_digital(
void *pvt,
int is_digital)
2240#if defined(HAVE_SS7)
2241static void my_set_inservice(
void *pvt,
int is_inservice)
2249#if defined(HAVE_SS7)
2250static void my_set_locallyblocked(
void *pvt,
int is_blocked)
2258#if defined(HAVE_SS7)
2259static void my_set_remotelyblocked(
void *pvt,
int is_blocked)
2372 p->
owner = new_owner;
2423 for (i = 0; i < 3; i++) {
2460 int needconf = needconference;
2567#if defined(HAVE_PRI) || defined(HAVE_SS7)
2568static int dahdi_setlaw(
int dfd,
int law)
2571 res = ioctl(dfd, DAHDI_SETLAW, &
law);
2578#if defined(HAVE_PRI)
2617 newlaw = DAHDI_LAW_ALAW;
2620 newlaw = DAHDI_LAW_MULAW;
2630#if defined(HAVE_PRI) || defined(HAVE_SS7)
2638static void my_pri_ss7_open_media(
void *p)
2649 res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val);
2656 res = dahdi_setlaw(dfd, pvt->
law);
2678#if defined(HAVE_PRI)
2689static void my_pri_dial_digits(
void *p,
const char *dial_string)
2691 char dial_str[DAHDI_MAX_DTMF_BUF];
2695 snprintf(dial_str,
sizeof(dial_str),
"T%s", dial_string);
2745 case DAHDI_EVENT_ONHOOK:
2748 case DAHDI_EVENT_RINGOFFHOOK:
2751 case DAHDI_EVENT_WINKFLASH:
2754 case DAHDI_EVENT_ALARM:
2757 case DAHDI_EVENT_NOALARM:
2760 case DAHDI_EVENT_DIALCOMPLETE:
2763 case DAHDI_EVENT_RINGERON:
2766 case DAHDI_EVENT_RINGEROFF:
2769 case DAHDI_EVENT_HOOKCOMPLETE:
2772 case DAHDI_EVENT_PULSE_START:
2775 case DAHDI_EVENT_POLARITY:
2778 case DAHDI_EVENT_RINGBEGIN:
2781 case DAHDI_EVENT_EC_DISABLED:
2784 case DAHDI_EVENT_REMOVED:
2787 case DAHDI_EVENT_NEONMWI_ACTIVE:
2790 case DAHDI_EVENT_NEONMWI_INACTIVE:
2793#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2794 case DAHDI_EVENT_TX_CED_DETECTED:
2797 case DAHDI_EVENT_RX_CED_DETECTED:
2800 case DAHDI_EVENT_EC_NLP_DISABLED:
2803 case DAHDI_EVENT_EC_NLP_ENABLED:
2807 case DAHDI_EVENT_PULSEDIGIT:
2810 case DAHDI_EVENT_DTMFDOWN:
2813 case DAHDI_EVENT_DTMFUP:
2817 switch(
event & 0xFFFF0000) {
2818 case DAHDI_EVENT_PULSEDIGIT:
2819 case DAHDI_EVENT_DTMFDOWN:
2820 case DAHDI_EVENT_DTMFUP:
2862 struct dahdi_params par;
2864 memset(&par, 0,
sizeof(par));
2871 par.rxisoffhook = 0;
2881 return (par.rxbits > -1) || par.rxisoffhook;
2884 return par.rxisoffhook;
2911 int func = DAHDI_FLASH;
2978 int x = DAHDI_START;
2993 ast_log(
LOG_ERROR,
"Trying to dial_digits '%s' on channel %d subchannel %u\n",
3020 if (ioctl(p->
subs[index].
dfd, DAHDI_DIALING, &x)) {
3021 ast_debug(1,
"DAHDI_DIALING ioctl failed!\n");
3034#if defined(HAVE_PRI)
3035static void my_pri_fixup_chans(
void *chan_old,
void *chan_new)
3042 if (new_chan->
owner) {
3049 new_chan->
dsp = old_chan->
dsp;
3063 new_chan->
law = old_chan->
law;
3068#if defined(HAVE_PRI)
3069static int sig_pri_tone_to_dahditone(
enum sig_pri_tone tone)
3073 return DAHDI_TONE_RINGTONE;
3075 return DAHDI_TONE_STUTTER;
3077 return DAHDI_TONE_CONGESTION;
3079 return DAHDI_TONE_DIALTONE;
3081 return DAHDI_TONE_DIALRECALL;
3083 return DAHDI_TONE_INFO;
3085 return DAHDI_TONE_BUSY;
3092#if defined(HAVE_PRI)
3093static void my_handle_dchan_exception(
struct sig_pri_span *pri,
int index)
3097 ioctl(pri->
fds[index], DAHDI_GETEVENT, &x);
3099 case DAHDI_EVENT_NONE:
3101 case DAHDI_EVENT_ALARM:
3102 case DAHDI_EVENT_NOALARM:
3114 case DAHDI_EVENT_ALARM:
3117 case DAHDI_EVENT_NOALARM:
3120 case DAHDI_EVENT_REMOVED:
3121 pri_queue_for_destruction(pri);
3129#if defined(HAVE_PRI)
3130static int my_pri_play_tone(
void *pvt,
enum sig_pri_tone tone)
3134 return tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, sig_pri_tone_to_dahditone(tone));
3138#if defined(HAVE_PRI) || defined(HAVE_SS7)
3147static void my_set_callerid(
void *pvt,
const struct ast_party_caller *caller)
3162 if (caller->
id.
tag) {
3167 sizeof(p->cid_ani));
3172#if defined(HAVE_PRI) || defined(HAVE_SS7)
3181static void my_set_dnid(
void *pvt,
const char *
dnid)
3189#if defined(HAVE_PRI)
3198static void my_set_rdnis(
void *pvt,
const char *
rdnis)
3206#if defined(HAVE_PRI)
3233static void my_pri_make_cc_dialstring(
void *priv,
char *
buf,
size_t buf_size)
3254 snprintf(
buf, buf_size,
"%s/i%d-",
args.tech, pvt->pri->span);
3257 if (isdigit(
args.group[0]) ||
args.group[0] ==
'i' || strchr(
args.group,
'!')) {
3264 snprintf(
buf, buf_size,
"%s/i%d-%s",
args.tech, pvt->pri->span,
args.group);
3268#if defined(HAVE_PRI)
3278static void dahdi_pri_update_span_devstate(
struct sig_pri_span *pri)
3281 unsigned num_b_chans;
3290 for (idx = pri->
numchans; idx--;) {
3314#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
3318 }
else if (!in_use) {
3320 }
else if (!pri->user_busy_threshold) {
3326 if (pri->threshold_devstate != new_state) {
3327 pri->threshold_devstate = new_state;
3334#if defined(HAVE_PRI)
3340static void my_module_ref(
void)
3346#if defined(HAVE_PRI)
3352static void my_module_unref(
void)
3358#if defined(HAVE_PRI)
3359#if defined(HAVE_PRI_CALL_WAITING)
3360static void my_pri_init_config(
void *priv,
struct sig_pri_span *pri);
3362static int dahdi_new_pri_nobch_channel(
struct sig_pri_span *pri);
3367 .play_tone = my_pri_play_tone,
3373 .new_ast_channel = my_new_pri_ast_channel,
3374 .fixup_chans = my_pri_fixup_chans,
3378 .set_digital = my_set_digital,
3379 .set_callerid = my_set_callerid,
3380 .set_dnid = my_set_dnid,
3381 .set_rdnis = my_set_rdnis,
3382 .new_nobch_intf = dahdi_new_pri_nobch_channel,
3383#if defined(HAVE_PRI_CALL_WAITING)
3384 .init_config = my_pri_init_config,
3387 .make_cc_dialstring = my_pri_make_cc_dialstring,
3388 .update_span_devstate = dahdi_pri_update_span_devstate,
3389 .module_ref = my_module_ref,
3390 .module_unref = my_module_unref,
3391 .dial_digits = my_pri_dial_digits,
3392 .open_media = my_pri_ss7_open_media,
3393 .ami_channel_event = my_ami_channel_event,
3394 .destroy_later = pri_queue_for_destruction,
3398#if defined(HAVE_SS7)
3407static void my_handle_link_exception(
struct sig_ss7_linkset *linkset,
int which)
3411 if (ioctl(linkset->
fds[which], DAHDI_GETEVENT, &
event)) {
3413 linkset->
span, which);
3417 case DAHDI_EVENT_NONE:
3419 case DAHDI_EVENT_ALARM:
3424 case DAHDI_EVENT_NOALARM:
3437#if defined(HAVE_SS7)
3438static void my_ss7_set_loopback(
void *pvt,
int enable)
3449#if defined(HAVE_SS7)
3469 if (linksets[idx].
ss7.ss7 ==
ss7) {
3470 return &linksets[idx].
ss7;
3477#if defined(HAVE_SS7)
3520 newlaw = DAHDI_LAW_ALAW;
3523 newlaw = DAHDI_LAW_MULAW;
3530#if defined(HAVE_SS7)
3531static int sig_ss7_tone_to_dahditone(
enum sig_ss7_tone tone)
3535 return DAHDI_TONE_RINGTONE;
3537 return DAHDI_TONE_STUTTER;
3539 return DAHDI_TONE_CONGESTION;
3541 return DAHDI_TONE_DIALTONE;
3543 return DAHDI_TONE_DIALRECALL;
3545 return DAHDI_TONE_INFO;
3547 return DAHDI_TONE_BUSY;
3554#if defined(HAVE_SS7)
3555static int my_ss7_play_tone(
void *pvt,
enum sig_ss7_tone tone)
3559 return tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, sig_ss7_tone_to_dahditone(tone));
3563#if defined(HAVE_SS7)
3571 .set_loopback = my_ss7_set_loopback,
3573 .new_ast_channel = my_new_ss7_ast_channel,
3574 .play_tone = my_ss7_play_tone,
3576 .handle_link_exception = my_handle_link_exception,
3580 .set_digital = my_set_digital,
3581 .set_inservice = my_set_inservice,
3582 .set_locallyblocked = my_set_locallyblocked,
3583 .set_remotelyblocked = my_set_remotelyblocked,
3584 .set_callerid = my_set_callerid,
3585 .set_dnid = my_set_dnid,
3586 .open_media = my_pri_ss7_open_media,
3587 .find_linkset = my_ss7_find_linkset,
3657#define gen_pvt_field_callback(type, field) \
3658 static type my_get_##field(void *pvt) \
3660 struct dahdi_pvt *p = pvt; \
3668#undef gen_pvt_field_callback
3759 "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
3852#if defined(HAVE_PRI)
3867static void mfcr2_queue_for_destruction(
const struct dahdi_pvt *p)
3869 const struct dahdi_mfcr2 *r2link = p->mfcr2;
3870 struct r2link_entry *cur;
3873 if (r2link == &cur->mfcr2) {
3883static int dahdi_r2_answer(
struct dahdi_pvt *p)
3889#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
3891 int wants_double_answer =
ast_true(double_answer) ? 1 : 0;
3892 if (!double_answer) {
3895 res = openr2_chan_answer_call(p->r2chan);
3896 }
else if (wants_double_answer) {
3897 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE);
3899 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE);
3902 res = openr2_chan_answer_call(p->r2chan);
3910static openr2_calling_party_category_t dahdi_r2_get_channel_category(
struct ast_channel *
c)
3912 openr2_calling_party_category_t cat;
3916 ast_debug(1,
"No MFC/R2 category specified for chan %s, using default %s\n",
3918 return p->mfcr2_category;
3920 if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) {
3921 ast_log(
LOG_WARNING,
"Invalid category specified '%s' for chan %s, using default %s\n",
3922 catstr,
ast_channel_name(
c), openr2_proto_get_category_string(p->mfcr2_category));
3923 return p->mfcr2_category;
3925 ast_debug(1,
"Using category %s\n", catstr);
3929static void dahdi_r2_on_call_init(openr2_chan_t *r2chan)
3931 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3940 ast_log(
LOG_ERROR,
"Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan));
3950 p->mfcr2_ani_index =
'\0';
3951 p->mfcr2_dnis_index =
'\0';
3952 p->mfcr2_dnis_matched = 0;
3953 p->mfcr2_answer_pending = 0;
3954 p->mfcr2_call_accepted = 0;
3956 ast_verbose(
"New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
3959static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan,
int alarm)
3962 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3967 if (res == DAHDI_ALARM_NOTOPEN) {
3968 mfcr2_queue_for_destruction(p);
3977static void dahdi_r2_on_os_error(openr2_chan_t *r2chan,
int errorcode)
3979 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3981 ast_log(
LOG_ERROR,
"OS error on chan %d: %s\n", openr2_chan_get_number(r2chan), strerror(errorcode));
3984 if (errorcode == ENODEV) {
3985 struct dahdi_mfcr2 *r2link = p->mfcr2;
3994static void dahdi_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
3996 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3997 ast_log(
LOG_ERROR,
"MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason));
4007static void dahdi_r2_disconnect_call(
struct dahdi_pvt *p, openr2_call_disconnect_cause_t cause)
4009 if (openr2_chan_disconnect_call(p->r2chan, cause)) {
4010 ast_log(
LOG_NOTICE,
"Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n",
4011 p->
channel, openr2_proto_get_disconnect_string(cause));
4013 openr2_chan_set_idle(p->r2chan);
4020static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan,
const char *ani,
const char *dnis, openr2_calling_party_category_t category)
4026 ast_verbose(
"MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n",
4027 openr2_chan_get_number(r2chan), ani ? ani :
"(restricted)", dnis,
4028 openr2_proto_get_category_string(category));
4029 p = openr2_chan_get_client_data(r2chan);
4031 if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
4033 dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED);
4034 goto dahdi_r2_on_call_offered_cleanup;
4037 p->mfcr2_recvd_category = category;
4040 ast_debug(1,
"No CID allowed in configuration, CID is being cleared!\n");
4045 if (p->
immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) {
4046 ast_debug(1,
"Setting exten => s because of immediate or 0 DNIS configured\n");
4052 ast_log(
LOG_NOTICE,
"MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
4054 dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER);
4055 goto dahdi_r2_on_call_offered_cleanup;
4057 if (!p->mfcr2_accept_on_offer) {
4064 goto dahdi_r2_on_call_offered_cleanup;
4067 dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
4068 }
else if (p->mfcr2_charge_calls) {
4069 ast_debug(1,
"Accepting MFC/R2 call with charge on chan %d\n", p->
channel);
4070 openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
4072 ast_debug(1,
"Accepting MFC/R2 call with no charge on chan %d\n", p->
channel);
4073 openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
4076dahdi_r2_on_call_offered_cleanup:
4080static void dahdi_r2_on_call_end(openr2_chan_t *r2chan)
4082 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4089static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
4095 p = openr2_chan_get_client_data(r2chan);
4097 p->mfcr2_call_accepted = 1;
4099 if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
4100 ast_verbose(
"MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan));
4105 if (!p->mfcr2_accept_on_offer) {
4106 openr2_chan_disable_read(r2chan);
4107 if (p->mfcr2_answer_pending) {
4108 ast_debug(1,
"Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan));
4111 goto dahdi_r2_on_call_accepted_cleanup;
4117 openr2_chan_disable_read(r2chan);
4118 goto dahdi_r2_on_call_accepted_cleanup;
4122 dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
4123 goto dahdi_r2_on_call_accepted_cleanup;
4130 openr2_chan_disable_read(r2chan);
4132dahdi_r2_on_call_accepted_cleanup:
4136static void dahdi_r2_on_call_answered(openr2_chan_t *r2chan)
4138 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4139 ast_verbose(
"MFC/R2 call has been answered on channel %d\n", openr2_chan_get_number(r2chan));
4143static void dahdi_r2_on_call_read(openr2_chan_t *r2chan,
const unsigned char *
buf,
int buflen)
4148static int dahdi_r2_cause_to_ast_cause(openr2_call_disconnect_cause_t cause)
4151 case OR2_CAUSE_BUSY_NUMBER:
4153 case OR2_CAUSE_NETWORK_CONGESTION:
4155 case OR2_CAUSE_OUT_OF_ORDER:
4157 case OR2_CAUSE_UNALLOCATED_NUMBER:
4159 case OR2_CAUSE_NO_ANSWER:
4161 case OR2_CAUSE_NORMAL_CLEARING:
4163 case OR2_CAUSE_UNSPECIFIED:
4169static void dahdi_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause)
4171 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4174 int datalen =
sizeof(*cause_code);
4176 ast_verbose(
"MFC/R2 call disconnected on channel %d\n", openr2_chan_get_number(r2chan));
4181 dahdi_r2_disconnect_call(p, OR2_CAUSE_NORMAL_CLEARING);
4185 snprintf(cause_str,
sizeof(cause_str),
"R2 DISCONNECT (%s)", openr2_proto_get_disconnect_string(cause));
4186 datalen += strlen(cause_str);
4188 memset(cause_code, 0, datalen);
4189 cause_code->
ast_cause = dahdi_r2_cause_to_ast_cause(cause);
4201 }
else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) {
4204 case OR2_CAUSE_BUSY_NUMBER:
4207 case OR2_CAUSE_NETWORK_CONGESTION:
4208 case OR2_CAUSE_OUT_OF_ORDER:
4209 case OR2_CAUSE_UNALLOCATED_NUMBER:
4210 case OR2_CAUSE_NO_ANSWER:
4211 case OR2_CAUSE_UNSPECIFIED:
4212 case OR2_CAUSE_NORMAL_CLEARING:
4227static void dahdi_r2_write_log(openr2_log_level_t level,
char *logmessage)
4230 case OR2_LOG_NOTICE:
4233 case OR2_LOG_WARNING:
4239 case OR2_LOG_STACK_TRACE:
4240 case OR2_LOG_MF_TRACE:
4241 case OR2_LOG_CAS_TRACE:
4243 case OR2_LOG_EX_DEBUG:
4253static void dahdi_r2_on_line_blocked(openr2_chan_t *r2chan)
4255 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4259 ast_log(
LOG_NOTICE,
"Far end blocked on chan %d\n", openr2_chan_get_number(r2chan));
4262static void dahdi_r2_on_line_idle(openr2_chan_t *r2chan)
4264 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4268 ast_log(
LOG_NOTICE,
"Far end unblocked on chan %d\n", openr2_chan_get_number(r2chan));
4271static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level,
const char *fmt, va_list ap)
4272 __attribute__((format (printf, 3, 0)));
4273static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level,
const char *fmt, va_list ap)
4275#define CONTEXT_TAG "Context - "
4277 char completemsg[
sizeof(
logmsg) * 2];
4279 snprintf(completemsg,
sizeof(completemsg), CONTEXT_TAG
"%s",
logmsg);
4280 dahdi_r2_write_log(level, completemsg);
4284static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level,
const char *fmt, va_list ap)
4285 __attribute__((format (printf, 3, 0)));
4286static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level,
const char *fmt, va_list ap)
4288#define CHAN_TAG "Chan "
4290 char completemsg[
sizeof(
logmsg) * 2];
4292 snprintf(completemsg,
sizeof(completemsg), CHAN_TAG
"%d - %s", openr2_chan_get_number(r2chan),
logmsg);
4293 dahdi_r2_write_log(level, completemsg);
4297static int dahdi_r2_on_dnis_digit_received(openr2_chan_t *r2chan,
char digit)
4299 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4306 p->mfcr2_dnis_index++;
4307 p->
exten[p->mfcr2_dnis_index] = 0;
4308 p->
rdnis[p->mfcr2_dnis_index] = 0;
4310 if ((p->mfcr2_dnis_matched ||
4319static void dahdi_r2_on_ani_digit_received(openr2_chan_t *r2chan,
char digit)
4321 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4324 p->mfcr2_ani_index++;
4325 p->
cid_num[p->mfcr2_ani_index] = 0;
4326 p->
cid_name[p->mfcr2_ani_index] = 0;
4329static void dahdi_r2_on_billing_pulse_received(openr2_chan_t *r2chan)
4331 ast_verbose(
"MFC/R2 billing pulse received on channel %d\n", openr2_chan_get_number(r2chan));
4334static openr2_event_interface_t dahdi_r2_event_iface = {
4335 .on_call_init = dahdi_r2_on_call_init,
4336 .on_call_offered = dahdi_r2_on_call_offered,
4337 .on_call_accepted = dahdi_r2_on_call_accepted,
4338 .on_call_answered = dahdi_r2_on_call_answered,
4339 .on_call_disconnect = dahdi_r2_on_call_disconnect,
4340 .on_call_end = dahdi_r2_on_call_end,
4341 .on_call_read = dahdi_r2_on_call_read,
4342 .on_hardware_alarm = dahdi_r2_on_hardware_alarm,
4343 .on_os_error = dahdi_r2_on_os_error,
4344 .on_protocol_error = dahdi_r2_on_protocol_error,
4345 .on_line_blocked = dahdi_r2_on_line_blocked,
4346 .on_line_idle = dahdi_r2_on_line_idle,
4348 .on_context_log = (openr2_handle_context_logging_func)dahdi_r2_on_context_log,
4349 .on_dnis_digit_received = dahdi_r2_on_dnis_digit_received,
4350 .on_ani_digit_received = dahdi_r2_on_ani_digit_received,
4352 .on_billing_pulse_received = dahdi_r2_on_billing_pulse_received
4355static inline int16_t dahdi_r2_alaw_to_linear(uint8_t sample)
4360static inline uint8_t dahdi_r2_linear_to_alaw(
int sample)
4365static openr2_transcoder_interface_t dahdi_r2_transcode_iface = {
4366 dahdi_r2_alaw_to_linear,
4367 dahdi_r2_linear_to_alaw
4408 for (
x = 0;
x < strlen(fn);
x++) {
4409 if (!isdigit(fn[
x])) {
4420 fn =
"/dev/dahdi/channel";
4422 fd = open(fn, O_RDWR | O_NONBLOCK);
4428 if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
4437 if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &
bs) == -1) {
4456 chan_pvt->
subs[sub_num].
dfd = -1;
4459#if defined(HAVE_PRI)
4460static void dahdi_close_pri_fd(
struct dahdi_pri *pri,
int fd_num)
4463 pri->pri.fds[fd_num] = -1;
4467#if defined(HAVE_SS7)
4468static void dahdi_close_ss7_fd(
struct dahdi_ss7 *ss7,
int fd_num)
4471 ss7->ss7.fds[fd_num] = -1;
4477 return ioctl(dfd, DAHDI_SETLINEAR, &linear);
4483 struct dahdi_bufferinfo bi;
4496 res = ioctl(p->
subs[x].
dfd, DAHDI_GET_BUFINFO, &bi);
4501 res = ioctl(p->
subs[x].
dfd, DAHDI_SET_BUFINFO, &bi);
4538 return DAHDI_TONE_DTMF_BASE + (
digit -
'0');
4540 return DAHDI_TONE_DTMF_A + (
digit -
'A');
4542 return DAHDI_TONE_DTMF_A + (
digit -
'a');
4543 else if (
digit ==
'*')
4544 return DAHDI_TONE_DTMF_s;
4545 else if (
digit ==
'#')
4546 return DAHDI_TONE_DTMF_p;
4585 char dial_str[] = {
'T',
digit,
'\0' };
4596 dtmf = DAHDI_FLUSH_WRITE;
4599 ast_log(
LOG_WARNING,
"Unable to flush the DAHDI write buffer to send DTMF on channel %d: %s\n",
4603 ast_debug(1,
"Channel %s started VLDTMF digit '%c'\n",
4638 ast_debug(1,
"Channel %s ending VLDTMF digit '%c'\n",
4664 "Hook Transition Complete",
4669 "Polarity Reversal",
4677 { DAHDI_ALARM_RED,
"Red Alarm" },
4678 { DAHDI_ALARM_YELLOW,
"Yellow Alarm" },
4679 { DAHDI_ALARM_BLUE,
"Blue Alarm" },
4680 { DAHDI_ALARM_RECOVER,
"Recovering" },
4681 { DAHDI_ALARM_LOOPBACK,
"Loopback" },
4682 { DAHDI_ALARM_NOTOPEN,
"Not Open" },
4683 { DAHDI_ALARM_NONE,
"None" },
4693 return alm ?
"Unknown Alarm" :
"No Alarm";
4698 static char buf[256];
4707 static char buf[256];
4710 return "E & M Immediate";
4712 return "E & M Wink";
4716 return "Feature Group D (DTMF)";
4718 return "Feature Group D (MF)";
4720 return "Feature Group D (MF) Tandem Access";
4722 return "Feature Group B (MF)";
4726 return "FGC/CAMA (Dialpulse)";
4728 return "FGC/CAMA (MF)";
4730 return "FXS Loopstart";
4732 return "FXS Groundstart";
4734 return "FXS Kewlstart";
4736 return "FXO Loopstart";
4738 return "FXO Groundstart";
4740 return "FXO Kewlstart";
4744 return "ISDN BRI Point to Point";
4746 return "ISDN BRI Point to MultiPoint";
4752 return "SF (Tone) Immediate";
4754 return "SF (Tone) Wink";
4756 return "SF (Tone) with Feature Group D (DTMF)";
4758 return "SF (Tone) with Feature Group D (MF)";
4760 return "SF (Tone) with Feature Group B (MF)";
4764 snprintf(
buf,
sizeof(
buf),
"Unknown signalling %d", sig);
4769#define sig2str dahdi_sig2str
4775 struct dahdi_confinfo zi;
4777 memset(&zi, 0,
sizeof(zi));
4780 if (slavechannel > 0) {
4782 zi.confmode = DAHDI_CONF_DIGITALMON;
4783 zi.confno = slavechannel;
4787 zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |
4788 DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;
4790 zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
4793 if ((zi.confno ==
c->curconf.confno) && (zi.confmode ==
c->curconf.confmode))
4797 if (ioctl(
c->dfd, DAHDI_SETCONF, &zi)) {
4798 ast_log(
LOG_WARNING,
"Failed to add %d to conference %d/%d: %s\n",
c->dfd, zi.confmode, zi.confno, strerror(
errno));
4801 if (slavechannel < 1) {
4805 ast_debug(1,
"Added %d to conference %d/%d\n",
c->dfd,
c->curconf.confmode,
c->curconf.confno);
4812 if ((p->
channel ==
c->curconf.confno) && (
c->curconf.confmode == DAHDI_CONF_DIGITALMON))
4815 if ((p->
confno > 0) && (p->
confno ==
c->curconf.confno) && (
c->curconf.confmode & DAHDI_CONF_TALKER))
4822 struct dahdi_confinfo zi;
4829 memset(&zi, 0,
sizeof(zi));
4830 if (ioctl(
c->dfd, DAHDI_SETCONF, &zi)) {
4831 ast_log(
LOG_WARNING,
"Failed to drop %d from conference %d/%d: %s\n",
c->dfd,
c->curconf.confmode,
c->curconf.confno, strerror(
errno));
4834 ast_debug(1,
"Removed %d from conference %d/%d\n",
c->dfd,
c->curconf.confmode,
c->curconf.confno);
4835 memcpy(&
c->curconf, &zi,
sizeof(
c->curconf));
4847 for (x = 0; x < 3; x++) {
4855 if (useslavenative) {
4874 else if (slave->
law != p->
law) {
4880 return useslavenative;
4888 struct dahdi_confinfo zi;
4890 memset(&zi, 0,
sizeof(zi));
4906 for (x = 0; x < 3; x++) {
4949 ast_debug(1,
"Updated conferencing on %d, with %d conference users\n", p->
channel, needconf);
4958 ast_debug(1,
"Echo cancellation already on\n");
4962 ast_debug(1,
"Echo cancellation isn't required on digital connection\n");
4966#if defined(HAVE_PRI) || defined(HAVE_SS7)
4968#if defined(HAVE_PRI)
4979#if defined(HAVE_SS7)
4988 "Unable to enable audio mode on channel %d (%s)\n",
5004 ast_debug(1,
"No echo cancellation requested\n");
5020 ast_debug(1,
"No echo training requested\n");
5029 struct dahdi_echocanparams ecp = { .tap_length = 0 };
5044 struct dahdi_hwgain hwgain;
5046 hwgain.newgain = gain * 10.0;
5047 hwgain.tx = tx_direction;
5048 return ioctl(fd, DAHDI_SET_HWGAIN, &hwgain) < 0;
5055 float shallow, steep;
5056 float max = SHRT_MAX;
5058 neg = (sample < 0 ? -1 : 1);
5060 shallow = neg*(
max-
max/drc)+(
float)sample/drc;
5061 if (fabsf(steep) < fabsf(shallow)) {
5072static void fill_txgain(
struct dahdi_gains *g,
float gain,
float drc,
int law)
5077 float linear_gain = pow(10.0, gain / 20.0);
5080 case DAHDI_LAW_ALAW:
5081 for (j = 0; j <
ARRAY_LEN(g->txgain); j++) {
5087 k = (float)k * linear_gain;
5090 }
else if (k < -32768) {
5099 case DAHDI_LAW_MULAW:
5100 for (j = 0; j <
ARRAY_LEN(g->txgain); j++) {
5106 k = (float)k * linear_gain;
5109 }
else if (k < -32768) {
5122static void fill_rxgain(
struct dahdi_gains *g,
float gain,
float drc,
int law)
5126 float linear_gain = pow(10.0, gain / 20.0);
5129 case DAHDI_LAW_ALAW:
5130 for (j = 0; j <
ARRAY_LEN(g->rxgain); j++) {
5136 k = (float)k * linear_gain;
5139 }
else if (k < -32768) {
5148 case DAHDI_LAW_MULAW:
5149 for (j = 0; j <
ARRAY_LEN(g->rxgain); j++) {
5155 k = (float)k * linear_gain;
5158 }
else if (k < -32768) {
5172 struct dahdi_gains g;
5175 memset(&g, 0,
sizeof(g));
5176 res = ioctl(fd, DAHDI_GETGAINS, &g);
5184 return ioctl(fd, DAHDI_SETGAINS, &g);
5189 struct dahdi_gains g;
5192 memset(&g, 0,
sizeof(g));
5193 res = ioctl(fd, DAHDI_GETGAINS, &g);
5201 return ioctl(fd, DAHDI_SETGAINS, &g);
5204static int set_actual_gain(
int fd,
float rxgain,
float txgain,
float rxdrc,
float txdrc,
int law)
5241 res = ioctl(fd, DAHDI_HOOK, &x);
5244 if (
errno == EINPROGRESS)
5258#if defined(HAVE_PRI) || defined(HAVE_SS7)
5260#if defined(HAVE_PRI)
5268#if defined(HAVE_SS7)
5292 struct dahdi_confinfo
c;
5305 memset(&
c, 0,
sizeof(
c));
5306 c.confmode = DAHDI_CONF_NORMAL;
5312 ast_debug(1,
"Disabled conferencing\n");
5326 ast_debug(1,
"Restored conferencing\n");
5359 ast_debug(6,
"MWI manual override active on channel %d: pretending that it should be %s\n",
5390 if (
errno == EAGAIN)
5469#if defined(HAVE_PRI)
5476 subaddr = strchr(p->
exten,
':');
5505 x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;
5520 (p->
law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW);
5526#if defined(HAVE_SS7)
5558 openr2_calling_party_category_t chancat;
5577 chancat = dahdi_r2_get_channel_category(ast);
5578 callres = openr2_chan_make_call(p->r2chan, l, (
c + p->
stripmsd), chancat);
5579 if (-1 == callres) {
5584 p->mfcr2_call_accepted = 0;
5585 p->mfcr2_progress_sent = 0;
5659 }
else if (
iflist == pvt) {
5667 }
else if (
ifend == pvt) {
5678#if defined(HAVE_PRI)
5731#if defined(HAVE_PRI)
5769#if defined(HAVE_PRI)
5777static void dahdi_unlink_pri_pvt(
struct dahdi_pvt *pvt)
5788 for (idx = 0; idx <
pri->numchans; ++idx) {
5799#if defined(HAVE_SS7)
5807static void dahdi_unlink_ss7_pvt(
struct dahdi_pvt *pvt)
5818 for (idx = 0; idx <
ss7->numchans; ++idx) {
5829#if defined(HAVE_OPENR2)
5836static void dahdi_unlink_mfcr2_pvt(
struct dahdi_pvt *pvt)
5839 struct dahdi_mfcr2 *mfcr2;
5840 int should_destroy_link = 0;
5845 openr2_chan_disable_read(pvt->r2chan);
5849 for (idx = 0; idx < mfcr2->numchans; ++idx) {
5850 if (mfcr2->pvts[idx] == pvt) {
5851 ast_debug(1,
"Removing MFC/R2 channel %d from the mfcr2 link\n", pvt->
channel);
5852 mfcr2->pvts[idx] =
NULL;
5853 mfcr2->live_chans--;
5857 if (!mfcr2->live_chans) {
5858 ast_debug(1,
"MFC/R2 link is now empty\n");
5859 should_destroy_link = 1;
5863 if (should_destroy_link) {
5864 ast_debug(1,
"MFC/R2 link is now empty\n");
5865 mfcr2_queue_for_destruction(pvt);
5893#if defined(HAVE_PRI)
5894 dahdi_unlink_pri_pvt(p);
5896#if defined(HAVE_SS7)
5897 dahdi_unlink_ss7_pvt(p);
5899#if defined(HAVE_OPENR2)
5900 dahdi_unlink_mfcr2_pvt(p);
5908#if defined(HAVE_PRI)
5909 case DAHDI_IFLIST_NO_B_CHAN:
5911 dahdi_nobch_extract(p->pri, p);
5922#if defined(HAVE_PRI)
5927#if defined(HAVE_SS7)
5970 for (i = 0; i < 3; i++) {
5982#if defined(HAVE_PRI)
5998#if defined(HAVE_PRI_SERVICE_MESSAGES)
6000 char db_chan_name[20];
6005 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, p->
span, chan);
6006 if (!
ast_db_get(db_chan_name, SRVST_DBKEY, db_answer,
sizeof(db_answer))) {
6007 sscanf(db_answer,
"%1c:%30d", &
state, &why);
6017 ast_verb(3,
"Unregistered channel %d\n", chan);
6022#if defined(HAVE_PRI)
6025 if (!pris[
span].dchannels[0]) {
6041#if defined(HAVE_PRI)
6042static char *dahdi_send_keypad_facility_app =
"DAHDISendKeypadFacility";
6044static int dahdi_send_keypad_facility_exec(
struct ast_channel *chan,
const char *digits)
6050 ast_debug(1,
"No digit string sent to application!\n");
6057 ast_debug(1,
"Unable to find technology private\n");
6067#if defined(HAVE_PRI)
6068#if defined(HAVE_PRI_PROG_W_CAUSE)
6069static char *dahdi_send_callrerouting_facility_app =
"DAHDISendCallreroutingFacility";
6071static int dahdi_send_callrerouting_facility_exec(
struct ast_channel *chan,
const char *data)
6084 ast_debug(1,
"No data sent to application!\n");
6088 ast_debug(1,
"Only DAHDI technology accepted!\n");
6093 ast_debug(1,
"Unable to find technology private\n");
6100 ast_debug(1,
"callrerouting attempted on non-ISDN channel %s\n",
6109 ast_log(
LOG_WARNING,
"callrerouting facility requires at least destination number argument\n");
6114 ast_log(
LOG_WARNING,
"Callrerouting Facility without original called number argument\n");
6119 ast_log(
LOG_NOTICE,
"Callrerouting Facility without diversion reason argument, defaulting to unknown\n");
6138#if defined(HAVE_OPENR2)
6139static const char *
const dahdi_accept_r2_call_app =
"DAHDIAcceptR2Call";
6141static int dahdi_accept_r2_call_exec(
struct ast_channel *chan,
const char *data)
6144 openr2_call_mode_t accept_mode;
6145 int res, timeout, maxloops;
6154 ast_debug(1,
"No data sent to application!\n");
6159 ast_debug(1,
"Only DAHDI technology accepted!\n");
6165 ast_debug(1,
"Unable to find technology private!\n");
6173 ast_log(
LOG_WARNING,
"DAHDIAcceptR2Call requires 'yes' or 'no' for the charge parameter\n");
6178 if (!p->mfcr2 || !p->mfcr2call) {
6184 if (p->mfcr2_call_accepted) {
6189 accept_mode =
ast_true(
args.charge) ? OR2_CALL_WITH_CHARGE : OR2_CALL_NO_CHARGE;
6190 if (openr2_chan_accept_call(p->r2chan, accept_mode)) {
6201 while (maxloops > 0) {
6230 if (p->mfcr2_call_accepted) {
6232 ast_debug(1,
"Accepted MFC/R2 call!\n");
6243static openr2_call_disconnect_cause_t dahdi_ast_cause_to_r2_cause(
int cause)
6245 openr2_call_disconnect_cause_t r2cause = OR2_CAUSE_NORMAL_CLEARING;
6250 r2cause = OR2_CAUSE_BUSY_NUMBER;
6255 r2cause = OR2_CAUSE_NETWORK_CONGESTION;
6259 r2cause = OR2_CAUSE_UNALLOCATED_NUMBER;
6264 r2cause = OR2_CAUSE_OUT_OF_ORDER;
6269 r2cause = OR2_CAUSE_NO_ANSWER;
6273 r2cause = OR2_CAUSE_NORMAL_CLEARING;
6276 ast_debug(1,
"ast cause %d resulted in openr2 cause %d/%s\n",
6277 cause, r2cause, openr2_proto_get_disconnect_string(r2cause));
6286 struct dahdi_bufferinfo bi = {
6294 if ((bpres = ioctl(p->
subs[
SUB_REAL].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
6311 struct dahdi_params par;
6339#if defined(HAVE_PRI)
6402#if defined(HAVE_SS7)
6481 ast_debug(1,
"Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
6498 ast_debug(1,
"Normal call hung up with both three way call and a call waiting call in place?\n");
6501 ast_debug(1,
"We were flipped over to the callwait, moving back and not owning.\n");
6508 ast_debug(1,
"We were in the threeway and have a callwait still. Ditching the threeway.\n");
6514 ast_debug(1,
"Call was complete, setting owner to former third call\n");
6518 ast_debug(1,
"Call was incomplete, setting owner to NULL\n");
6537 ast_debug(1,
"Call was complete, setting owner to former third call\n");
6541 ast_debug(1,
"Call was incomplete, setting owner to NULL\n");
6602 if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) {
6605 if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) {
6606 dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE);
6609 int r2cause_user = r2causestr ? atoi(r2causestr) : 0;
6610 openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user)
6612 dahdi_r2_disconnect_call(p, r2cause);
6614 }
else if (p->mfcr2call) {
6640 memset(&par, 0,
sizeof(par));
6645 ast_debug(1,
"Hanging up channel %d, offhook = %d\n", p->
channel, par.rxisoffhook);
6648 if ((par.rxisoffhook) && (!(p->
radio || (p->
oprmode < 0))))
6741 ast_debug(1,
"Channel %d is no longer eligible for reorigination (went back on hook or became in use)\n", p->
channel);
6786#if defined(HAVE_PRI)
6791#if defined(HAVE_SS7)
6798 if (!p->mfcr2_call_accepted) {
6801 p->mfcr2_answer_pending = 1;
6802 if (p->mfcr2_charge_calls) {
6803 ast_debug(1,
"Accepting MFC/R2 call with charge before answering on chan %d\n", p->
channel);
6804 openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE);
6806 ast_debug(1,
"Accepting MFC/R2 call with no charge before answering on chan %d\n", p->
channel);
6807 openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE);
6843 int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
6864 if (!p || !data || (*datalen < 1)) {
6875 *cp = p->
tdd ? 1 : 0;
6889#if defined(HAVE_PRI)
6890#if defined(HAVE_PRI_CCSS)
6918 if (!p || !data || (datalen < 1)) {
6925 scp = (
signed char *) data;
6934 scp = (
signed char *) data;
6972 ast_debug(1,
"Set option TDD MODE, value: %s(%d) on %s\n",
6977 unsigned char mybuf[41000];
6979 int size, res, fd,
len;
6980 struct pollfd fds[1];
6983 memset(
buf, 0x7f,
sizeof(mybuf));
6999 fds[0].events = POLLPRI | POLLOUT;
7001 res = poll(fds, 1, -1);
7007 if (fds[0].revents & POLLPRI)
7009 if (!(fds[0].revents & POLLOUT)) {
7013 res = write(fd,
buf, size);
7015 if (res == -1)
return -1;
7039 ast_debug(1,
"Set option RELAX DTMF, value: %s(%d) on %s\n",
7044#if defined(HAVE_PRI)
7084 ast_debug(1,
"Set Operator Services mode, value: %d on %s/%s\n",
7137 if (!strcasecmp(data,
"rxgain")) {
7141 }
else if (!strcasecmp(data,
"txgain")) {
7145 }
else if (!strcasecmp(data,
"dahdi_channel")) {
7149 }
else if (!strcasecmp(data,
"dahdi_span")) {
7153 }
else if (!strcasecmp(data,
"dahdi_group")) {
7157 }
else if (!strcasecmp(data,
"dahdi_type")) {
7160#if defined(HAVE_OPENR2)
7165#if defined(HAVE_PRI)
7173#if defined(HAVE_SS7)
7184#if defined(HAVE_PRI)
7185#if defined(HAVE_PRI_REVERSE_CHARGE)
7186 }
else if (!strcasecmp(data,
"reversecharge")) {
7199#if defined(HAVE_PRI_SETUP_KEYPAD)
7200 }
else if (!strcasecmp(data,
"keypad_digits")) {
7214 }
else if (!strcasecmp(data,
"no_media_path")) {
7231 }
else if (!strcasecmp(data,
"dialmode")) {
7269 char policy_str[21] =
"";
7271 if ((res = sscanf(parse,
"%30d,%20s", num_buffers, policy_str)) != 2) {
7275 if (*num_buffers < 0) {
7279 if (!strcasecmp(policy_str,
"full")) {
7280 *policy = DAHDI_POLICY_WHEN_FULL;
7281 }
else if (!strcasecmp(policy_str,
"immediate")) {
7282 *policy = DAHDI_POLICY_IMMEDIATE;
7283#if defined(HAVE_DAHDI_HALF_FULL)
7284 }
else if (!strcasecmp(policy_str,
"half")) {
7285 *policy = DAHDI_POLICY_HALF_FULL;
7305 if (!strcasecmp(data,
"buffers")) {
7306 int num_bufs, policy;
7309 struct dahdi_bufferinfo bi = {
7310 .txbufpolicy = policy,
7311 .rxbufpolicy = policy,
7313 .numbufs = num_bufs,
7317 if ((bpres = ioctl(p->
subs[
SUB_REAL].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
7325 }
else if (!strcasecmp(data,
"echocan_mode")) {
7326 if (!strcasecmp(
value,
"on")) {
7330 }
else if (!strcasecmp(
value,
"off")) {
7334#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
7335 }
else if (!strcasecmp(
value,
"fax")) {
7346 }
else if (!strcasecmp(
value,
"voice")) {
7362 }
else if (!strcasecmp(data,
"dialmode")) {
7373 if (!strcasecmp(
value,
"pulse")) {
7375 }
else if (!strcasecmp(
value,
"dtmf") || !strcasecmp(
value,
"tone")) {
7377 }
else if (!strcasecmp(
value,
"none")) {
7379 }
else if (!strcasecmp(
value,
"both")) {
7386 }
else if (!strcasecmp(data,
"waitfordialtone")) {
7426 if (!slave || (master->
slaves[x] == slave)) {
7467 if (!slave || !master) {
7472 if (!master->
slaves[x]) {
7473 master->
slaves[x] = slave;
7496 if (p->
owner == oldchan) {
7499 for (x = 0; x < 3; x++) {
7509#if defined(HAVE_PRI)
7513#if defined(HAVE_SS7)
7582 ast_verb(3,
"TRANSFERRING %s to %s\n",
7607 struct dahdi_confinfo ci;
7611 memset(&ci, 0,
sizeof(ci));
7620 ast_verb(3,
"Avoiding 3-way call when in an external conference\n");
7634 struct dahdi_spaninfo zi;
7635 struct dahdi_params params;
7637 memset(&zi, 0,
sizeof(zi));
7638 zi.spanno = p->
span;
7641 if (zi.alarms != DAHDI_ALARM_NONE)
7649 memset(¶ms, 0,
sizeof(params));
7650 if ((res = ioctl(p->
subs[
SUB_REAL].
dfd, DAHDI_GET_PARAMS, ¶ms)) >= 0)
7651 return params.chan_alarms;
7655 return DAHDI_ALARM_NONE;
7663 ast_debug(1,
"%s DTMF digit: 0x%02X '%c' on %s\n",
7680 *dest = &p->
subs[idx].
f;
7684 ast_debug(1,
"Got some DTMF, but it's for the CAS\n");
7693 *dest = &p->
subs[idx].
f;
7700 struct dahdi_bufferinfo bi = {
7707 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
7745 ast_debug(1,
"Already in a fax extension, not redirecting\n");
7754 *dest = &p->
subs[idx].
f;
7764 "Alarm", alarm_txt);
7783 "Alarm", alarm_txt);
7793 const char *alarm_str;
7795#if defined(HAVE_PRI)
7836 p->
subs[idx].
f.
src =
"dahdi_handle_event";
7838 f = &p->
subs[idx].
f;
7848 if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) {
7849 p->
pulsedial = (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0;
7851#if defined(HAVE_PRI)
7869 if (res & DAHDI_EVENT_DTMFDOWN) {
7870 ast_debug(1,
"DTMF Down '%c'\n", res & 0xff);
7871#if defined(HAVE_PRI)
7886 return &p->
subs[idx].
f;
7890 case DAHDI_EVENT_EC_DISABLED:
7894#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
7895 case DAHDI_EVENT_TX_CED_DETECTED:
7896 ast_verb(3,
"Channel %d detected a CED tone towards the network.\n", p->
channel);
7898 case DAHDI_EVENT_RX_CED_DETECTED:
7899 ast_verb(3,
"Channel %d detected a CED tone from the network.\n", p->
channel);
7901 case DAHDI_EVENT_EC_NLP_DISABLED:
7902 ast_verb(3,
"Channel %d echo canceler disabled its NLP.\n", p->
channel);
7904 case DAHDI_EVENT_EC_NLP_ENABLED:
7905 ast_verb(3,
"Channel %d echo canceler enabled its NLP.\n", p->
channel);
7908 case DAHDI_EVENT_BITSCHANGED:
7914 openr2_chan_handle_cas(p->r2chan);
7920 case DAHDI_EVENT_PULSE_START:
7923 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
7925 case DAHDI_EVENT_DIALCOMPLETE:
7927#if defined(HAVE_PRI)
7932 if (ioctl(p->
subs[idx].
dfd, DAHDI_DIALING, &x) == -1) {
7933 ast_debug(1,
"DAHDI_DIALING ioctl failed on %s: %s\n",
7958 if (ioctl(p->
subs[idx].
dfd,DAHDI_DIALING,&x) == -1) {
7967 p->
dop.op = DAHDI_DIAL_OP_REPLACE;
7986 ast_debug(1,
"Done dialing, but waiting for progress detection before doing more...\n");
8011 case DAHDI_EVENT_ALARM:
8013#if defined(HAVE_PRI)
8018#if defined(HAVE_SS7)
8030 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
8036#if defined(HAVE_SS7)
8044 case DAHDI_EVENT_ONHOOK:
8077 ast_verb(3,
"Channel %d still has (callwait) call, ringing phone\n", p->
channel);
8092 unsigned int mssinceflash;
8103 if (p->
owner != ast) {
8113 ast_debug(1,
"Last flash was %u ms ago\n", mssinceflash);
8120 ast_debug(1,
"Looks like a bounced flash, hanging up both calls on %d\n", p->
channel);
8166 case DAHDI_EVENT_RINGOFFHOOK:
8195 int numchars = snprintf(p->
dop.dialstr,
sizeof(p->
dop.dialstr),
"M*0%s#",
c);
8196 if (numchars >=
sizeof(p->
dop.dialstr)) {
8203 if (strlen(p->
dop.dialstr) > 4) {
8208 p->
dop.dialstr[strlen(p->
dop.dialstr)-2] =
'\0';
8217 return &p->
subs[idx].
f;
8249 p->
dop.dialstr[0] =
'\0';
8252 ast_debug(1,
"Sent FXO deferred digit string: %s\n", p->
dop.dialstr);
8257 p->
dop.dialstr[0] =
'\0';
8261 return &p->
subs[idx].
f;
8268 return &p->
subs[idx].
f;
8281 res = tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, DAHDI_TONE_DIALTONE);
8296 ast_debug(1,
"Setting IDLE polarity due "
8297 "to ring. Old polarity was %d\n",
8340 case DAHDI_EVENT_RINGBEGIN:
8351 case DAHDI_EVENT_RINGERON:
8353 case DAHDI_EVENT_NOALARM:
8355#if defined(HAVE_PRI)
8360#if defined(HAVE_SS7)
8371 case DAHDI_EVENT_WINKFLASH:
8373 if (p->
radio)
break;
8377 struct dahdi_params par;
8379 memset(&par, 0,
sizeof(par));
8382 if (!par.rxisoffhook)
8400 ast_debug(1,
"Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
8464 ast_debug(1,
"Flash when call not up or ringing\n");
8495 res = tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, DAHDI_TONE_DIALRECALL);
8503 res = tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, DAHDI_TONE_CONGESTION);
8519 ast_debug(1,
"Got flash with three way call up, dropping last call on %d\n", p->
channel);
8537 ast_verb(3,
"Building conference call with %s and %s\n",
8587 snprintf(p->
dop.dialstr,
sizeof(p->
dop.dialstr),
"M*%d%s#",
8596 ast_log(
LOG_WARNING,
"Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
8613 p->
dop.dialstr[0] =
'\0';
8616 ast_debug(1,
"Sent deferred digit string: %s\n", p->
dop.dialstr);
8618 p->
dop.dialstr[0] =
'\0';
8624 case DAHDI_EVENT_HOOKCOMPLETE:
8642 p->
dop.dialstr[0] =
'\0';
8645 ast_debug(1,
"Sent deferred digit string: %s\n", p->
dop.dialstr);
8647 p->
dop.dialstr[0] =
'\0';
8648 p->
dop.op = DAHDI_DIAL_OP_REPLACE;
8658 ast_debug(1,
"Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->
channel);
8664 case DAHDI_EVENT_POLARITY:
8676 ast_debug(1,
"Answering on polarity switch!\n");
8691 ast_debug(1,
"Polarity Reversal event occurred - 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) );
8694 ast_debug(1,
"Polarity Reversal detected and now Hanging up on channel %d\n", p->
channel);
8705 ast_debug(1,
"Polarity Reversal event occurred - 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) );
8708 ast_debug(1,
"Dunno what to do with event %d on channel %d\n", res, p->
channel);
8710 return &p->
subs[idx].
f;
8732 p->
subs[idx].
f.
src =
"dahdi_exception";
8748 if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) &&
8749 (res != DAHDI_EVENT_HOOKCOMPLETE)) {
8750 ast_debug(1,
"Restoring owner of channel %d on event %d\n", p->
channel, res);
8758 case DAHDI_EVENT_ONHOOK:
8770 case DAHDI_EVENT_RINGOFFHOOK:
8778 case DAHDI_EVENT_HOOKCOMPLETE:
8779 case DAHDI_EVENT_RINGERON:
8780 case DAHDI_EVENT_RINGEROFF:
8783 case DAHDI_EVENT_WINKFLASH:
8790 if (usedindex > -1) {
8807 f = &p->
subs[idx].
f;
8813 if (ast != p->
owner) {
8817 f = &p->
subs[idx].
f;
8911 struct dahdi_params ps;
8913 memset(&ps, 0,
sizeof(ps));
8929 return &p->
subs[idx].
f;
8932 if (!(--p->
ringt)) {
8940 openr2_chan_process_event(p->r2chan);
8941 if (OR2_DIR_FORWARD == openr2_chan_get_direction(p->r2chan)) {
8945 if (p->mfcr2_call_accepted &&
8946 !p->mfcr2_progress_sent &&
8948 ast_debug(1,
"Enqueuing progress frame after R2 accept in chan %d\n", p->
channel);
8950 p->mfcr2_progress_sent = 1;
8963 return &p->
subs[idx].
f;
8972 return &p->
subs[idx].
f;
8981 return &p->
subs[idx].
f;
8990 return &p->
subs[idx].
f;
8993 if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) {
9009 return &p->
subs[idx].
f;
9019 return &p->
subs[idx].
f;
9029 return &p->
subs[idx].
f;
9071 if (
errno == EAGAIN) {
9074 return &p->
subs[idx].
f;
9075 }
else if (
errno == ELAST) {
9117 return &p->
subs[idx].
f;
9125 ast_verb(3,
"CPE does not support Call Waiting Caller*ID.\n");
9182 ast_debug(1,
"Channel driver fax CNG detection timeout on %s\n",
9227 ast_debug(1,
"Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n",
9250 ast_debug(1,
"Got 10 samples of dialtone!\n");
9254 p->
dop.dialstr[0] =
'\0';
9259 ast_debug(1,
"Sent deferred digit string: %s\n", p->
dop.dialstr);
9261 p->
dop.dialstr[0] =
'\0';
9262 p->
dop.op = DAHDI_DIAL_OP_REPLACE;
9271 f = &p->
subs[idx].
f;
9323 res = write(fd,
buf, size);
9368 if (mssinceflash >= 1000) {
9386 ast_debug(5,
"Dropping frame since I'm still dialing on %s...\n",
9392 ast_debug(5,
"Dropping frame since there is no active owner on %s...\n",
9398 ast_debug(5,
"Dropping frame since I've still got a callerid spill on %s...\n",
9440 int func = DAHDI_FLASH;
9445#if defined(HAVE_PRI)
9451#if defined(HAVE_SS7)
9461 if (p->mfcr2 && !p->mfcr2_call_accepted) {
9470 switch (condition) {
9472 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_BUSY);
9475 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_RINGTONE);
9536 p->
dop.dialstr[0] =
'\0';
9549 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
9559#if defined(HAVE_PRI)
9574#if defined(HAVE_PRI)
9575 }
else if (i->pri) {
9577 y = ++i->pri->new_chan_seq;
9595 for (x = 0; x < 3; ++x) {
9633#if defined(HAVE_PRI)
9652 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));
9666#if defined(HAVE_PRI)
9674 if (law == DAHDI_LAW_ALAW) {
9684 ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW;
9719 x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
9720 if (ioctl(i->
subs[idx].
dfd, DAHDI_TONEDETECT, &x)) {
9738#if defined(HAVE_PRI) || defined(HAVE_SS7)
9772 ast_channel_parkinglot_set(tmp, i->
parkinglot);
9774 ast_channel_language_set(tmp, i->
language);
9801#if defined(HAVE_PRI) || defined(HAVE_SS7)
9836 ast_debug(3,
"Suppressing immediate device state update to prevent INUSE -> RINGING transition\n");
9839 dashptr = strrchr(device_name,
'-');
9846 for (v = i->
vars ; v ; v = v->
next)
9886 if (strchr(term,
c))
9898 j = DAHDI_IOMUX_SIGEVENT;
9900 if (ioctl(p->
subs[idx].
dfd,DAHDI_IOMUX,&j) == -1)
return(-1);
9902 if (j & DAHDI_IOMUX_SIGEVENT)
break;
9905 if (ioctl(p->
subs[idx].
dfd,DAHDI_GETEVENT,&j) == -1)
return(-1);
9945 return dahdichan->
dnd;
9950 ast_verb(3,
"%s DND on channel %d\n",
9951 flag?
"Enabled" :
"Disabled",
9959 int extlen = strlen(exten);
9965 if (extlen < strlen(pickupexten) && !strncmp(pickupexten, exten, extlen)) {
9969 if (exten[0] ==
'*' && extlen < 3) {
9990 unsigned char buf[256];
10005 int getforward = 0;
10011 const char *pickupexten;
10035 ast_log(
LOG_ERROR,
"Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
10038 pickupexten =
ast_strdupa(pickup_cfg->pickupexten);
10063 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10073 memset(dtmfbuf, 0,
sizeof(dtmfbuf));
10088 res =
my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf),
"*", 3000);
10098 if (res <= 0)
break;
10107 if ((p->
sig ==
SIG_FEATDMF) && (dtmfbuf[1] !=
'0') && (strlen(dtmfbuf) != 14))
10113 if (res <= 0)
break;
10121 res =
my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf),
"#", 3000);
10138 res =
my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf),
"*", 3000);
10145 dtmfbuf[
len] =
'\0';
10154 ast_debug(1,
"waitfordigit returned < 0...\n");
10158 dtmfbuf[
len++] = res;
10159 dtmfbuf[
len] =
'\0';
10171 }
else if (res < 0) {
10172 ast_debug(1,
"Got hung up before digits finished\n");
10187 if ((res > 0) && (strlen(anibuf) > 2)) {
10188 if (anibuf[strlen(anibuf) - 1] ==
'#')
10189 anibuf[strlen(anibuf) - 1] = 0;
10200 if (exten[0] ==
'*') {
10201 char *stringp=
NULL;
10205 s1 =
strsep(&stringp,
"*");
10206 s2 =
strsep(&stringp,
"*");
10219 if (exten[0] ==
'*') {
10220 char *stringp=
NULL;
10224 s1 =
strsep(&stringp,
"#");
10225 s2 =
strsep(&stringp,
"#");
10239 if (exten[0] ==
'*') {
10240 char *stringp=
NULL;
10244 s1 =
strsep(&stringp,
"#");
10245 s2 =
strsep(&stringp,
"#");
10246 if (s2 && (*(s2 + 1) ==
'0')) {
10256 if (exten[0] ==
'*') {
10257 char *stringp=
NULL;
10261 s1 =
strsep(&stringp,
"#");
10295 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10301 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_INFO);
10309 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10324 int is_exten_parking = 0;
10334 ast_debug(1,
"waitfordigit returned < 0...\n");
10335 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10339 ast_debug(1,
"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
10344 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10346 tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALTONE);
10357 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10361 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10363 memset(exten, 0,
sizeof(exten));
10364 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALTONE);
10368 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10387 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10396 }
else if (res == 0) {
10397 ast_debug(1,
"not enough digits (and no ambiguous match)...\n");
10398 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10402 }
else if (p->
callwaiting && !strcmp(exten,
"*70")) {
10406 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10412 ioctl(p->
subs[idx].
dfd,DAHDI_CONFDIAG,&
len);
10413 memset(exten, 0,
sizeof(exten));
10416 }
else if (!strcmp(exten, pickupexten)) {
10432 ast_debug(1,
"No call pickup possible...\n");
10433 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10444 }
else if (!p->
hidecallerid && !strcmp(exten,
"*67")) {
10452 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10458 memset(exten, 0,
sizeof(exten));
10460 }
else if (p->
callreturn && !strcmp(exten,
"*69")) {
10461 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10463 }
else if (!strcmp(exten,
"*78")) {
10466 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10468 memset(exten, 0,
sizeof(exten));
10470 }
else if (!strcmp(exten,
"*79")) {
10473 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10475 memset(exten, 0,
sizeof(exten));
10478 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10480 memset(exten, 0,
sizeof(exten));
10483 ast_verb(3,
"Cancelling call forwarding on channel %d\n", p->
channel);
10484 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10487 memset(exten, 0,
sizeof(exten));
10500 if (bridge_channel) {
10519 }
else if (p->
hidecallerid && !strcmp(exten,
"*82")) {
10524 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10530 memset(exten, 0,
sizeof(exten));
10532 }
else if (!strcmp(exten,
"*0")) {
10539 if (nbridge && bridged) {
10542 if (nbridge && pbridge &&
10546 int func = DAHDI_FLASH;
10548 p->
dop.dialstr[0] =
'\0';
10561 tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10563 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10581 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10591 if (smdi_msg !=
NULL) {
10594 if (smdi_msg->
type ==
'B')
10596 else if (smdi_msg->
type ==
'N')
10644 "Exiting simple switch\n");
10669 ast_debug(1,
"CID got string '%s'\n", dtmfbuf);
10682 struct timeval start;
10693 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10694 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
10700 if (i & DAHDI_IOMUX_SIGEVENT) {
10703 if (res == DAHDI_EVENT_NOALARM) {
10708 if (res == DAHDI_EVENT_RINGBEGIN) {
10716 }
else if (i & DAHDI_IOMUX_READ) {
10719 if (
errno != ELAST) {
10740 "Failed to decode CallerID on channel '%s'\n",
10745 else if (samples > (8000 * 10))
10769 "Exiting simple switch\n");
10790 for (receivedRingT = 0; receivedRingT <
ARRAY_LEN(curRingData); receivedRingT++)
10791 curRingData[receivedRingT] = 0;
10802 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10803 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
10809 if (i & DAHDI_IOMUX_SIGEVENT) {
10812 if (res == DAHDI_EVENT_NOALARM) {
10818 curRingData[receivedRingT] = p->
ringt;
10824 if (++receivedRingT ==
ARRAY_LEN(curRingData))
10826 }
else if (i & DAHDI_IOMUX_READ) {
10829 if (
errno != ELAST) {
10837 if (p->
ringt > 0) {
10838 if (!(--p->
ringt)) {
10846 ast_verb(3,
"Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
10847 for (counter = 0; counter < 3; counter++) {
10851 for (counter1 = 0; counter1 < 3; counter1++) {
10854 ast_verb(3,
"Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
10855 curRingData[counter1]);
10859 ast_verb(3,
"Ring pattern matched in range: %d to %d\n",
10866 if (distMatches == 3) {
10884 "state, but I have nothing to do. "
10885 "Terminating simple switch, should be "
10886 "restarted by the actual ring.\n",
10895 struct timeval start;
10908 "Exiting simple switch\n");
10932 ast_debug(1,
"CID is '%s', flags %d\n",
10951 for (receivedRingT = 0; receivedRingT <
ARRAY_LEN(curRingData); receivedRingT++)
10952 curRingData[receivedRingT] = 0;
10965 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10966 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
10972 if (i & DAHDI_IOMUX_SIGEVENT) {
10975 if (res == DAHDI_EVENT_NOALARM) {
10980 ast_debug(1,
"Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->
channel);
10989 curRingData[receivedRingT] = p->
ringt;
10995 if (++receivedRingT ==
ARRAY_LEN(curRingData))
10997 }
else if (i & DAHDI_IOMUX_READ) {
11000 if (
errno != ELAST) {
11008 if (p->
ringt > 0) {
11009 if (!(--p->
ringt)) {
11022 "Failed to decode CallerID on channel '%s'\n",
11027 else if (
samples > (8000 * 10))
11037 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
11038 curRingData[receivedRingT] = 0;
11041 ast_verb(3,
"Detecting post-CID distinctive ring\n");
11043 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
11044 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
11050 if (i & DAHDI_IOMUX_SIGEVENT) {
11053 if (res == DAHDI_EVENT_NOALARM) {
11059 curRingData[receivedRingT] = p->
ringt;
11065 if (++receivedRingT ==
ARRAY_LEN(curRingData))
11067 }
else if (i & DAHDI_IOMUX_READ) {
11070 if (
errno != ELAST) {
11078 if (p->
ringt > 0) {
11079 if (!(--p->
ringt)) {
11089 ast_verb(3,
"Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
11091 for (counter = 0; counter < 3; counter++) {
11095 ast_verb(3,
"Checking %d,%d,%d\n",
11100 for (counter1 = 0; counter1 < 3; counter1++) {
11103 ast_verb(3,
"Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
11104 curRingData[counter1]);
11109 ast_verb(3,
"Ring pattern matched in range: %d to %d\n",
11115 if (distMatches == 3) {
11162 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
11166 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
11192 for (x = 0; x <
len; x++)
11202 pthread_t threadid;
11207 unsigned int spill_done = 0;
11208 int spill_result = -1;
11211 goto quit_no_clean;
11219 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
11225 if (i & DAHDI_IOMUX_SIGEVENT) {
11228 int callid_created;
11236 case DAHDI_EVENT_NEONMWI_ACTIVE:
11237 case DAHDI_EVENT_NEONMWI_INACTIVE:
11238 case DAHDI_EVENT_NONE:
11239 case DAHDI_EVENT_BITSCHANGED:
11241 case DAHDI_EVENT_NOALARM:
11250 case DAHDI_EVENT_ALARM:
11288 goto quit_no_clean;
11290 }
else if (i & DAHDI_IOMUX_READ) {
11292 if (
errno != ELAST) {
11307 }
else if (spill_result) {
11317 if (samples > (8000 * 4))
11322 if (spill_result == 1) {
11359#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11361 if (pvt->mwisend_rpas) {
11364 }
else if (pvt->mwisend_fsk) {
11392 x = DAHDI_FLUSH_BOTH;
11396#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11397 if (pvt->mwisend_fsk) {
11402#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11410 struct timeval now;
11434#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11435 if (pvt->mwisend_fsk) {
11437 gettimeofday(&now,
NULL);
11441#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11449 if (0 < num_read) {
11502 case DAHDI_EVENT_RINGEROFF:
11519 case DAHDI_EVENT_RINGOFFHOOK:
11529 case DAHDI_EVENT_RINGERON:
11530 case DAHDI_EVENT_HOOKCOMPLETE:
11544 int destroyed_first = 0;
11545 int destroyed_last = 0;
11552 int x = DAHDI_FLASH;
11554 if (cur->
channel > destroyed_last) {
11555 destroyed_last = cur->
channel;
11557 if (destroyed_first < 1 || cur->
channel < destroyed_first) {
11558 destroyed_first = cur->
channel;
11569 if (destroyed_first > start || destroyed_last <
end) {
11570 ast_debug(1,
"Asked to destroy %d-%d, destroyed %d-%d,\n",
11571 start,
end, destroyed_first, destroyed_last);
11576static void dahdi_r2_destroy_nodev(
void)
11578 struct r2link_entry *cur;
11582 struct dahdi_mfcr2 *r2 = &cur->mfcr2;
11583 ast_debug(3,
"About to destroy %d DAHDI channels of MFC/R2 link.\n", r2->numchans);
11584 for (i = 0; i < r2->numchans; i++) {
11597 pthread_cancel(r2->r2master);
11598 pthread_join(r2->r2master,
NULL);
11600 openr2_context_delete(r2->protocol_context);
11630 ast_debug(1,
"channel range caps: %d - %d\n", start,
end);
11635 "channel range %d-%d is occupied\n",
11644 struct dahdi_pri *pri = pris + x;
11646 if (!pris[x].pri.pvts[0]) {
11650 int channo = pri->dchannels[i];
11655 if (!pri->pri.fds[i]) {
11658 if (channo >= start && channo <=
end) {
11660 "channel range %d-%d is occupied by span %d\n",
11661 start,
end, x + 1);
11669 !
conf.chan.cc_params) {
11674 conf.wanted_channels_start = start;
11677 conf.wanted_channels_end =
end;
11693 pthread_t threadid;
11696 int callid_created;
11701 case DAHDI_EVENT_NONE:
11702 case DAHDI_EVENT_BITSCHANGED:
11704 case DAHDI_EVENT_WINKFLASH:
11705 case DAHDI_EVENT_RINGOFFHOOK:
11707 if (i->
radio)
break;
11714 if (res && (
errno == EBUSY)) {
11728 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_RINGTONE);
11732 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_CONGESTION);
11741 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_STUTTER);
11743 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_DIALTONE);
11745 ast_log(
LOG_WARNING,
"Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->
channel);
11748 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_CONGESTION);
11791 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_CONGESTION);
11802 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_CONGESTION);
11808 case DAHDI_EVENT_NOALARM:
11810#if defined(HAVE_PRI)
11817#if defined(HAVE_SS7)
11828 case DAHDI_EVENT_ALARM:
11830#if defined(HAVE_PRI)
11837#if defined(HAVE_SS7)
11849 case DAHDI_EVENT_ONHOOK:
11895 case DAHDI_EVENT_POLARITY:
11909 ast_verb(2,
"Starting post polarity "
11910 "CID detection on channel %d\n",
11924 "polarity reversal on non-FXO (SIG_FXS) "
11925 "interface %d\n", i->
channel);
11928 case DAHDI_EVENT_REMOVED:
11930 "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n",
11933 case DAHDI_EVENT_NEONMWI_ACTIVE:
11939 case DAHDI_EVENT_NEONMWI_INACTIVE:
11950 struct pollfd **pfds = arg;
11956 int count, res, res2, spoint, pollres=0;
11960 time_t thispass = 0, lastpass = 0;
11963 struct pollfd *pfds=
NULL;
11964 int lastalloc = -1;
11969 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,
NULL)) {
11975 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
11981 if (!pfds || (lastalloc !=
ifcount)) {
12008 pfds[count].events = POLLPRI;
12009 pfds[count].revents = 0;
12013 pfds[count].events |= POLLIN;
12021 pfds[count].events = POLLPRI;
12022 pfds[count].revents = 0;
12027 pfds[count].events |= POLLIN;
12038 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
NULL);
12039 pthread_testcancel();
12041 res = poll(pfds, count, 1000);
12042 pthread_testcancel();
12043 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
12056 lastpass = thispass;
12057 thispass = time(
NULL);
12068 if (thispass != lastpass) {
12075 && !
last->mwisendactive
12076 && (
last->sig & __DAHDI_SIG_FXO)
12089 res2 = ioctl(
last->subs[
SUB_REAL].dfd, DAHDI_VMWI, &res);
12092 ast_debug(3,
"Unable to control message waiting led on channel %d: %s\n",
last->channel, strerror(
errno));
12095 ast_debug(5,
"Initiating MWI FSK spill on channel %d\n",
last->channel);
12125 if (pollres & POLLIN) {
12141 pthread_attr_t attr;
12142 pthread_t threadid;
12145 pthread_attr_init(&attr);
12146 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
12151 memcpy(mtd->
buf,
buf, res);
12164 struct timeval now;
12172 gettimeofday(&now,
NULL);
12179 pthread_t threadid;
12214 if (pollres & POLLPRI) {
12241 ast_debug(1,
"Woah! Went back on hook before reoriginate could happen on channel %d\n", i->
channel);
12244 res = DAHDI_EVENT_RINGOFFHOOK;
12259 dahdi_r2_destroy_nodev();
12263 pthread_cleanup_pop(1);
12294#if defined(HAVE_PRI)
12295static int pri_resolve_span(
int *
span,
int channel,
int offset,
struct dahdi_spaninfo *si)
12300 trunkgroup = pris[*
span].mastertrunkgroup;
12315 }
else if (pris[*
span].mastertrunkgroup) {
12316 ast_log(
LOG_WARNING,
"Unable to use span %d implicitly since it is already part of trunk group %d\n", *
span, pris[*
span].mastertrunkgroup);
12319 if (si->totalchans == 31) {
12321 pris[*
span].dchannels[0] = 16 + offset;
12322 }
else if (si->totalchans == 24) {
12324 pris[*
span].dchannels[0] = 24 + offset;
12325 }
else if (si->totalchans == 3) {
12327 pris[*
span].dchannels[0] = 3 + offset;
12329 ast_log(
LOG_WARNING,
"Unable to use span %d, since the D-channel cannot be located (unexpected span size of %d channels)\n", *
span, si->totalchans);
12340#if defined(HAVE_PRI)
12341static int pri_create_trunkgroup(
int trunkgroup,
int *
channels)
12343 struct dahdi_spaninfo si;
12344 struct dahdi_params p;
12351 ast_log(
LOG_WARNING,
"Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
12358 memset(&si, 0,
sizeof(si));
12359 memset(&p, 0,
sizeof(p));
12360 fd = open(
"/dev/dahdi/channel", O_RDWR);
12366 if (ioctl(fd, DAHDI_SPECIFY, &x)) {
12371 if (ioctl(fd, DAHDI_GET_PARAMS, &p)) {
12376 if (ioctl(fd, DAHDI_SPANSTAT, &si)) {
12381 span = p.spanno - 1;
12387 if (pris[span].pri.
pvts[0]) {
12388 ast_log(
LOG_WARNING,
"Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
12393 pris[span].pri.trunkgroup = trunkgroup;
12396 pris[ospan].dchannels[y] =
channels[y];
12397 pris[span].pri.span = span + 1;
12404#if defined(HAVE_PRI)
12405static int pri_create_spanmap(
int span,
int trunkgroup,
int logicalspan)
12407 if (pris[span].mastertrunkgroup) {
12408 ast_log(
LOG_WARNING,
"Span %d is already part of trunk group %d, cannot add to trunk group %d\n", span + 1, pris[span].mastertrunkgroup, trunkgroup);
12411 pris[span].mastertrunkgroup = trunkgroup;
12412 pris[span].prilogicalspan = logicalspan;
12417#if defined(HAVE_SS7)
12418static unsigned int parse_pointcode(
const char *pcstring)
12420 unsigned int code1, code2, code3;
12423 numvals = sscanf(pcstring,
"%30d-%30d-%30d", &code1, &code2, &code3);
12427 return (code1 << 16) | (code2 << 8) | code3;
12433#if defined(HAVE_SS7)
12434static struct dahdi_ss7 * ss7_resolve_linkset(
int linkset)
12436 if ((linkset < 0) || (linkset >=
NUM_SPANS))
12439 return &linksets[linkset - 1];
12444static void dahdi_r2_destroy_links(
void)
12446 struct r2link_entry *cur;
12451 ast_debug(3,
"MFC/R2 link #%d queued for destruction\n", cur->mfcr2.index);
12457 dahdi_r2_destroy_nodev();
12461#define R2_LINK_CAPACITY 30
12464 struct r2link_entry *cur =
NULL;
12472 if (memcmp(&
conf->mfcr2, &cur->mfcr2.conf,
sizeof(
conf->mfcr2))) {
12473 ast_debug(3,
"Need new R2 link because of: Configuration change\n");
12475 }
else if (cur->mfcr2.numchans == R2_LINK_CAPACITY) {
12476 ast_debug(3,
"Need new R2 link because of: Capacity (%d)\n", R2_LINK_CAPACITY);
12481 struct r2link_entry *tmp =
NULL;
12482 int new_idx = r2links_count + 1;
12484 for (i = 1; i <= r2links_count; i++) {
12487 if (i == tmp->mfcr2.index) {
12502 cur->mfcr2.index = new_idx;
12505 ast_debug(3,
"Created new R2 link #%d (now have %d)\n", new_idx, r2links_count);
12512static int dahdi_r2_set_context(
struct dahdi_mfcr2 *r2_link,
const struct dahdi_chan_conf *
conf)
12514 char tmplogdir[] =
"/tmp";
12515 char logdir[OR2_MAX_PATH];
12518 r2_link->protocol_context = openr2_context_new(
NULL, &dahdi_r2_event_iface,
12519 &dahdi_r2_transcode_iface,
conf->mfcr2.variant,
conf->mfcr2.max_ani,
12520 conf->mfcr2.max_dnis);
12521 if (!r2_link->protocol_context) {
12524 openr2_context_set_log_level(r2_link->protocol_context,
conf->mfcr2.loglevel);
12525 openr2_context_set_ani_first(r2_link->protocol_context,
conf->mfcr2.get_ani_first);
12526#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
12527 openr2_context_set_skip_category_request(r2_link->protocol_context,
conf->mfcr2.skip_category_request);
12529 openr2_context_set_mf_threshold(r2_link->protocol_context,
threshold);
12530 openr2_context_set_mf_back_timeout(r2_link->protocol_context,
conf->mfcr2.mfback_timeout);
12531 openr2_context_set_metering_pulse_timeout(r2_link->protocol_context,
conf->mfcr2.metering_pulse_timeout);
12532 openr2_context_set_double_answer(r2_link->protocol_context,
conf->mfcr2.double_answer);
12533 openr2_context_set_immediate_accept(r2_link->protocol_context,
conf->mfcr2.immediate_accept);
12534#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
12535 openr2_context_set_dtmf_dialing(r2_link->protocol_context,
conf->mfcr2.dtmf_dialing,
conf->mfcr2.dtmf_time_on,
conf->mfcr2.dtmf_time_off);
12536 openr2_context_set_dtmf_detection(r2_link->protocol_context,
conf->mfcr2.dtmf_detection);
12538#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
12539 openr2_context_set_dtmf_detection_end_timeout(r2_link->protocol_context,
conf->mfcr2.dtmf_end_timeout);
12542 if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
12543 ast_log(
LOG_ERROR,
"Failed setting default MFC/R2 log directory %s\n", tmplogdir);
12547 if (snres >=
sizeof(logdir)) {
12548 ast_log(
LOG_ERROR,
"MFC/R2 logging directory truncated, using %s\n", tmplogdir);
12549 if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
12550 ast_log(
LOG_ERROR,
"Failed setting default MFC/R2 log directory %s\n", tmplogdir);
12553 if (openr2_context_set_log_directory(r2_link->protocol_context, logdir)) {
12559 if (openr2_context_configure_from_advanced_file(r2_link->protocol_context,
conf->mfcr2.r2proto_file)) {
12560 ast_log(
LOG_ERROR,
"Failed to configure r2context from advanced configuration file %s\n",
conf->mfcr2.r2proto_file);
12564 memcpy(&r2_link->conf, &
conf->mfcr2,
sizeof(r2_link->conf));
12598 struct dahdi_bufferinfo bi;
12601#if defined(HAVE_PRI)
12607 struct dahdi_params p;
12608#if defined(HAVE_PRI)
12609 struct dahdi_spaninfo si;
12612#if defined(HAVE_SS7)
12632 if (!here && reloading != 1) {
12644 for (x = 0; x < 3; x++)
12651 int chan_sig =
conf->chan.sig;
12654 if (reloading && tmp->
vars) {
12664 snprintf(fn,
sizeof(fn),
"%d",
channel);
12679 memset(&p, 0,
sizeof(p));
12686 if (
conf->is_sig_auto)
12688 if (p.sigtype != (chan_sig & 0x3ffff)) {
12694 tmp->
law = p.curlaw;
12695 tmp->
span = p.spanno;
12696#if defined(HAVE_PRI)
12697 span = p.spanno - 1;
12702 tmp->
sig = chan_sig;
12713#if defined(HAVE_SS7)
12715 struct dahdi_ss7 *ss7;
12719 ast_log(
LOG_ERROR,
"Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(
errno));
12724 ss7 = ss7_resolve_linkset(cur_linkset);
12730 ss7->ss7.span = cur_linkset;
12731 if (cur_cicbeginswith < 0) {
12742 tmp->ss7 = &ss7->ss7;
12745 ss7_chan->
cic = cur_cicbeginswith++;
12748 ss7_chan->
dpc = cur_defaultdpc;
12750 ss7->ss7.pvts[ss7->ss7.numchans++] = ss7_chan;
12752 ast_copy_string(ss7->ss7.internationalprefix,
conf->ss7.ss7.internationalprefix,
sizeof(ss7->ss7.internationalprefix));
12753 ast_copy_string(ss7->ss7.nationalprefix,
conf->ss7.ss7.nationalprefix,
sizeof(ss7->ss7.nationalprefix));
12754 ast_copy_string(ss7->ss7.subscriberprefix,
conf->ss7.ss7.subscriberprefix,
sizeof(ss7->ss7.subscriberprefix));
12755 ast_copy_string(ss7->ss7.unknownprefix,
conf->ss7.ss7.unknownprefix,
sizeof(ss7->ss7.unknownprefix));
12756 ast_copy_string(ss7->ss7.networkroutedprefix,
conf->ss7.ss7.networkroutedprefix,
sizeof(ss7->ss7.networkroutedprefix));
12758 ss7->ss7.called_nai =
conf->ss7.ss7.called_nai;
12759 ss7->ss7.calling_nai =
conf->ss7.ss7.calling_nai;
12764 struct dahdi_mfcr2 *r2_link;
12765 struct r2link_entry *r2_le = dahdi_r2_get_link(
conf);
12766 r2_link = &r2_le->mfcr2;
12772 if (!r2_link->protocol_context && dahdi_r2_set_context(r2_link,
conf)) {
12777 if (r2_link->numchans ==
ARRAY_LEN(r2_link->pvts)) {
12782 r2_link->pvts[r2_link->numchans++] = tmp;
12783 tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context,
12786 if (!tmp->r2chan) {
12787 openr2_liberr_t err = openr2_context_get_last_error(r2_link->protocol_context);
12788 ast_log(
LOG_ERROR,
"Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err));
12792 r2_link->live_chans++;
12793 tmp->mfcr2 = r2_link;
12794 if (
conf->mfcr2.call_files) {
12795 openr2_chan_enable_call_files(tmp->r2chan);
12797 openr2_chan_set_client_data(tmp->r2chan, tmp);
12799 openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log);
12800 openr2_chan_set_log_level(tmp->r2chan,
conf->mfcr2.loglevel);
12801 tmp->mfcr2_category =
conf->mfcr2.category;
12802 tmp->mfcr2_charge_calls =
conf->mfcr2.charge_calls;
12803 tmp->mfcr2_allow_collect_calls =
conf->mfcr2.allow_collect_calls;
12804 tmp->mfcr2_forced_release =
conf->mfcr2.forced_release;
12805 tmp->mfcr2_accept_on_offer =
conf->mfcr2.accept_on_offer;
12806 tmp->mfcr2call = 0;
12807 tmp->mfcr2_dnis_index = 0;
12808 tmp->mfcr2_ani_index = 0;
12816 int myswitchtype = 0;
12820 ast_log(
LOG_ERROR,
"Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(
errno));
12825 ast_log(
LOG_ERROR,
"Channel %d does not lie on a span I know of (%d)\n", channel, span);
12836 tmp->logicalspan = pris[span].prilogicalspan;
12837 pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
12839 ast_log(
LOG_WARNING,
"Channel %d: Unable to find locate channel/trunk group!\n", channel);
12843 myswitchtype =
conf->pri.pri.switchtype;
12848 if (pris[x].dchannels[y] == tmp->
channel) {
12854 if (!matchesdchan) {
12855 if (pris[span].pri.
nodetype && (pris[span].pri.nodetype !=
conf->pri.pri.nodetype)) {
12860 if (pris[span].pri.
switchtype && (pris[span].pri.switchtype != myswitchtype)) {
12865 if ((pris[span].pri.
dialplan) && (pris[span].pri.dialplan !=
conf->pri.pri.dialplan)) {
12866 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));
12880 if (pris[span].pri.
minunused && (pris[span].pri.minunused !=
conf->pri.pri.minunused)) {
12881 ast_log(
LOG_ERROR,
"Span %d already has minunused of %d.\n", span + 1,
conf->pri.pri.minunused);
12885 if (pris[span].pri.
minidle && (pris[span].pri.minidle !=
conf->pri.pri.minidle)) {
12891 ast_log(
LOG_ERROR,
"Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
12897 pri_chan =
sig_pri_chan_new(tmp, &pris[span].pri, tmp->logicalspan, p.chanpos, pris[span].mastertrunkgroup);
12903 tmp->pri = &pris[span].pri;
12915 conf->chan.cc_params);
12917 pris[span].pri.sig = chan_sig;
12918 pris[span].pri.nodetype =
conf->pri.pri.nodetype;
12919 pris[span].pri.switchtype = myswitchtype;
12920 pris[span].pri.nsf =
conf->pri.pri.nsf;
12921 pris[span].pri.dialplan =
conf->pri.pri.dialplan;
12922 pris[span].pri.localdialplan =
conf->pri.pri.localdialplan;
12923 pris[span].pri.cpndialplan =
conf->pri.pri.cpndialplan;
12924 pris[span].pri.pvts[pris[span].pri.numchans++] = tmp->
sig_pvt;
12925 pris[span].pri.minunused =
conf->pri.pri.minunused;
12926 pris[span].pri.minidle =
conf->pri.pri.minidle;
12927 pris[span].pri.overlapdial =
conf->pri.pri.overlapdial;
12928 pris[span].pri.qsigchannelmapping =
conf->pri.pri.qsigchannelmapping;
12929 pris[span].pri.discardremoteholdretrieval =
conf->pri.pri.discardremoteholdretrieval;
12930#if defined(HAVE_PRI_SERVICE_MESSAGES)
12931 pris[span].pri.enable_service_message_support =
conf->pri.pri.enable_service_message_support;
12933#ifdef HAVE_PRI_INBANDDISCONNECT
12934 pris[span].pri.inbanddisconnect =
conf->pri.pri.inbanddisconnect;
12936#if defined(HAVE_PRI_CALL_HOLD)
12937 pris[span].pri.hold_disconnect_transfer =
12938 conf->pri.pri.hold_disconnect_transfer;
12940#if defined(HAVE_PRI_CCSS)
12941 pris[span].pri.cc_ptmp_recall_mode =
12942 conf->pri.pri.cc_ptmp_recall_mode;
12943 pris[span].pri.cc_qsig_signaling_link_req =
12944 conf->pri.pri.cc_qsig_signaling_link_req;
12945 pris[span].pri.cc_qsig_signaling_link_rsp =
12946 conf->pri.pri.cc_qsig_signaling_link_rsp;
12948#if defined(HAVE_PRI_CALL_WAITING)
12949 pris[span].pri.max_call_waiting_calls =
12950 conf->pri.pri.max_call_waiting_calls;
12951 pris[span].pri.allow_call_waiting_calls =
12952 conf->pri.pri.allow_call_waiting_calls;
12954 pris[span].pri.transfer =
conf->chan.transfer;
12955 pris[span].pri.facilityenable =
conf->pri.pri.facilityenable;
12956#if defined(HAVE_PRI_L2_PERSISTENCE)
12957 pris[span].pri.l2_persistence =
conf->pri.pri.l2_persistence;
12959 pris[span].pri.colp_send =
conf->pri.pri.colp_send;
12960#if defined(HAVE_PRI_AOC_EVENTS)
12961 pris[span].pri.aoc_passthrough_flag =
conf->pri.pri.aoc_passthrough_flag;
12962 pris[span].pri.aoce_delayhangup =
conf->pri.pri.aoce_delayhangup;
12965 pris[span].pri.layer1_ignored =
conf->pri.pri.layer1_ignored;
12968 pris[span].pri.layer1_ignored = 0;
12970 pris[span].pri.append_msn_to_user_tag =
conf->pri.pri.append_msn_to_user_tag;
12971 pris[span].pri.inband_on_setup_ack =
conf->pri.pri.inband_on_setup_ack;
12972 pris[span].pri.inband_on_proceeding =
conf->pri.pri.inband_on_proceeding;
12973 ast_copy_string(pris[span].pri.initial_user_tag,
conf->chan.cid_tag,
sizeof(pris[span].pri.initial_user_tag));
12974 ast_copy_string(pris[span].pri.msn_list,
conf->pri.pri.msn_list,
sizeof(pris[span].pri.msn_list));
12975#if defined(HAVE_PRI_MWI)
12977 conf->pri.pri.mwi_mailboxes,
12978 sizeof(pris[span].pri.mwi_mailboxes));
12980 conf->pri.pri.mwi_vm_boxes,
12981 sizeof(pris[span].pri.mwi_vm_boxes));
12983 conf->pri.pri.mwi_vm_numbers,
12984 sizeof(pris[span].pri.mwi_vm_numbers));
12986 ast_copy_string(pris[span].pri.idledial,
conf->pri.pri.idledial,
sizeof(pris[span].pri.idledial));
12987 ast_copy_string(pris[span].pri.idleext,
conf->pri.pri.idleext,
sizeof(pris[span].pri.idleext));
12988 ast_copy_string(pris[span].pri.internationalprefix,
conf->pri.pri.internationalprefix,
sizeof(pris[span].pri.internationalprefix));
12989 ast_copy_string(pris[span].pri.nationalprefix,
conf->pri.pri.nationalprefix,
sizeof(pris[span].pri.nationalprefix));
12990 ast_copy_string(pris[span].pri.localprefix,
conf->pri.pri.localprefix,
sizeof(pris[span].pri.localprefix));
12991 ast_copy_string(pris[span].pri.privateprefix,
conf->pri.pri.privateprefix,
sizeof(pris[span].pri.privateprefix));
12992 ast_copy_string(pris[span].pri.unknownprefix,
conf->pri.pri.unknownprefix,
sizeof(pris[span].pri.unknownprefix));
12993 pris[span].pri.moh_signaling =
conf->pri.pri.moh_signaling;
12994 pris[span].pri.resetinterval =
conf->pri.pri.resetinterval;
12995#if defined(HAVE_PRI_DISPLAY_TEXT)
12996 pris[span].pri.display_flags_send =
conf->pri.pri.display_flags_send;
12997 pris[span].pri.display_flags_receive =
conf->pri.pri.display_flags_receive;
12999#if defined(HAVE_PRI_MCID)
13000 pris[span].pri.mcid_send =
conf->pri.pri.mcid_send;
13002 pris[span].pri.force_restart_unavailable_chans =
conf->pri.pri.force_restart_unavailable_chans;
13003#if defined(HAVE_PRI_DATETIME_SEND)
13004 pris[span].pri.datetime_send =
conf->pri.pri.datetime_send;
13007 for (x = 0; x < PRI_MAX_TIMERS; x++) {
13008 pris[span].pri.pritimers[x] =
conf->pri.pri.pritimers[x];
13011#if defined(HAVE_PRI_CALL_WAITING)
13013 pris[span].pri.ch_cfg.stripmsd =
conf->chan.stripmsd;
13014 pris[span].pri.ch_cfg.hidecallerid =
conf->chan.hidecallerid;
13015 pris[span].pri.ch_cfg.hidecalleridname =
conf->chan.hidecalleridname;
13016 pris[span].pri.ch_cfg.immediate =
conf->chan.immediate;
13017 pris[span].pri.ch_cfg.priexclusive =
conf->chan.priexclusive;
13018 pris[span].pri.ch_cfg.priindication_oob =
conf->chan.priindication_oob;
13019 pris[span].pri.ch_cfg.use_callerid =
conf->chan.use_callerid;
13020 pris[span].pri.ch_cfg.use_callingpres =
conf->chan.use_callingpres;
13021 ast_copy_string(pris[span].pri.ch_cfg.context,
conf->chan.context,
sizeof(pris[span].pri.ch_cfg.context));
13022 ast_copy_string(pris[span].pri.ch_cfg.mohinterpret,
conf->chan.mohinterpret,
sizeof(pris[span].pri.ch_cfg.mohinterpret));
13035 chan_sig = tmp->
sig;
13037 memset(&p, 0,
sizeof(p));
13042 switch (chan_sig) {
13066 p.channo = channel;
13070 p.debouncetime = 5;
13072 p.channo = channel;
13074 if (
conf->timing.prewinktime >= 0)
13075 p.prewinktime =
conf->timing.prewinktime;
13076 if (
conf->timing.preflashtime >= 0)
13077 p.preflashtime =
conf->timing.preflashtime;
13078 if (
conf->timing.winktime >= 0)
13079 p.winktime =
conf->timing.winktime;
13080 if (
conf->timing.flashtime >= 0)
13081 p.flashtime =
conf->timing.flashtime;
13082 if (
conf->timing.starttime >= 0)
13083 p.starttime =
conf->timing.starttime;
13084 if (
conf->timing.rxwinktime >= 0)
13085 p.rxwinktime =
conf->timing.rxwinktime;
13086 if (
conf->timing.rxflashtime >= 0)
13087 p.rxflashtime =
conf->timing.rxflashtime;
13088 if (
conf->timing.debouncetime >= 0)
13089 p.debouncetime =
conf->timing.debouncetime;
13104 memset(&bi, 0,
sizeof(bi));
13107 bi.txbufpolicy =
conf->chan.buf_policy;
13108 bi.rxbufpolicy =
conf->chan.buf_policy;
13109 bi.numbufs =
conf->chan.buf_no;
13133 if (chan_sig & __DAHDI_SIG_FXS) {
13174 if (
conf->chan.echocanbridged)
13175 ast_log(
LOG_NOTICE,
"echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
13216 ast_log(
LOG_ERROR,
"Invalid SMDI port specified, disabling SMDI support\n");
13244#if defined(HAVE_PRI)
13261#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
13262 tmp->mwisend_setting =
conf->chan.mwisend_setting;
13263 tmp->mwisend_fsk =
conf->chan.mwisend_fsk;
13264 tmp->mwisend_rpas =
conf->chan.mwisend_rpas;
13274 if (
conf->chan.vars) {
13276 for (v =
conf->chan.vars ; v ; v = v->
next) {
13280 tmp->
vars = tmpvar;
13307 switch (chan_sig) {
13319 if ((res =
get_alarms(tmp)) != DAHDI_ALARM_NONE) {
13321 switch (tmp->
sig) {
13327#if defined(HAVE_SS7)
13358 switch (tmp->
sig) {
13359#if defined(HAVE_PRI)
13362#if defined(HAVE_PRI_SERVICE_MESSAGES)
13365 char db_chan_name[20];
13372 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, tmp->
span, tmp->
channel);
13373 if (!
ast_db_get(db_chan_name, SRVST_DBKEY, db_answer,
sizeof(db_answer))) {
13377 if (tmp->pri->enable_service_message_support) {
13380 sscanf(db_answer,
"%1c:%30u", &
state, why);
13383 *why &= (SRVST_NEAREND | SRVST_FAREND);
13393#if defined(HAVE_SS7)
13408 switch (tmp->
sig) {
13409#if defined(HAVE_PRI)
13429#if defined(HAVE_SS7)
13484 switch (
conf->chan.cid_start) {
13503 if (chan_sig & __DAHDI_SIG_FXO) {
13504 memset(&p, 0,
sizeof(p));
13509#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
13510 res = ioctl(tmp->
subs[
SUB_REAL].
dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting);
13523#if defined(HAVE_PRI)
13529 dahdi_pseudo_parms.buf_no = tmp->
buf_no;
13530 dahdi_pseudo_parms.buf_policy = tmp->
buf_policy;
13531 dahdi_pseudo_parms.faxbuf_no = tmp->
faxbuf_no;
13536 if (tmp && !here) {
13545#if defined(HAVE_PRI)
13548 if (!p->pri || p->pri->
span != span) {
13551 if (!groupmatch && channelmatch == -1) {
13560 if ((p->
group & groupmatch) != groupmatch)
13566 if (channelmatch != -1) {
13567 if (p->
channel != channelmatch)
13570 *channelmatched = 1;
13587#if defined(HAVE_PRI)
13599#if defined(HAVE_SS7)
13616 if (p->mfcr2call) {
13629#if defined(HAVE_PRI)
13630#if defined(HAVE_PRI_CALL_WAITING)
13645 pvt->
stripmsd = pri->ch_cfg.stripmsd;
13648 pvt->
immediate = pri->ch_cfg.immediate;
13659#if defined(HAVE_PRI)
13672static int dahdi_new_pri_nobch_channel(
struct sig_pri_span *pri)
13679 struct dahdi_bufferinfo bi;
13684 for (pvt_idx = 0; pvt_idx < pri->
numchans; ++pvt_idx) {
13685 if (!pri->
pvts[pvt_idx]) {
13713 pvt->
buf_no = dahdi_pseudo_parms.buf_no;
13714 pvt->
buf_policy = dahdi_pseudo_parms.buf_policy;
13715 pvt->
faxbuf_no = dahdi_pseudo_parms.faxbuf_no;
13736 pri->
pvts[pvt_idx] = chan;
13740 ast_log(
LOG_ERROR,
"Unable to open no B channel interface pseudo channel: %s\n",
13745 memset(&bi, 0,
sizeof(bi));
13751 bi.numbufs = pvt->
buf_no;
13755 "Unable to set buffer policy on no B channel interface: %s\n",
13760 "Unable to check buffer policy on no B channel interface: %s\n",
13767 pvt->
channel = nobch_channel;
13771 dahdi_nobch_insert(pri, pvt);
13785 struct dahdi_bufferinfo bi;
13816 bi.numbufs = src->
buf_no;
13853 char *subdir =
NULL;
13897 memset(param, 0,
sizeof(*param));
13900 if (strchr(
args.group,
'!') !=
NULL) {
13902 while ((s = strchr(
prev,
'!')) !=
NULL) {
13906 *(
prev - 1) =
'\0';
13909 }
else if (
args.group[0] ==
'i') {
13911 res = sscanf(
args.group + 1,
"%30d", &x);
13919 s = strchr(
args.group,
'-');
13927 if (toupper(
args.group[0]) ==
'G' || toupper(
args.group[0])==
'R') {
13929 s =
args.group + 1;
13930 res = sscanf(s,
"%30d%1c%30d", &x, ¶m->
opt, ¶m->
cadence);
13937 if (toupper(
args.group[0]) ==
'G') {
13938 if (
args.group[0] ==
'G') {
13949 if (
args.group[0] ==
'R') {
13964 if (!strcasecmp(s,
"pseudo")) {
13969 res = sscanf(s,
"%30d%1c%30d", &x, ¶m->
opt, ¶m->
cadence);
13981 snprintf(path,
sizeof(path),
"/dev/dahdi/%s/%d",
13983 if (stat(path, &stbuf) < 0) {
13985 path, strerror(
errno));
13988 if (!S_ISCHR(stbuf.st_mode)) {
13999 if (param->
opt ==
'r' && res < 3) {
14009 const char *
data,
int *cause)
14015 int channelmatched = 0;
14016 int foundowner = 0;
14017 int groupmatched = 0;
14018#if defined(HAVE_PRI) || defined(HAVE_SS7)
14019 int transcapdigital = 0;
14036 while (p && !tmp) {
14052 if (p->mfcr2call) {
14054 ast_debug(1,
"Yay!, someone just beat us in the race for channel %d.\n", p->
channel);
14070 switch (start.
opt) {
14083#if defined(HAVE_PRI) || defined(HAVE_SS7)
14110#if defined(HAVE_SS7)
14119#if defined(HAVE_PRI)
14122#if defined(HAVE_PRI_CALL_WAITING)
14161 if (cause && !tmp) {
14162 if (callwait || (channelmatched && foundowner)) {
14164 }
else if (groupmatched) {
14190#if defined(HAVE_PRI)
14191 const char *device;
14197 if (*device !=
'I') {
14201 res = sscanf(device,
"I%30u", &span);
14202 if (res != 1 || !span ||
NUM_SPANS < span) {
14206 device = strchr(device,
'/');
14216#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
14218 if (!strcmp(device,
"congestion"))
14221 return pris[span - 1].pri.congestion_devstate;
14223#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
14224 else if (!strcmp(device,
"threshold")) {
14225 return pris[span - 1].pri.threshold_devstate;
14255 int groupmatched = 0;
14256 int channelmatched = 0;
14270 const char *monitor_type;
14280#if defined(HAVE_PRI)
14286 snprintf(full_device_name,
sizeof(full_device_name),
14287 "DAHDI/I%d/congestion", p->pri->
span);
14291#if defined(HAVE_PRI)
14296 snprintf(full_device_name,
sizeof(full_device_name),
"DAHDI/%s",
14304 dash = strrchr(full_device_name,
'-');
14309 snprintf(dialstring,
sizeof(dialstring),
"DAHDI/%s", dest);
14319#
if defined(HAVE_PRI)
14324 monitor_type, full_device_name, dialstring,
NULL);
14332 if (p == exitpvt) {
14340#if defined(HAVE_SS7)
14341static void dahdi_ss7_message(
struct ss7 *ss7,
char *s)
14347 if (linksets[i].ss7.ss7 == ss7) {
14357#if defined(HAVE_SS7)
14358static void dahdi_ss7_error(
struct ss7 *ss7,
char *s)
14364 if (linksets[i].ss7.ss7 == ss7) {
14374#if defined(HAVE_OPENR2)
14375static void *mfcr2_monitor(
void *data)
14377 struct dahdi_mfcr2 *mfcr2 = data;
14395 for (i = 0; i < mfcr2->numchans; i++) {
14396 pvt = mfcr2->pvts[i];
14400 openr2_chan_set_idle(pvt->r2chan);
14401 openr2_chan_handle_cas(pvt->r2chan);
14407 for (i = 0; i < mfcr2->numchans; i++) {
14408 pollers[i].revents = 0;
14409 pollers[i].events = 0;
14410 pvt = mfcr2->pvts[i];
14417 if (mfcr2->nodev) {
14420 if (!pvt->r2chan) {
14425 openr2_chan_enable_read(pvt->r2chan);
14426 pollers[i].events = POLLIN | POLLPRI;
14433 if (pollsize == 0) {
14435 ast_debug(1,
"Monitor thread going idle since everybody has an owner\n");
14438 poll(
NULL, 0, maxsleep);
14444 pthread_testcancel();
14445 res = poll(pollers, mfcr2->numchans, maxsleep);
14446 pthread_testcancel();
14447 if ((res < 0) && (
errno != EINTR)) {
14452 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
14453 for (i = 0; i < mfcr2->numchans; i++) {
14454 pvt = mfcr2->pvts[i];
14458 if (pollers[i].revents & POLLPRI || pollers[i].revents & POLLIN) {
14459 openr2_chan_process_event(pvt->r2chan);
14462 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
14469#if defined(HAVE_PRI)
14470static void dahdi_pri_message(
struct pri *pri,
char *s)
14476 int dchancount = 0;
14481 if (pris[x].pri.dchans[y]) {
14485 if (pris[x].pri.dchans[y] == pri) {
14496 if (1 < dchancount) {
14510 if (pridebugfd >= 0) {
14511 if (write(pridebugfd, s, strlen(s)) < 0) {
14520#if defined(HAVE_PRI)
14521static void dahdi_pri_error(
struct pri *pri,
char *s)
14527 int dchancount = 0;
14532 if (pris[x].pri.dchans[y]) {
14536 if (pris[x].pri.dchans[y] == pri) {
14547 if (1 < dchancount) {
14561 if (pridebugfd >= 0) {
14562 if (write(pridebugfd, s, strlen(s)) < 0) {
14571#if defined(HAVE_PRI)
14572static int prepare_pri(
struct dahdi_pri *pri)
14575 struct dahdi_params p;
14576 struct dahdi_bufferinfo bi;
14577 struct dahdi_spaninfo si;
14580 if (!pri->dchannels[i])
14582 if (pri->pri.fds[i] >= 0) {
14586 pri->pri.fds[i] = open(
"/dev/dahdi/channel", O_RDWR);
14587 if ((pri->pri.fds[i] < 0)) {
14589 pri->pri.fds[i], strerror(
errno));
14592 x = pri->dchannels[i];
14593 res = ioctl(pri->pri.fds[i], DAHDI_SPECIFY, &x);
14595 dahdi_close_pri_fd(pri, i);
14599 memset(&p, 0,
sizeof(p));
14600 res = ioctl(pri->pri.fds[i], DAHDI_GET_PARAMS, &p);
14602 dahdi_close_pri_fd(pri, i);
14606 if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC)) {
14607 dahdi_close_pri_fd(pri, i);
14611 memset(&si, 0,
sizeof(si));
14612 res = ioctl(pri->pri.fds[i], DAHDI_SPANSTAT, &si);
14614 dahdi_close_pri_fd(pri, i);
14622 memset(&bi, 0,
sizeof(bi));
14623 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
14624 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
14627 if (ioctl(pri->pri.fds[i], DAHDI_SET_BUFINFO, &bi)) {
14629 dahdi_close_pri_fd(pri, i);
14632 pri->pri.dchan_logical_span[i] = pris[p.spanno - 1].prilogicalspan;
14638#if defined(HAVE_PRI)
14639static char *complete_span_helper(
const char *line,
const char *
word,
int pos,
int state,
int rpos)
14647 for (which = span = 0; span <
NUM_SPANS; span++) {
14648 if (pris[span].pri.pri && ++which >
state) {
14659#if defined(HAVE_PRI)
14660static char *complete_span_4(
const char *line,
const char *
word,
int pos,
int state)
14662 return complete_span_helper(line,
word,pos,
state,3);
14666#if defined(HAVE_PRI)
14672 e->
command =
"pri set debug file";
14673 e->
usage =
"Usage: pri set debug file [output-file]\n"
14674 " Sends PRI debug output to the specified output file\n";
14687 ast_cli(
a->fd,
"Unable to open '%s' for writing\n",
a->argv[4]);
14693 if (pridebugfd >= 0)
14699 ast_cli(
a->fd,
"PRI debug output will be sent to '%s'\n",
a->argv[4]);
14704#if defined(HAVE_PRI)
14705static int action_pri_debug_file_set(
struct mansession *s,
const struct message *m)
14722 if (pridebugfd >= 0) {
14727 ast_copy_string(pridebugfilename, output_file,
sizeof(pridebugfilename));
14729 astman_send_ack(s, m,
"PRI debug output will now be sent to requested file.");
14735#if defined(HAVE_PRI)
14736static int action_pri_debug_file_unset(
struct mansession *s,
const struct message *m)
14740 if (pridebugfd >= 0) {
14753#if defined(HAVE_PRI)
14762 e->
command =
"pri set debug {on|off|hex|intense|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15} span";
14764 "Usage: pri set debug {<level>|on|off|hex|intense} span <span>\n"
14765 " Enables debugging on a given PRI span\n"
14766 " Level is a bitmap of the following values:\n"
14767 " 1 General debugging incl. state changes\n"
14768 " 2 Decoded Q.931 messages\n"
14769 " 4 Decoded Q.921 messages\n"
14770 " 8 Raw hex dumps of Q.921 frames\n"
14771 " on - equivalent to 3\n"
14772 " hex - equivalent to 8\n"
14773 " intense - equivalent to 15\n";
14776 return complete_span_4(
a->line,
a->word,
a->pos,
a->n);
14782 if (!strcasecmp(
a->argv[3],
"on")) {
14784 }
else if (!strcasecmp(
a->argv[3],
"off")) {
14786 }
else if (!strcasecmp(
a->argv[3],
"intense")) {
14788 }
else if (!strcasecmp(
a->argv[3],
"hex")) {
14791 level = atoi(
a->argv[3]);
14793 span = atoi(
a->argv[5]);
14794 if ((span < 1) || (span >
NUM_SPANS)) {
14795 ast_cli(
a->fd,
"Invalid span %s. Should be a number %d to %d\n",
a->argv[5], 1,
NUM_SPANS);
14798 if (!pris[span-1].pri.pri) {
14799 ast_cli(
a->fd,
"No PRI running on span %d\n", span);
14804 if (level & 2) debugmask |= PRI_DEBUG_Q931_DUMP;
14805 if (level & 4) debugmask |= PRI_DEBUG_Q921_DUMP;
14806 if (level & 8) debugmask |= PRI_DEBUG_Q921_RAW;
14810 if (pris[span - 1].pri.dchans[x]) {
14811 pri_set_debug(pris[span - 1].pri.dchans[x], debugmask);
14817 if (0 <= pridebugfd) {
14820 ast_cli(
a->fd,
"Disabled PRI debug output to file '%s'\n",
14825 pris[span - 1].pri.debug = (level) ? 1 : 0;
14826 ast_cli(
a->fd,
"%s debugging on span %d\n", (level) ?
"Enabled" :
"Disabled", span);
14831#if defined(HAVE_PRI)
14851 if (!strcasecmp(level,
"on")) {
14853 }
else if (!strcasecmp(level,
"off")) {
14855 }
else if (!strcasecmp(level,
"intense")) {
14857 }
else if (!strcasecmp(level,
"hex")) {
14860 if (sscanf(level,
"%30d", &level_val) != 1) {
14866 if (sscanf(span,
"%30d", &span_val) != 1) {
14870 if ((span_val < 1) || (span_val >
NUM_SPANS)) {
14872 char id_text[256] =
"";
14875 snprintf(id_text,
sizeof(id_text),
"ActionID: %s\r\n",
id);
14880 "Message: Invalid span '%s' - Should be a number from 1 to %d\r\n"
14888 if (!pris[span_val-1].pri.pri) {
14893 if (level_val & 1) {
14896 if (level_val & 2) {
14897 debugmask |= PRI_DEBUG_Q931_DUMP;
14899 if (level_val & 4) {
14900 debugmask |= PRI_DEBUG_Q921_DUMP;
14902 if (level_val & 8) {
14903 debugmask |= PRI_DEBUG_Q921_RAW;
14908 if (pris[span_val - 1].pri.dchans[x]) {
14909 pri_set_debug(pris[span_val - 1].pri.dchans[x], debugmask);
14913 pris[span_val - 1].pri.debug = (level_val) ? 1 : 0;
14920#if defined(HAVE_PRI)
14921#if defined(HAVE_PRI_SERVICE_MESSAGES)
14927 int x, y, fd =
a->fd;
14928 int interfaceid = 0;
14929 char db_chan_name[20], db_answer[15];
14931 struct dahdi_pri *pri;
14933 if (
a->argc < 5 ||
a->argc > 6)
14935 if (strchr(
a->argv[4],
':')) {
14936 if (sscanf(
a->argv[4],
"%30d:%30d", &trunkgroup, &channel) != 2)
14938 if ((trunkgroup < 1) || (channel < 1))
14942 if (pris[x].pri.trunkgroup == trunkgroup) {
14948 ast_cli(fd,
"No such trunk group %d\n", trunkgroup);
14952 channel = atoi(
a->argv[4]);
14955 interfaceid = atoi(
a->argv[5]);
14960 if (pris[x].dchannels[y] == channel) {
14962 if (pri->pri.enable_service_message_support) {
14964 pri_maintenance_service(pri->pri.pri, interfaceid, -1, changestatus);
14968 "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n"
14969 "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n");
14979 if (tmp->pri && tmp->
channel == channel) {
14982 if (!tmp->pri->enable_service_message_support) {
14985 "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n"
14986 "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n");
14989 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, tmp->
span, channel);
14991 switch(changestatus) {
14995 *why &= ~SRVST_NEAREND;
14997 snprintf(db_answer,
sizeof(db_answer),
"%s:%u", SRVST_TYPE_OOS, *why);
14998 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
15000 dahdi_pri_update_span_devstate(tmp->pri);
15007 *why |= SRVST_NEAREND;
15008 snprintf(db_answer,
sizeof(db_answer),
"%s:%u", SRVST_TYPE_OOS, *why);
15009 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
15010 dahdi_pri_update_span_devstate(tmp->pri);
15018 pri_maintenance_bservice(tmp->pri->pri, tmp->
sig_pvt, changestatus);
15025 ast_cli(fd,
"Unable to find given channel %d, possibly not a PRI\n",
channel);
15033 e->
command =
"pri service enable channel";
15035 "Usage: pri service enable channel <channel> [<interface id>]\n"
15036 " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n"
15037 " to restore a channel to service, with optional interface id\n"
15038 " as agreed upon with remote switch operator\n";
15043 return handle_pri_service_generic(e, cmd,
a, 0);
15050 e->
command =
"pri service disable channel";
15052 "Usage: pri service disable channel <chan num> [<interface id>]\n"
15053 " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n"
15054 " to remove a channel from service, with optional interface id\n"
15055 " as agreed upon with remote switch operator\n";
15060 return handle_pri_service_generic(e, cmd,
a, 2);
15065#if defined(HAVE_PRI)
15072 e->
command =
"pri show channels";
15074 "Usage: pri show channels\n"
15075 " Displays PRI channel information such as the current mapping\n"
15076 " of DAHDI B channels to Asterisk channel names and which calls\n"
15077 " are on hold or call-waiting. Calls on hold or call-waiting\n"
15078 " are not associated with any B channel.\n";
15088 for (span = 0; span <
NUM_SPANS; ++span) {
15089 if (pris[span].
pri.
pri) {
15097#if defined(HAVE_PRI)
15104 e->
command =
"pri show spans";
15106 "Usage: pri show spans\n"
15107 " Displays PRI span information\n";
15116 for (span = 0; span <
NUM_SPANS; span++) {
15117 if (pris[span].
pri.
pri) {
15125#if defined(HAVE_PRI)
15126#define container_of(ptr, type, member) \
15127 ((type *)((char *)(ptr) - offsetof(type, member)))
15144 struct dahdi_pri* dahdi_pri;
15145 pthread_t master = pri->
master;
15150 ast_debug(2,
"About to destroy DAHDI channels of span %d.\n", pri->
span);
15151 for (i = 0; i < pri->
numchans; i++) {
15163 cancel_code = pthread_cancel(master);
15164 pthread_kill(master, SIGURG);
15166 "Waiting to join thread of span %d "
15167 "with pid=%p cancel_code=%d\n",
15168 pri->
span, (
void *)master, cancel_code);
15169 res = pthread_join(master,
NULL);
15178 ast_debug(4,
"closing pri_fd %d\n", i);
15179 dahdi_close_pri_fd(dahdi_pri, i);
15180 dahdi_pri->dchannels[i] = 0;
15186static char *handle_pri_destroy_span(
struct ast_cli_entry *e,
int cmd,
15195 e->
command =
"pri destroy span";
15197 "Usage: pri destroy span <span>\n"
15198 " Destroys D-channel of span and its B-channels.\n"
15199 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n";
15202 return complete_span_4(
a->line,
a->word,
a->pos,
a->n);
15208 res = sscanf(
a->argv[3],
"%30d", &
span);
15209 if ((res != 1) || span < 1 || span >
NUM_SPANS) {
15211 "Invalid span '%s'. Should be a number from %d to %d\n",
15221 pri_destroy_span(
pri);
15227#if defined(HAVE_PRI)
15234 e->
command =
"pri show span";
15236 "Usage: pri show span <span>\n"
15237 " Displays PRI Information on a given PRI span\n";
15240 return complete_span_4(
a->line,
a->word,
a->pos,
a->n);
15245 span = atoi(
a->argv[3]);
15247 ast_cli(
a->fd,
"Invalid span '%s'. Should be a number from %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
15261#if defined(HAVE_PRI)
15271 e->
command =
"pri show debug";
15273 "Usage: pri show debug\n"
15274 " Show the debug state of pri spans\n";
15283 if (pris[
span].
pri.dchans[x]) {
15285 ast_cli(
a->fd,
"Span %d: Debug: %s\tIntense: %s\n",
span+1, (
debug&PRI_DEBUG_Q931_STATE)?
"Yes" :
"No" ,(
debug&PRI_DEBUG_Q921_RAW)?
"Yes" :
"No" );
15293 if (pridebugfd >= 0)
15294 ast_cli(
a->fd,
"Logging PRI debug to file %s\n", pridebugfilename);
15298 ast_cli(
a->fd,
"No PRI running\n");
15303#if defined(HAVE_PRI)
15308 e->
command =
"pri show version";
15310 "Usage: pri show version\n"
15311 "Show libpri version information\n";
15317 ast_cli(
a->fd,
"libpri version: %s\n", pri_get_version());
15323#if defined(HAVE_PRI)
15325 AST_CLI_DEFINE(handle_pri_debug,
"Enables PRI debugging on a span"),
15326#if defined(HAVE_PRI_SERVICE_MESSAGES)
15327 AST_CLI_DEFINE(handle_pri_service_enable_channel,
"Return a channel to service"),
15328 AST_CLI_DEFINE(handle_pri_service_disable_channel,
"Remove a channel from service"),
15330 AST_CLI_DEFINE(handle_pri_show_channels,
"Displays PRI channel information"),
15331 AST_CLI_DEFINE(handle_pri_show_spans,
"Displays PRI span information"),
15332 AST_CLI_DEFINE(handle_pri_show_span,
"Displays PRI span information"),
15334 AST_CLI_DEFINE(handle_pri_show_debug,
"Displays current PRI debug settings"),
15335 AST_CLI_DEFINE(handle_pri_set_debug_file,
"Sends PRI debug output to the specified file"),
15346 e->
command =
"mfcr2 show version";
15348 "Usage: mfcr2 show version\n"
15349 " Shows the version of the OpenR2 library being used.\n";
15354 ast_cli(
a->fd,
"OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision());
15360#define FORMAT "%4s %40s\n"
15362 int numvariants = 0;
15363 const openr2_variant_entry_t *variants;
15366 e->
command =
"mfcr2 show variants";
15368 "Usage: mfcr2 show variants\n"
15369 " Shows the list of MFC/R2 variants supported.\n";
15374 if (!(variants = openr2_proto_get_variant_list(&numvariants))) {
15375 ast_cli(
a->fd,
"Failed to get list of variants.\n");
15379 for (i = 0; i < numvariants; i++) {
15388#define FORMAT "%4s %4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n"
15389 int filtertype = 0;
15396 openr2_context_t *r2context;
15397 openr2_variant_t r2variant;
15400 e->
command =
"mfcr2 show channels [group|context]";
15402 "Usage: mfcr2 show channels [group <group> | context <context>]\n"
15403 " Shows the DAHDI channels configured with MFC/R2 signaling.\n";
15408 if (!((
a->argc == 3) || (
a->argc == 5))) {
15411 if (
a->argc == 5) {
15412 if (!strcasecmp(
a->argv[3],
"group")) {
15413 targetnum = atoi(
a->argv[4]);
15414 if ((targetnum < 0) || (targetnum > 63))
15416 targetnum = 1 << targetnum;
15418 }
else if (!strcasecmp(
a->argv[3],
"context")) {
15424 ast_cli(
a->fd,
FORMAT,
"Chan",
"Link#",
"Variant",
"Max ANI",
"Max DNIS",
"ANI First",
"Immediate Accept",
"Tx CAS",
"Rx CAS");
15431 switch(filtertype) {
15433 if (p->
group != targetnum) {
15438 if (strcasecmp(p->
context,
a->argv[4])) {
15446 r2context = openr2_chan_get_context(p->r2chan);
15447 r2variant = openr2_context_get_variant(r2context);
15448 snprintf(channo,
sizeof(channo),
"%d", p->
channel);
15449 snprintf(linkno,
sizeof(linkno),
"%d", p->mfcr2->index);
15450 snprintf(anino,
sizeof(anino),
"%d", openr2_context_get_max_ani(r2context));
15451 snprintf(dnisno,
sizeof(dnisno),
"%d", openr2_context_get_max_dnis(r2context));
15452 ast_cli(
a->fd,
FORMAT, channo, linkno, openr2_proto_get_variant_string(r2variant),
15453 anino, dnisno, openr2_context_get_ani_first(r2context) ?
"Yes" :
"No",
15454 openr2_context_get_immediate_accept(r2context) ?
"Yes" :
"No",
15455 openr2_chan_get_tx_cas_string(p->r2chan), openr2_chan_get_rx_cas_string(p->r2chan));
15466 char *toklevel =
NULL;
15467 char *saveptr =
NULL;
15468 char *logval =
NULL;
15469 openr2_log_level_t loglevel = OR2_LOG_NOTHING;
15470 openr2_log_level_t tmplevel = OR2_LOG_NOTHING;
15473 e->
command =
"mfcr2 set debug";
15475 "Usage: mfcr2 set debug <loglevel> <channel>\n"
15476 " Set a new logging level for the specified channel.\n"
15477 " If no channel is specified the logging level will be applied to all channels.\n";
15485 channo = (
a->argc == 5) ? atoi(
a->argv[4]) : -1;
15487 toklevel = strtok_r(logval,
",", &saveptr);
15488 if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
15489 ast_cli(
a->fd,
"Invalid MFC/R2 logging level '%s'.\n",
a->argv[3]);
15491 }
else if (OR2_LOG_NOTHING == tmplevel) {
15492 loglevel = tmplevel;
15494 loglevel |= tmplevel;
15495 while ((toklevel = strtok_r(
NULL,
",", &saveptr))) {
15496 if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
15497 ast_cli(
a->fd,
"Ignoring invalid logging level: '%s'.\n", toklevel);
15500 loglevel |= tmplevel;
15508 if ((channo != -1) && (p->
channel != channo )) {
15511 openr2_chan_set_log_level(p->r2chan, loglevel);
15512 if (channo != -1) {
15513 ast_cli(
a->fd,
"MFC/R2 debugging set to '%s' for channel %d.\n",
a->argv[3], p->
channel);
15517 if ((channo != -1) && !p) {
15518 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15520 if (channo == -1) {
15521 ast_cli(
a->fd,
"MFC/R2 debugging set to '%s' for all channels.\n",
a->argv[3]);
15533 e->
command =
"mfcr2 call files [on|off]";
15535 "Usage: mfcr2 call files [on|off] <channel>\n"
15536 " Enable call files creation on the specified channel.\n"
15537 " If no channel is specified call files creation policy will be applied to all channels.\n";
15545 channo = (
a->argc == 5) ? atoi(
a->argv[4]) : -1;
15551 if ((channo != -1) && (p->
channel != channo )) {
15555 openr2_chan_enable_call_files(p->r2chan);
15557 openr2_chan_disable_call_files(p->r2chan);
15559 if (channo != -1) {
15561 ast_cli(
a->fd,
"MFC/R2 call files enabled for channel %d.\n", p->
channel);
15563 ast_cli(
a->fd,
"MFC/R2 call files disabled for channel %d.\n", p->
channel);
15568 if ((channo != -1) && !p) {
15569 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15571 if (channo == -1) {
15573 ast_cli(
a->fd,
"MFC/R2 Call files enabled for all channels.\n");
15575 ast_cli(
a->fd,
"MFC/R2 Call files disabled for all channels.\n");
15588 e->
command =
"mfcr2 set idle";
15590 "Usage: mfcr2 set idle <channel>\n"
15591 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
15592 " Force the given channel into IDLE state.\n"
15593 " If no channel is specified, all channels will be set to IDLE.\n";
15598 channo = (
a->argc == 4) ? atoi(
a->argv[3]) : -1;
15604 if ((channo != -1) && (p->
channel != channo )) {
15607 openr2_chan_set_idle(p->r2chan);
15612 if (channo != -1) {
15616 if ((channo != -1) && !p) {
15617 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15629 e->
command =
"mfcr2 set blocked";
15631 "Usage: mfcr2 set blocked <channel>\n"
15632 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
15633 " Force the given channel into BLOCKED state.\n"
15634 " If no channel is specified, all channels will be set to BLOCKED.\n";
15639 channo = (
a->argc == 4) ? atoi(
a->argv[3]) : -1;
15645 if ((channo != -1) && (p->
channel != channo )) {
15648 openr2_chan_set_blocked(p->r2chan);
15652 if (channo != -1) {
15656 if ((channo != -1) && !p) {
15657 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15663static void mfcr2_show_links_of(
struct ast_cli_args *
a,
struct r2links *list_head,
const char *title)
15665#define FORMAT "%-5s %-10s %-15s %-10s %s\n"
15669 char live_chans_str[5];
15670 char channel_list[R2_LINK_CAPACITY * 4];
15671 struct r2link_entry *cur;
15673 ast_cli(
a->fd,
FORMAT,
"Index",
"Thread",
"Dahdi-Device",
"Channels",
"Channel-List");
15675 struct dahdi_mfcr2 *mfcr2 = &cur->mfcr2;
15676 const char *thread_status =
NULL;
15683 if (mfcr2->r2master == 0L) {
15684 thread_status =
"zero";
15686 thread_status =
"none";
15688 thread_status =
"created";
15690 snprintf(index,
sizeof(index),
"%d", mfcr2->index);
15691 snprintf(live_chans_str,
sizeof(live_chans_str),
"%d", mfcr2->live_chans);
15697 for (i = 0; i < mfcr2->numchans &&
len <
sizeof(channel_list) - 1; i++) {
15704 if (prev_channo && prev_channo == channo - 1) {
15705 prev_channo = channo;
15709 if (inside_range) {
15711 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
"-%d,%d", prev_channo, channo);
15713 }
else if (prev_channo) {
15715 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
",%d", channo);
15718 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
"%d", channo);
15720 prev_channo = channo;
15723 if (inside_range) {
15725 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
"-%d", channo);
15727 }
else if (prev_channo) {
15729 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
",%d", channo);
15735 (mfcr2->nodev) ?
"MISSING" :
"OK",
15748 e->
command =
"mfcr2 show links";
15750 "Usage: mfcr2 show links\n"
15751 " Shows the DAHDI MFC/R2 links.\n";
15756 if (
a->argc != 3) {
15759 mfcr2_show_links_of(
a, &r2links,
"Live links\n");
15760 mfcr2_show_links_of(
a, &nodev_r2links,
"Links to be removed (device missing)\n");
15767 int wanted_link_index;
15768 int found_link = 0;
15769 struct r2link_entry *cur =
NULL;
15773 e->
command =
"mfcr2 destroy link";
15775 "Usage: mfcr2 destroy link <index-number>\n"
15776 " Destroys D-channel of link and its B-channels.\n"
15777 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n";
15785 res = sscanf(
a->argv[3],
"%30d", &wanted_link_index);
15786 if ((res != 1) || wanted_link_index < 1) {
15788 "Invalid link index '%s'. Should be a positive number\n",
a->argv[3]);
15793 struct dahdi_mfcr2 *mfcr2 = &cur->mfcr2;
15794 if (wanted_link_index == mfcr2->index) {
15802 if (! found_link) {
15803 ast_cli(
a->fd,
"No link found with index %d.\n", wanted_link_index);
15810 AST_CLI_DEFINE(handle_mfcr2_version,
"Show OpenR2 library version"),
15811 AST_CLI_DEFINE(handle_mfcr2_show_variants,
"Show supported MFC/R2 variants"),
15812 AST_CLI_DEFINE(handle_mfcr2_show_channels,
"Show MFC/R2 channels"),
15814 AST_CLI_DEFINE(handle_mfcr2_set_debug,
"Set MFC/R2 channel logging level"),
15815 AST_CLI_DEFINE(handle_mfcr2_call_files,
"Enable/Disable MFC/R2 call files"),
15816 AST_CLI_DEFINE(handle_mfcr2_set_idle,
"Reset MFC/R2 channel forcing it to IDLE"),
15817 AST_CLI_DEFINE(handle_mfcr2_set_blocked,
"Reset MFC/R2 channel forcing it to BLOCKED"),
15818 AST_CLI_DEFINE(handle_mfcr2_destroy_link,
"Destroy given MFC/R2 link"),
15829 e->
command =
"dahdi destroy channels";
15831 "Usage: dahdi destroy channels <from_channel> [<to_channel>]\n"
15832 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n";
15837 if ((
a->argc < 4) ||
a->argc > 5) {
15840 start = atoi(
a->argv[3]);
15842 ast_cli(
a->fd,
"Invalid starting channel number %s.\n",
15846 if (
a->argc == 5) {
15847 end = atoi(
a->argv[4]);
15849 ast_cli(
a->fd,
"Invalid ending channel number %s.\n",
15859 "range end (%d) is smaller than range start (%d)\n",
15875 e->
command =
"dahdi create channels";
15876 e->
usage =
"Usage: dahdi create channels <from> [<to>] - a range of channels\n"
15877 " dahdi create channels new - add channels not yet created\n"
15878 "For ISDN and SS7 the range should include complete spans.\n";
15883 if ((
a->argc < 4) ||
a->argc > 5) {
15886 if (
a->argc == 4 && !strcmp(
a->argv[3],
"new")) {
15890 start = atoi(
a->argv[3]);
15892 ast_cli(
a->fd,
"Invalid starting channel number '%s'.\n",
15896 if (
a->argc == 5) {
15897 end = atoi(
a->argv[4]);
15899 ast_cli(
a->fd,
"Invalid ending channel number '%s'.\n",
15908 "range end (%d) is smaller than range start (%d)\n",
15946#if defined(HAVE_PRI) || defined(HAVE_SS7)
15953 ast_verb(1,
"Destroying channels and reloading DAHDI configuration.\n");
15955 ast_verb(4,
"Initial softhangup of all DAHDI channels complete.\n");
15957 dahdi_r2_destroy_links();
15960#if defined(HAVE_PRI)
15963 cancel_code = pthread_cancel(pris[i].pri.
master);
15964 pthread_kill(pris[i].pri.
master, SIGURG);
15965 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);
15967 ast_debug(4,
"Joined thread of span %d\n", i);
15972#if defined(HAVE_SS7)
15975 cancel_code = pthread_cancel(linksets[i].ss7.master);
15976 pthread_kill(linksets[i].ss7.master, SIGURG);
15977 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);
15978 pthread_join(linksets[i].ss7.master,
NULL);
15979 ast_debug(4,
"Joined thread of span %d\n", i);
15988 ast_debug(4,
"Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (
void *)
monitor_thread, cancel_code);
15990 ast_debug(4,
"Joined monitor thread\n");
15996 int x = DAHDI_FLASH;
16012 ast_verb(4,
"Final softhangup of all DAHDI channels complete.\n");
16022 dahdi_close_pri_fd(&(pris[i]), j);
16025 memset(pris, 0,
sizeof(pris));
16029 pri_set_error(dahdi_pri_error);
16030 pri_set_message(dahdi_pri_message);
16032#if defined(HAVE_SS7)
16035 dahdi_close_ss7_fd(&(linksets[i]), j);
16038 memset(linksets, 0,
sizeof(linksets));
16042 ss7_set_error(dahdi_ss7_error);
16043 ss7_set_message(dahdi_ss7_message);
16063 e->
command =
"dahdi restart";
16065 "Usage: dahdi restart\n"
16066 " Restarts the DAHDI channels: destroys them all and then\n"
16067 " re-reads them from chan_dahdi.conf.\n"
16068 " Note that this will STOP any running CALL on DAHDI channels.\n"
16094#define FORMAT "%7s %4d %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"
16095#define FORMAT2 "%7s %4s %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"
16097 int filtertype = 0;
16104 e->
command =
"dahdi show channels [group|context]";
16106 "Usage: dahdi show channels [ group <group> | context <context> ]\n"
16107 " Shows a list of available channels with optional filtering\n"
16108 " <group> must be a number between 0 and 63\n";
16116 if (!((
a->argc == 3) || (
a->argc == 5))) {
16120 if (
a->argc == 5) {
16121 if (!strcasecmp(
a->argv[3],
"group")) {
16122 targetnum = atoi(
a->argv[4]);
16123 if (63 < targetnum) {
16128 }
else if (!strcasecmp(
a->argv[3],
"context")) {
16133 ast_cli(
a->fd,
FORMAT2,
"Chan",
"Span",
"Signalling",
"Extension",
"Context",
"Language",
"MOH Interpret",
"Blocked",
"In Service",
"Alarms",
"Description");
16138 switch(filtertype) {
16140 if (!(tmp->
group & targetnum)) {
16145 if (strcasecmp(tmp->
context,
a->argv[4])) {
16154 snprintf(tmps,
sizeof(tmps),
"%d", tmp->
channel);
16162 blockstr[2] =
'\0';
16164 ast_cli(
a->fd,
FORMAT, tmps, tmp->
span,
sig2str(tmp->
sig), tmp->
exten, tmp->
context, tmp->
language, tmp->
mohinterpret, blockstr, tmp->
inservice ?
"Yes" :
"No",
16177 struct dahdi_confinfo ci;
16178 struct dahdi_params ps;
16185 e->
command =
"dahdi show channel";
16187 "Usage: dahdi show channel <chan num>\n"
16188 " Detailed information about a given channel\n";
16197 channel = atoi(
a->argv[3]);
16201 if (tmp->
channel == channel) {
16211#if defined(HAVE_PRI)
16212#if defined(HAVE_PRI_SUBADDR)
16221 for (v = tmp->
vars ; v ; v = v->
next)
16235 ast_cli(
a->fd,
"DSP: %s\n", tmp->
dsp ?
"yes" :
"no");
16238#if defined(BUSYDETECT_TONEONLY)
16239 ast_cli(
a->fd,
" Busy Detector Helper: BUSYDETECT_TONEONLY\n");
16240#elif defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
16241 ast_cli(
a->fd,
" Busy Detector Helper: BUSYDETECT_COMPARE_TONE_AND_SILENCE\n");
16243#ifdef BUSYDETECT_DEBUG
16244 ast_cli(
a->fd,
" Busy Detector Debug: Enabled\n");
16249 ast_cli(
a->fd,
"TDD: %s\n", tmp->
tdd ?
"yes" :
"no");
16256 snprintf(hwrxgain,
sizeof(hwrxgain),
"%.1f", tmp->
hwrxgain);
16261 snprintf(hwtxgain,
sizeof(hwtxgain),
"%.1f", tmp->
hwtxgain);
16265 ast_cli(
a->fd,
"HW Gains (RX/TX): %s/%s\n", hwrxgain, hwtxgain);
16267 ast_cli(
a->fd,
"Dynamic Range Compression (RX/TX): %.2f/%.2f\n", tmp->
rxdrc, tmp->
txdrc);
16269 ast_cli(
a->fd,
"Echo Cancellation:\n");
16289 char calldir[OR2_MAX_PATH];
16290 openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan);
16291 openr2_variant_t r2variant = openr2_context_get_variant(r2context);
16292 ast_cli(
a->fd,
"MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan));
16293 ast_cli(
a->fd,
"MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan));
16294 ast_cli(
a->fd,
"MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan));
16295 ast_cli(
a->fd,
"MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan));
16296 ast_cli(
a->fd,
"MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ?
"Yes" :
"No");
16297 ast_cli(
a->fd,
"MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant));
16298 ast_cli(
a->fd,
"MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context));
16299 ast_cli(
a->fd,
"MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context));
16300#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
16301 ast_cli(
a->fd,
"MFC/R2 DTMF Dialing: %s\n", openr2_context_get_dtmf_dialing(r2context,
NULL,
NULL) ?
"Yes" :
"No");
16302 ast_cli(
a->fd,
"MFC/R2 DTMF Detection: %s\n", openr2_context_get_dtmf_detection(r2context) ?
"Yes" :
"No");
16304 ast_cli(
a->fd,
"MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ?
"Yes" :
"No");
16305#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
16306 ast_cli(
a->fd,
"MFC/R2 Skip Category Request: %s\n", openr2_context_get_skip_category_request(r2context) ?
"Yes" :
"No");
16308 ast_cli(
a->fd,
"MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ?
"Yes" :
"No");
16309 ast_cli(
a->fd,
"MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ?
"Yes" :
"No");
16310 ast_cli(
a->fd,
"MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ?
"Yes" :
"No");
16311 ast_cli(
a->fd,
"MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ?
"Yes" :
"No");
16312 ast_cli(
a->fd,
"MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ?
"Yes" :
"No");
16313 ast_cli(
a->fd,
"MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context));
16314 ast_cli(
a->fd,
"MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context));
16315 ast_cli(
a->fd,
"MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan));
16316 ast_cli(
a->fd,
"MFC/R2 Tx CAS: %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan));
16317 ast_cli(
a->fd,
"MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan));
16318 ast_cli(
a->fd,
"MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan));
16319 ast_cli(
a->fd,
"MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir,
sizeof(calldir)));
16322#if defined(HAVE_SS7)
16343 if (tmp->logicalspan)
16344 ast_cli(
a->fd,
"PRI Logical Span: %d\n", tmp->logicalspan);
16346 ast_cli(
a->fd,
"PRI Logical Span: Implicit\n");
16349 memset(&ci, 0,
sizeof(ci));
16352 memset(&ci, 0,
sizeof(ci));
16354 ast_cli(
a->fd,
"Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, (
unsigned)ci.confmode);
16357 ast_cli(
a->fd,
"Actual Confmute: %s\n", x ?
"Yes" :
"No");
16359 memset(&ps, 0,
sizeof(ps));
16363 ast_cli(
a->fd,
"Hookstate (FXS only): %s\n", ps.rxisoffhook ?
"Offhook" :
"Onhook");
16381 e->
command =
"dahdi show cadences";
16383 "Usage: dahdi show cadences\n"
16384 " Shows all cadences currently defined\n";
16391 char tmp[16], tmp2[64];
16392 snprintf(tmp,
sizeof(tmp),
"r%d: ", i + 1);
16395 for (j = 0; j < 16; j++) {
16396 if (
cadences[i].ringcadence[j] == 0)
16398 snprintf(tmp,
sizeof(tmp),
"%d",
cadences[i].ringcadence[j]);
16404 strncat(output,
",",
sizeof(output) - strlen(output) - 1);
16405 strncat(output, tmp2,
sizeof(output) - strlen(output) - 1);
16414 alarmstr[0] =
'\0';
16415 if (spaninfo->alarms > 0) {
16416 if (spaninfo->alarms & DAHDI_ALARM_BLUE) {
16417 strcat(alarmstr,
"BLU/");
16419 if (spaninfo->alarms & DAHDI_ALARM_YELLOW) {
16420 strcat(alarmstr,
"YEL/");
16422 if (spaninfo->alarms & DAHDI_ALARM_RED) {
16423 strcat(alarmstr,
"RED/");
16425 if (spaninfo->alarms & DAHDI_ALARM_LOOPBACK) {
16426 strcat(alarmstr,
"LB/");
16428 if (spaninfo->alarms & DAHDI_ALARM_RECOVER) {
16429 strcat(alarmstr,
"REC/");
16431 if (spaninfo->alarms & DAHDI_ALARM_NOTOPEN) {
16432 strcat(alarmstr,
"NOP/");
16434 if (!strlen(alarmstr)) {
16435 strcat(alarmstr,
"UUU/");
16437 if (strlen(alarmstr)) {
16439 alarmstr[strlen(alarmstr) - 1] =
'\0';
16442 if (spaninfo->numchans) {
16443 strcpy(alarmstr,
"OK");
16445 strcpy(alarmstr,
"UNCONFIGURED");
16453 #define FORMAT "%4d %-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n"
16454 #define FORMAT2 "%4s %-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n"
16460 struct dahdi_spaninfo s;
16464 e->
command =
"dahdi show status";
16466 "Usage: dahdi show status\n"
16467 " Shows a list of DAHDI cards with status\n";
16472 ctl = open(
"/dev/dahdi/ctl", O_RDWR);
16474 ast_cli(
a->fd,
"No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(
errno));
16477 ast_cli(
a->fd,
FORMAT2,
"Span",
"Description",
"Alarms",
"IRQ",
"bpviol",
"CRC",
"Framing",
"Coding",
"Options",
"LBO");
16479 for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
16481 res = ioctl(ctl, DAHDI_SPANSTAT, &s);
16486 ast_cli(
a->fd,
FORMAT, span, s.desc, alarmstr, s.irqmisses, s.bpvcount, s.crc4count,
16487 s.lineconfig & DAHDI_CONFIG_D4 ?
"D4" :
16488 s.lineconfig & DAHDI_CONFIG_ESF ?
"ESF" :
16489 s.lineconfig & DAHDI_CONFIG_CCS ?
"CCS" :
16491 s.lineconfig & DAHDI_CONFIG_B8ZS ?
"B8ZS" :
16492 s.lineconfig & DAHDI_CONFIG_HDB3 ?
"HDB3" :
16493 s.lineconfig & DAHDI_CONFIG_AMI ?
"AMI" :
16495 s.lineconfig & DAHDI_CONFIG_CRC4 ?
16496 s.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"CRC4/YEL" :
"CRC4" :
16497 s.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"YEL" :
"",
16510 int pseudo_fd = -1;
16511 struct dahdi_versioninfo vi;
16515 e->
command =
"dahdi show version";
16517 "Usage: dahdi show version\n"
16518 " Shows the DAHDI version in use\n";
16523 if ((pseudo_fd = open(
"/dev/dahdi/ctl", O_RDONLY)) < 0) {
16524 ast_cli(
a->fd,
"Failed to open control file to get version.\n");
16528 strcpy(vi.version,
"Unknown");
16529 strcpy(vi.echo_canceller,
"Unknown");
16531 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi))
16532 ast_cli(
a->fd,
"Failed to get DAHDI version: %s\n", strerror(
errno));
16534 ast_cli(
a->fd,
"DAHDI Version: %s Echo Canceller: %s\n", vi.version, vi.echo_canceller);
16550 e->
command =
"dahdi set hwgain {rx|tx}";
16552 "Usage: dahdi set hwgain <rx|tx> <chan#> <gain>\n"
16553 " Sets the hardware gain on a given channel and overrides the\n"
16554 " value provided at module loadtime. Changes take effect\n"
16555 " immediately whether the channel is in use or not.\n"
16557 " <rx|tx> which direction do you want to change (relative to our module)\n"
16558 " <chan num> is the channel number relative to the device\n"
16559 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"
16562 " * hwgain is only supportable by hardware with analog ports because\n"
16563 " hwgain works on the analog side of an analog-digital conversion.\n";
16572 if (!strcasecmp(
"rx",
a->argv[3]))
16574 else if (!strcasecmp(
"tx",
a->argv[3]))
16580 gain = atof(
a->argv[5]);
16593 ast_cli(
a->fd,
"Unable to set the hardware gain for channel %d: %s\n",
channel, strerror(
errno));
16597 ast_cli(
a->fd,
"Hardware %s gain set to %.1f dB on channel %d.\n",
16598 tx ?
"tx" :
"rx", gain,
channel);
16630 e->
command =
"dahdi set swgain {rx|tx}";
16632 "Usage: dahdi set swgain <rx|tx> <chan#> <gain>\n"
16633 " Sets the software gain on a given channel and overrides the\n"
16634 " value provided at module loadtime. Changes take effect\n"
16635 " immediately whether the channel is in use or not.\n"
16637 " <rx|tx> which direction do you want to change (relative to our module)\n"
16638 " <chan num> is the channel number relative to the device\n"
16639 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n";
16648 if (!strcasecmp(
"rx",
a->argv[3]))
16650 else if (!strcasecmp(
"tx",
a->argv[3]))
16656 gain = atof(
a->argv[5]);
16673 ast_cli(
a->fd,
"Unable to set the software gain for channel %d\n",
channel);
16678 ast_cli(
a->fd,
"Software %s gain set to %.2f dB on channel %d.\n",
16679 tx ?
"tx" :
"rx", gain,
channel);
16706 e->
command =
"dahdi set dnd";
16708 "Usage: dahdi set dnd <chan#> <on|off>\n"
16709 " Sets/resets DND (Do Not Disturb) mode on a channel.\n"
16710 " Changes take effect immediately.\n"
16711 " <chan num> is the channel number\n"
16712 " <on|off> Enable or disable DND mode?\n"
16722 if ((
channel = atoi(
a->argv[3])) <= 0) {
16723 ast_cli(
a->fd,
"Expected channel number, got '%s'\n",
a->argv[3]);
16732 ast_cli(
a->fd,
"Expected 'on' or 'off', got '%s'\n",
a->argv[4]);
16737 for (dahdi_chan =
iflist; dahdi_chan; dahdi_chan = dahdi_chan->
next) {
16764 e->
command =
"dahdi set mwi";
16766 "Usage: dahdi set mwi <chan#> <on|off|reset>\n"
16767 " Sets/unsets MWI (Message Waiting Indicator) manually on a channel.\n"
16768 " This may be used regardless of whether the channel is assigned any mailboxes.\n"
16769 " When active, this setting will override the voicemail status to set MWI.\n"
16770 " Once cleared, the voicemail status will resume control of MWI.\n"
16771 " Changes are queued for when the channel is idle and persist until cleared.\n"
16772 " <chan num> is the channel number\n"
16773 " <on|off|reset> Enable, disable, or reset Message Waiting Indicator override?\n"
16783 if ((
channel = atoi(
a->argv[3])) <= 0) {
16784 ast_cli(
a->fd,
"Expected channel number, got '%s'\n",
a->argv[3]);
16792 }
else if (!strcmp(
a->argv[4],
"reset")) {
16795 ast_cli(
a->fd,
"Expected 'on' or 'off' or 'reset', got '%s'\n",
a->argv[4]);
16800 for (dahdi_chan =
iflist; dahdi_chan; dahdi_chan = dahdi_chan->
next) {
16807 ast_cli(
a->fd,
"MWI '%s' queued for channel %d\n", on ?
"enable" :
"disable",
channel);
16885 if (sscanf(
channel,
"%30d", &chan_num) != 1) {
16904#define REQUIRE_FXO_SIG() \
16905 if (!(dahdip->sigtype & __DAHDI_SIG_FXO)) { \
16906 ast_log(LOG_WARNING, "DAHDI channel %d is not FXO signalled\n", p->channel); \
16915 if (!strcasecmp(property,
"owner")) {
16917 }
else if (!strcasecmp(property,
"callwait")) {
16919 }
else if (!strcasecmp(property,
"threeway")) {
16922 }
else if (!strcasecmp(property,
"polarity")) {
16925 }
else if (!strcasecmp(property,
"dnd")) {
16927 snprintf(buffer,
len,
"%d", analog_p->
dnd);
16928 }
else if (!strcasecmp(property,
"callforward")) {
16931 }
else if (!strcasecmp(property,
"lastexten")) {
16949 if (!strcasecmp(property,
"owner") || !strcasecmp(property,
"callwait") || !strcasecmp(property,
"threeway")) {
16953 }
else if (!strcasecmp(property,
"polarity")) {
16961 }
else if (!strcasecmp(property,
"dnd")) {
16965 }
else if (!strcasecmp(property,
"callforward")) {
16971 }
else if (!strcasecmp(property,
"lastexten")) {
16983#undef REQUIRE_FXO_SIG
16989 struct dahdi_params dahdip;
17005 int channo = atoi(
args.dahdichan);
17020 memset(&dahdip, 0,
sizeof(dahdip));
17048 .
name =
"DAHDI_CHANNEL",
17057 struct dahdi_params dahdip;
17063 memset(&dahdip, 0,
sizeof(dahdip));
17073 struct dahdi_params dahdip;
17079 memset(&dahdip, 0,
sizeof(dahdip));
17088 .
name =
"POLARITY",
17201 for (i = 0; i < strlen(
number); i++) {
17216 int dahdichanquery;
17218 if (!dahdichannel || sscanf(dahdichannel,
"%30d", &dahdichanquery) != 1) {
17220 dahdichanquery = -1;
17225 snprintf(idText,
sizeof(idText),
"ActionID: %s\r\n",
id);
17237 if (dahdichanquery > 0 && tmp->
channel != dahdichanquery)
17245 "Event: DAHDIShowChannels\r\n"
17246 "DAHDIChannel: %d\r\n"
17249 "AccountCode: %s\r\n"
17250 "Signalling: %s\r\n"
17251 "SignallingCode: %d\r\n"
17255 "Description: %s\r\n"
17265 dahdi_dnd(tmp, -1) ?
"Enabled" :
"Disabled",
17270 "Event: DAHDIShowChannels\r\n"
17271 "DAHDIChannel: %d\r\n"
17272 "Signalling: %s\r\n"
17273 "SignallingCode: %d\r\n"
17277 "Description: %s\r\n"
17282 dahdi_dnd(tmp, -1) ?
"Enabled" :
"Disabled",
17306 struct dahdi_spaninfo spaninfo;
17308 ctl = open(
"/dev/dahdi/ctl", O_RDWR);
17316 snprintf(idText,
sizeof(idText),
"ActionID: %s\r\n",
id);
17320 for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
17321 spaninfo.spanno = span;
17322 res = ioctl(ctl, DAHDI_SPANSTAT, &spaninfo);
17329 "Event: DAHDIShowStatus\r\n"
17331 "Description: %s\r\n"
17342 span, spaninfo.desc, alarmstr, spaninfo.irqmisses, spaninfo.bpvcount, spaninfo.crc4count,
17343 spaninfo.lineconfig & DAHDI_CONFIG_D4 ?
"D4" :
17344 spaninfo.lineconfig & DAHDI_CONFIG_ESF ?
"ESF" :
17345 spaninfo.lineconfig & DAHDI_CONFIG_CCS ?
"CCS" :
17347 spaninfo.lineconfig & DAHDI_CONFIG_B8ZS ?
"B8ZS" :
17348 spaninfo.lineconfig & DAHDI_CONFIG_HDB3 ?
"HDB3" :
17349 spaninfo.lineconfig & DAHDI_CONFIG_AMI ?
"AMI" :
17351 spaninfo.lineconfig & DAHDI_CONFIG_CRC4 ?
17352 spaninfo.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"CRC4/YEL" :
"CRC4" :
17353 spaninfo.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"YEL" :
"",
17365#if defined(HAVE_PRI)
17371 struct dahdi_pri *dspan;
17374 char action_id[256];
17375 const char *show_cmd =
"PRIShowSpans";
17379 span_query = atoi(span_str);
17385 snprintf(action_id,
sizeof(action_id),
"ActionID: %s\r\n",
id);
17387 action_id[0] =
'\0';
17393 for (idx = 0; idx <
ARRAY_LEN(pris); ++idx) {
17394 dspan = &pris[idx];
17397 if (0 < span_query && dspan->pri.span != span_query) {
17401 if (dspan->pri.pri) {
17414#if defined(HAVE_SS7)
17415static int linkset_addsigchan(
int sigchan)
17417 struct dahdi_ss7 *link;
17420 struct dahdi_params params;
17421 struct dahdi_bufferinfo bi;
17422 struct dahdi_spaninfo si;
17428 if (cur_ss7type < 0) {
17432 if (cur_pointcode < 0) {
17436 if (cur_adjpointcode < 0) {
17440 if (cur_defaultdpc < 0) {
17444 if (cur_networkindicator < 0) {
17448 link = ss7_resolve_linkset(cur_linkset);
17458 curfd = link->ss7.numsigchans;
17461 link->ss7.fds[curfd] = open(
"/dev/dahdi/channel", O_RDWR, 0600);
17462 if (link->ss7.fds[curfd] < 0) {
17467 if (ioctl(link->ss7.fds[curfd], DAHDI_SPECIFY, &sigchan) == -1) {
17468 dahdi_close_ss7_fd(link, curfd);
17475 memset(¶ms, 0,
sizeof(params));
17476 res = ioctl(link->ss7.fds[curfd], DAHDI_GET_PARAMS, ¶ms);
17478 dahdi_close_ss7_fd(link, curfd);
17479 ast_log(
LOG_ERROR,
"Unable to get parameters for sigchan %d (%s)\n", sigchan,
17483 if (params.sigtype != DAHDI_SIG_HDLCFCS
17484 && params.sigtype != DAHDI_SIG_HARDHDLC
17485 && params.sigtype != DAHDI_SIG_MTP2) {
17486 dahdi_close_ss7_fd(link, curfd);
17492 memset(&bi, 0,
sizeof(bi));
17493 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
17494 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
17497 if (ioctl(link->ss7.fds[curfd], DAHDI_SET_BUFINFO, &bi)) {
17498 ast_log(
LOG_ERROR,
"Unable to set appropriate buffering on channel %d: %s\n",
17499 sigchan, strerror(
errno));
17500 dahdi_close_ss7_fd(link, curfd);
17505 memset(&si, 0,
sizeof(si));
17506 res = ioctl(link->ss7.fds[curfd], DAHDI_SPANSTAT, &si);
17508 dahdi_close_ss7_fd(link, curfd);
17509 ast_log(
LOG_ERROR,
"Unable to get span state for sigchan %d (%s)\n", sigchan,
17514 (params.sigtype == DAHDI_SIG_MTP2)
17515 ? SS7_TRANSPORT_DAHDIMTP2
17516 : SS7_TRANSPORT_DAHDIDCHAN,
17517 si.
alarms, cur_networkindicator, cur_pointcode, cur_adjpointcode, cur_slc);
17519 dahdi_close_ss7_fd(link, curfd);
17523 ++link->ss7.numsigchans;
17529#if defined(HAVE_SS7)
17535 e->
command =
"ss7 set debug {on|off} linkset";
17537 "Usage: ss7 set debug {on|off} linkset <linkset>\n"
17538 " Enables debugging on a given SS7 linkset\n";
17548 span = atoi(
a->argv[5]);
17549 if ((span < 1) || (span >
NUM_SPANS)) {
17550 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number from %d to %d\n",
a->argv[5], 1,
NUM_SPANS);
17553 if (!linksets[span-1].ss7.ss7) {
17554 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", span);
17556 if (!strcasecmp(
a->argv[3],
"on")) {
17557 linksets[span - 1].ss7.debug = 1;
17559 ast_cli(
a->fd,
"Enabled debugging on linkset %d\n", span);
17561 linksets[span - 1].ss7.debug = 0;
17562 ss7_set_debug(linksets[span-1].ss7.ss7, 0);
17563 ast_cli(
a->fd,
"Disabled debugging on linkset %d\n", span);
17571#if defined(HAVE_SS7)
17581 e->
command =
"ss7 {block|unblock} cic";
17583 "Usage: ss7 {block|unblock} cic <linkset> <dpc> <CIC>\n"
17584 " Sends a remote {blocking|unblocking} request for the given CIC on the specified linkset\n";
17590 if (
a->argc == 6) {
17591 linkset = atoi(
a->argv[3]);
17596 if (!strcasecmp(
a->argv[1],
"block")) {
17598 }
else if (strcasecmp(
a->argv[1],
"unblock")) {
17602 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17603 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17607 if (!linksets[linkset-1].ss7.ss7) {
17608 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17612 cic = atoi(
a->argv[5]);
17614 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17618 dpc = atoi(
a->argv[4]);
17620 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17624 for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) {
17625 if (linksets[linkset-1].ss7.pvts[i] && linksets[linkset-1].ss7.pvts[i]->cic == cic && linksets[linkset-1].ss7.pvts[i]->dpc == dpc) {
17626 blocked = linksets[linkset-1].ss7.pvts[i]->locallyblocked;
17629 ast_cli(
a->fd,
"Unable to allocate new ss7call\n");
17631 ast_cli(
a->fd,
"Sent %sblocking request for linkset %d on CIC %d DPC %d\n", (do_block) ?
"" :
"un", linkset, cic, dpc);
17633 }
else if (!do_block && blocked) {
17634 ast_cli(
a->fd,
"CIC %d is hardware locally blocked!\n", cic);
17636 ast_cli(
a->fd,
"CIC %d %s locally blocked\n", cic, do_block ?
"already" :
"is not");
17642 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17647#if defined(HAVE_SS7)
17659 e->
command =
"ss7 {reset|block|unblock} linkset";
17661 "Usage: ss7 {reset|block|unblock} linkset <linkset number>\n"
17662 " Sends a remote {reset|blocking|unblocking} request for all CICs on the given linkset\n";
17668 if (
a->argc == 4) {
17669 linkset = atoi(
a->argv[3]);
17674 if (!strcasecmp(
a->argv[1],
"block")) {
17675 do_what = DO_BLOCK;
17676 }
else if (!strcasecmp(
a->argv[1],
"unblock")) {
17677 do_what = DO_UNBLOCK;
17678 }
else if (!strcasecmp(
a->argv[1],
"reset")) {
17679 do_what = DO_RESET;
17684 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17685 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17689 if (!linksets[linkset - 1].ss7.ss7) {
17690 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17694 for (i = 0; i < linksets[linkset - 1].ss7.numchans; i++) {
17696 if (linksets[linkset - 1].ss7.pvts[i]) {
17701 ast_cli(
a->fd,
"Sent remote %s request on CIC %d\n",
17702 (do_what == DO_BLOCK) ?
"blocking" :
"unblocking",
17703 linksets[linkset - 1].ss7.
pvts[i]->cic);
17708 linksets[linkset - 1].ss7.pvts[i]->cic,
17709 linksets[linkset - 1].ss7.pvts[i]->dpc)) {
17710 ast_cli(
a->fd,
"Sent reset request on CIC %d\n",
17711 linksets[linkset - 1].ss7.pvts[i]->cic);
17722#if defined(HAVE_SS7)
17725 int linkset, cic, range, chanpos;
17726 int i, dpc, orient = 0;
17728 unsigned char state[255];
17732 e->
command =
"ss7 {block|unblock} group";
17734 "Usage: ss7 {block|unblock} group <linkset> <dpc> <1st. CIC> <range> [H]\n"
17735 " Sends a remote {blocking|unblocking} request for CIC range on the specified linkset\n";
17741 if (
a->argc == 7 ||
a->argc == 8) {
17742 linkset = atoi(
a->argv[3]);
17747 if (!strcasecmp(
a->argv[1],
"block")) {
17749 }
else if (strcasecmp(
a->argv[1],
"unblock")) {
17753 if (
a->argc == 8) {
17754 if (!strcasecmp(
a->argv[7],
"H")) {
17761 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17762 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[4], 1,
NUM_SPANS);
17766 if (!linksets[linkset-1].ss7.ss7) {
17767 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17771 cic = atoi(
a->argv[5]);
17773 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17777 range = atoi(
a->argv[6]);
17779 if (range < 1 || range > (linksets[linkset - 1].ss7.type == SS7_ANSI ? 24 : 31)) {
17780 ast_cli(
a->fd,
"Invalid range specified!\n");
17784 dpc = atoi(
a->argv[4]);
17786 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17793 ast_cli(
a->fd,
"Invalid CIC/RANGE\n");
17798 for (i = 0; i <= range; ++i) {
17805 ast_cli(
a->fd,
"Unable allocate new ss7call\n");
17807 ast_cli(
a->fd,
"Sending remote%s %sblocking request linkset %d on CIC %d range %d\n",
17808 orient ?
" hardware" :
"", do_block ?
"" :
"un", linkset, cic, range);
17815 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
17821#if defined(HAVE_SS7)
17824 int linkset, cic, range;
17829 e->
command =
"ss7 reset group";
17831 "Usage: ss7 reset group <linkset> <dpc> <1st CIC> <range>\n"
17832 " Send a GRS for the given CIC range on the specified linkset\n";
17838 if (
a->argc == 7) {
17839 linkset = atoi(
a->argv[3]);
17844 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17845 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[4], 1,
NUM_SPANS);
17849 if (!linksets[linkset-1].ss7.ss7) {
17850 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17854 cic = atoi(
a->argv[5]);
17857 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17861 range = atoi(
a->argv[6]);
17862 if (range < 1 || range > (linksets[linkset - 1].ss7.type == SS7_ANSI ? 24 : 31)) {
17863 ast_cli(
a->fd,
"Invalid range specified!\n");
17867 dpc = atoi(
a->argv[4]);
17869 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17876 ast_cli(
a->fd,
"Invalid CIC/RANGE\n");
17881 ast_cli(
a->fd,
"Unable to allocate new ss7call\n");
17883 ast_cli(
a->fd,
"GRS sent ... \n");
17890 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
17896#if defined(HAVE_SS7)
17903 e->
command =
"ss7 show calls";
17905 "Usage: ss7 show calls <linkset>\n"
17906 " Show SS7 calls on the specified linkset\n";
17912 if (
a->argc == 4) {
17913 linkset = atoi(
a->argv[3]);
17918 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17919 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17923 if (!linksets[linkset-1].ss7.ss7) {
17924 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17929 isup_show_calls(linksets[linkset-1].ss7.ss7, &
ast_cli,
a->fd);
17936#if defined(HAVE_SS7)
17939 int linkset, cic, res;
17944 e->
command =
"ss7 reset cic";
17946 "Usage: ss7 reset cic <linkset> <dpc> <CIC>\n"
17947 " Send a RSC for the given CIC on the specified linkset\n";
17953 if (
a->argc == 6) {
17954 linkset = atoi(
a->argv[3]);
17959 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17960 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17964 if (!linksets[linkset-1].ss7.ss7) {
17965 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17969 cic = atoi(
a->argv[5]);
17972 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17976 dpc = atoi(
a->argv[4]);
17978 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17984 ast_cli(
a->fd,
"%s RSC for linkset %d on CIC %d DPC %d\n", res ?
"Sent" :
"Failed", linkset, cic, dpc);
17990#if defined(HAVE_SS7)
17995 unsigned int arg = 0;
18002 "Usage: ss7 mtp3 <linkset> <slc> coo|coa|cbd|cba|eco|eca|tfp|tfa|lin|lun|lia|lua|lid|lfu <arg>\n"
18003 " Send a NET MNG message\n"
18004 " WARNING!!! WARNING!!! We are not a STP, just for testing/development purposes\n";
18014 linkset = atoi(
a->argv[2]);
18015 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
18016 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[2], 1,
NUM_SPANS);
18019 if (!linksets[linkset-1].ss7.ss7) {
18020 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
18024 slc = atoi(
a->argv[3]);
18026 if (
a->argc == 6) {
18027 arg = atoi(
a->argv[5]);
18031 res = mtp3_net_mng(linksets[linkset-1].ss7.ss7, slc,
a->argv[4], arg);
18036 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
18045#if defined(HAVE_SS7)
18049 unsigned int slc = 0;
18053 e->
command =
"ss7 restart mtp3";
18055 "Usage: ss7 restart mtp3 <linkset> <slc>\n"
18066 linkset = atoi(
a->argv[3]);
18067 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
18068 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[2], 1,
NUM_SPANS);
18071 if (!linksets[linkset-1].ss7.ss7) {
18072 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
18076 slc = atoi(
a->argv[4]);
18079 mtp3_init_restart(linksets[linkset-1].ss7.ss7, slc);
18084 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
18091#if defined(HAVE_SS7)
18098 e->
command =
"ss7 show linkset";
18100 "Usage: ss7 show linkset <span>\n"
18101 " Shows the status of an SS7 linkset.\n";
18111 linkset = atoi(
a->argv[3]);
18112 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
18113 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
18116 ss7 = &linksets[linkset - 1].ss7;
18118 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
18124 ast_cli(
a->fd,
"SS7 calling nai: %i\n",
ss7->calling_nai);
18125 ast_cli(
a->fd,
"SS7 called nai: %i\n",
ss7->called_nai);
18126 ast_cli(
a->fd,
"SS7 nationalprefix: %s\n",
ss7->nationalprefix);
18127 ast_cli(
a->fd,
"SS7 internationalprefix: %s\n",
ss7->internationalprefix);
18128 ast_cli(
a->fd,
"SS7 unknownprefix: %s\n",
ss7->unknownprefix);
18129 ast_cli(
a->fd,
"SS7 networkroutedprefix: %s\n",
ss7->networkroutedprefix);
18130 ast_cli(
a->fd,
"SS7 subscriberprefix: %s\n",
ss7->subscriberprefix);
18137#if defined(HAVE_SS7)
18144 e->
command =
"ss7 show channels";
18146 "Usage: ss7 show channels\n"
18147 " Displays SS7 channel information at a glance.\n";
18153 if (
a->argc != 3) {
18158 for (linkset = 0; linkset <
NUM_SPANS; ++linkset) {
18159 if (linksets[linkset].
ss7.ss7) {
18167#if defined(HAVE_SS7)
18170#define FORMAT "%5s %5s %6s %12s %-12s\n"
18171#define FORMAT2 "%5i %5i %6i %12s %-12s\n"
18172 int i, linkset, dpc = 0;
18179 e->
command =
"ss7 show cics";
18181 "Usage: ss7 show cics <linkset> [dpc]\n"
18182 " Shows the cics of an SS7 linkset.\n";
18188 if (
a->argc < 4 ||
a->argc > 5) {
18192 linkset = atoi(
a->argv[3]);
18194 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
18195 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
18199 if (!linksets[linkset-1].
ss7.ss7) {
18200 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
18203 ss7 = &linksets[linkset-1].ss7;
18205 if (
a->argc == 5) {
18206 dpc = atoi(
a->argv[4]);
18208 ast_cli(
a->fd,
"Invalid DPC specified!\n");
18213 ast_cli(
a->fd,
FORMAT,
"CIC",
"DPC",
"DAHDI",
"STATE",
"BLOCKING");
18215 for (i = 0; i <
ss7->numchans; i++) {
18216 if (!dpc || (
ss7->pvts[i] &&
ss7->pvts[i]->dpc == dpc)) {
18224 state =
"NotInServ";
18230 strcpy(blocking,
"L:");
18232 strcat(blocking,
"M");
18234 strcat(blocking,
" ");
18238 strcat(blocking,
"H");
18240 strcat(blocking,
" ");
18243 strcpy(blocking,
" ");
18247 strcat(blocking,
" R:");
18249 strcat(blocking,
"M");
18251 strcat(blocking,
" ");
18255 strcat(blocking,
"H");
18257 strcat(blocking,
" ");
18271#if defined(HAVE_SS7)
18276 e->
command =
"ss7 show version";
18278 "Usage: ss7 show version\n"
18279 " Show the libss7 version\n";
18285 ast_cli(
a->fd,
"libss7 version: %s\n", ss7_get_version());
18291#if defined(HAVE_SS7)
18293 AST_CLI_DEFINE(handle_ss7_debug,
"Enables SS7 debugging on a linkset"),
18294 AST_CLI_DEFINE(handle_ss7_cic_blocking,
"Blocks/Unblocks the given CIC"),
18295 AST_CLI_DEFINE(handle_ss7_linkset_mng,
"Resets/Blocks/Unblocks all CICs on a linkset"),
18296 AST_CLI_DEFINE(handle_ss7_group_blocking,
"Blocks/Unblocks the given CIC range"),
18298 AST_CLI_DEFINE(handle_ss7_group_reset,
"Resets the given CIC range"),
18301 AST_CLI_DEFINE(handle_ss7_show_linkset,
"Shows the status of a linkset"),
18302 AST_CLI_DEFINE(handle_ss7_show_channels,
"Displays SS7 channel information"),
18309#if defined(HAVE_PRI)
18310#if defined(HAVE_PRI_CCSS)
18357#if defined(HAVE_PRI)
18358#if defined(HAVE_PRI_CCSS)
18370static void dahdi_pri_cc_agent_destructor(
struct ast_cc_agent *agent)
18379#if defined(HAVE_PRI)
18380#if defined(HAVE_PRI_CCSS)
18382 .
type = dahdi_pri_cc_type,
18383 .init = dahdi_pri_cc_agent_init,
18392 .destructor = dahdi_pri_cc_agent_destructor,
18397#if defined(HAVE_PRI)
18398#if defined(HAVE_PRI_CCSS)
18400 .
type = dahdi_pri_cc_type,
18414#if defined(HAVE_PRI) || defined(HAVE_SS7)
18421 pthread_cancel(pris[i].pri.
master);
18422 pthread_kill(pris[i].pri.
master, SIGURG);
18427#ifdef HAVE_PRI_PROG_W_CAUSE
18431#if defined(HAVE_SS7)
18434 pthread_cancel(linksets[i].ss7.
master);
18435 pthread_kill(linksets[i].ss7.
master, SIGURG);
18440#if defined(HAVE_OPENR2)
18441 dahdi_r2_destroy_links();
18458#if defined(HAVE_PRI)
18485#if defined(HAVE_PRI)
18491 dahdi_close_pri_fd(&(pris[i]), j);
18495#if defined(HAVE_PRI_CCSS)
18502#if defined(HAVE_SS7)
18508 dahdi_close_ss7_fd(&(linksets[i]), j);
18510 if (linksets[i].ss7.
ss7) {
18511 ss7_destroy(linksets[i].ss7.
ss7);
18512 linksets[i].ss7.ss7 =
NULL;
18528#if defined(HAVE_PRI) || defined(HAVE_SS7)
18535#if defined(HAVE_SS7)
18545 int x, start, finish;
18548 if ((
reload == 0) && (
conf->chan.sig < 0) && !
conf->is_sig_auto) {
18549 ast_log(
LOG_ERROR,
"Signalling must be specified before any channels are.\n");
18555 while ((chan =
strsep(&
c,
","))) {
18556 if (sscanf(chan,
"%30d-%30d", &start, &finish) == 2) {
18558 }
else if (sscanf(chan,
"%30d", &start)) {
18561 }
else if (!strcasecmp(chan,
"pseudo")) {
18567 if (finish < start) {
18574 for (x = start; x <= finish; x++) {
18575 if (
conf->wanted_channels_start &&
18576 (x < conf->wanted_channels_start ||
18577 x >
conf->wanted_channels_end)
18587 (
reload == 1) ?
"reconfigure" :
"register",
value);
18601#define MAX_CHANLIST_LEN 80
18606 char *
params[DAHDI_MAX_ECHOCANPARAMS + 1];
18607 unsigned int param_count;
18619 if ((x == 32) || (x == 64) || (x == 128) || (x == 256) || (x == 512) || (x == 1024))
18626 for (x = 1; x < param_count; x++) {
18633 ast_log(
LOG_WARNING,
"Invalid echocancel parameter supplied at line %u: '%s'\n", line, params[x]);
18638 ast_log(
LOG_WARNING,
"Invalid echocancel parameter supplied at line %u: '%s'\n", line, param.name);
18646 ast_log(
LOG_WARNING,
"Invalid echocancel parameter value supplied at line %u: '%s'\n", line, param.value);
18654#if defined(HAVE_PRI)
18655#if defined(HAVE_PRI_DISPLAY_TEXT)
18665static unsigned long dahdi_display_text_option(
const char *
value)
18675 opt_str =
strsep(&val_str,
",");
18684 if (!strcasecmp(opt_str,
"block")) {
18685 options |= PRI_DISPLAY_OPTION_BLOCK;
18686 }
else if (!strcasecmp(opt_str,
"name_initial")) {
18687 options |= PRI_DISPLAY_OPTION_NAME_INITIAL;
18688 }
else if (!strcasecmp(opt_str,
"name_update")) {
18689 options |= PRI_DISPLAY_OPTION_NAME_UPDATE;
18690 }
else if (!strcasecmp(opt_str,
"name")) {
18691 options |= (PRI_DISPLAY_OPTION_NAME_INITIAL | PRI_DISPLAY_OPTION_NAME_UPDATE);
18692 }
else if (!strcasecmp(opt_str,
"text")) {
18693 options |= PRI_DISPLAY_OPTION_TEXT;
18701#if defined(HAVE_PRI)
18702#if defined(HAVE_PRI_DATETIME_SEND)
18712static int dahdi_datetime_send_option(
const char *
value)
18716 option = PRI_DATE_TIME_SEND_DEFAULT;
18719 option = PRI_DATE_TIME_SEND_NO;
18720 }
else if (!strcasecmp(
value,
"date")) {
18721 option = PRI_DATE_TIME_SEND_DATE;
18722 }
else if (!strcasecmp(
value,
"date_hh")) {
18723 option = PRI_DATE_TIME_SEND_DATE_HH;
18724 }
else if (!strcasecmp(
value,
"date_hhmm")) {
18725 option = PRI_DATE_TIME_SEND_DATE_HHMM;
18726 }
else if (!strcasecmp(
value,
"date_hhmmss")) {
18727 option = PRI_DATE_TIME_SEND_DATE_HHMMSS;
18736#define PROC_DAHDI_OPT_NOCHAN (1 << 0)
18738#define PROC_DAHDI_OPT_NOWARN (1 << 1)
18742 int count_pattern = 0;
18744 const char *temp =
NULL;
18748 if (!sscanf(v->
value,
"%30d", &norval) && count_pattern == 0) {
18749 ast_log(
LOG_ERROR,
"busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->
lineno);
18753 busy_cadence->
pattern[count_pattern] = norval;
18756 if (count_pattern == 4) {
18760 temp = strchr(v->
value,
',');
18761 if (temp ==
NULL) {
18764 v->
value = temp + 1;
18766 busy_cadence->
length = count_pattern;
18768 if (count_pattern % 2 != 0) {
18770 ast_log(
LOG_ERROR,
"busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->
lineno);
18784 for (; v; v = v->
next) {
18789 if (!strcasecmp(v->
name,
"channel") || !strcasecmp(v->
name,
"channels")) {
18803 }
else if (!strcasecmp(v->
name,
"ignore_failed_channels")) {
18805 }
else if (!strcasecmp(v->
name,
"buffers")) {
18811 }
else if (!strcasecmp(v->
name,
"faxbuffers")) {
18815 }
else if (!strcasecmp(v->
name,
"dahdichan")) {
18818 }
else if (!strcasecmp(v->
name,
"usedistinctiveringdetection")) {
18820 }
else if (!strcasecmp(v->
name,
"distinctiveringaftercid")) {
18822 }
else if (!strcasecmp(v->
name,
"dring1context")) {
18824 }
else if (!strcasecmp(v->
name,
"dring2context")) {
18826 }
else if (!strcasecmp(v->
name,
"dring3context")) {
18828 }
else if (!strcasecmp(v->
name,
"dring1range")) {
18830 }
else if (!strcasecmp(v->
name,
"dring2range")) {
18832 }
else if (!strcasecmp(v->
name,
"dring3range")) {
18834 }
else if (!strcasecmp(v->
name,
"dring1")) {
18836 }
else if (!strcasecmp(v->
name,
"dring2")) {
18838 }
else if (!strcasecmp(v->
name,
"dring3")) {
18840 }
else if (!strcasecmp(v->
name,
"usecallerid")) {
18842 }
else if (!strcasecmp(v->
name,
"cidsignalling")) {
18843 if (!strcasecmp(v->
value,
"bell"))
18845 else if (!strcasecmp(v->
value,
"v23"))
18847 else if (!strcasecmp(v->
value,
"dtmf"))
18849 else if (!strcasecmp(v->
value,
"smdi"))
18851 else if (!strcasecmp(v->
value,
"v23_jp"))
18855 }
else if (!strcasecmp(v->
name,
"cidstart")) {
18856 if (!strcasecmp(v->
value,
"ring"))
18858 else if (!strcasecmp(v->
value,
"polarity_in"))
18860 else if (!strcasecmp(v->
value,
"polarity"))
18862 else if (!strcasecmp(v->
value,
"dtmf"))
18866 }
else if (!strcasecmp(v->
name,
"threewaycalling")) {
18868 }
else if (!strcasecmp(v->
name,
"threewaysilenthold")) {
18870 }
else if (!strcasecmp(v->
name,
"cancallforward")) {
18872 }
else if (!strcasecmp(v->
name,
"relaxdtmf")) {
18877 }
else if (!strcasecmp(v->
name,
"mailbox")) {
18879 }
else if (!strcasecmp(v->
name,
"description")) {
18881 }
else if (!strcasecmp(v->
name,
"adsi")) {
18883 }
else if (!strcasecmp(v->
name,
"usesmdi")) {
18885 }
else if (!strcasecmp(v->
name,
"smdiport")) {
18887 }
else if (!strcasecmp(v->
name,
"transfer")) {
18889 }
else if (!strcasecmp(v->
name,
"canpark")) {
18891 }
else if (!strcasecmp(v->
name,
"echocancelwhenbridged")) {
18893 }
else if (!strcasecmp(v->
name,
"busydetect")) {
18895 }
else if (!strcasecmp(v->
name,
"busycount")) {
18897 }
else if (!strcasecmp(v->
name,
"busypattern")) {
18899 }
else if (!strcasecmp(v->
name,
"calledsubscriberheld")) {
18901 }
else if (!strcasecmp(v->
name,
"lastnumredial")) {
18903 }
else if (!strcasecmp(v->
name,
"callprogress")) {
18907 }
else if (!strcasecmp(v->
name,
"waitfordialtone")) {
18909 }
else if (!strcasecmp(v->
name,
"dialtone_detect")) {
18910 if (!strcasecmp(v->
value,
"always")) {
18919 }
else if (!strcasecmp(v->
name,
"faxdetect")) {
18921 if (!strcasecmp(v->
value,
"incoming")) {
18923 }
else if (!strcasecmp(v->
value,
"outgoing")) {
18927 }
else if (!strcasecmp(v->
name,
"faxdetect_timeout")) {
18931 }
else if (!strcasecmp(v->
name,
"firstdigit_timeout")) {
18936 }
else if (!strcasecmp(v->
name,
"interdigit_timeout")) {
18941 }
else if (!strcasecmp(v->
name,
"matchdigit_timeout")) {
18946 }
else if (!strcasecmp(v->
name,
"echocancel")) {
18948 }
else if (!strcasecmp(v->
name,
"echotraining")) {
18949 if (sscanf(v->
value,
"%30d", &y) == 1) {
18950 if ((y < 10) || (y > 4000)) {
18959 }
else if (!strcasecmp(v->
name,
"hidecallerid")) {
18961 }
else if (!strcasecmp(v->
name,
"hidecalleridname")) {
18963 }
else if (!strcasecmp(v->
name,
"pulsedial")) {
18965 }
else if (!strcasecmp(v->
name,
"callreturn")) {
18967 }
else if (!strcasecmp(v->
name,
"callwaiting")) {
18969 }
else if (!strcasecmp(v->
name,
"callwaitingcallerid")) {
18971 }
else if (!strcasecmp(v->
name,
"callwaitingdeluxe")) {
18973 }
else if (!strcasecmp(v->
name,
"context")) {
18975 }
else if (!strcasecmp(v->
name,
"language")) {
18977 }
else if (!strcasecmp(v->
name,
"progzone")) {
18979 }
else if (!strcasecmp(v->
name,
"mohinterpret")
18980 ||!strcasecmp(v->
name,
"musiconhold") || !strcasecmp(v->
name,
"musicclass")) {
18982 }
else if (!strcasecmp(v->
name,
"mohsuggest")) {
18984 }
else if (!strcasecmp(v->
name,
"parkinglot")) {
18986 }
else if (!strcasecmp(v->
name,
"stripmsd")) {
18987 ast_log(
LOG_NOTICE,
"Configuration option \"%s\" has been deprecated. Please use dialplan instead\n", v->
name);
18989 }
else if (!strcasecmp(v->
name,
"jitterbuffers")) {
18991 }
else if (!strcasecmp(v->
name,
"group")) {
18993 }
else if (!strcasecmp(v->
name,
"callgroup")) {
18997 if (!strcasecmp(v->
value,
"none"))
19001 }
else if (!strcasecmp(v->
name,
"pickupgroup")) {
19005 if (!strcasecmp(v->
value,
"none"))
19009 }
else if (!strcasecmp(v->
name,
"namedcallgroup")) {
19011 ast_log(
LOG_WARNING,
"Only FXO signalled channels may belong to a named call group\n");
19014 }
else if (!strcasecmp(v->
name,
"namedpickupgroup")) {
19016 ast_log(
LOG_WARNING,
"Only FXO signalled channels may belong to a named pickup group\n");
19019 }
else if (!strcasecmp(v->
name,
"setvar")) {
19021 char *varval =
NULL;
19023 char varname[strlen(v->
value) + 1];
19024 strcpy(varname, v->
value);
19025 if ((varval = strchr(varname,
'='))) {
19035 }
else if (!strcasecmp(v->
name,
"immediate")) {
19037 }
else if (!strcasecmp(v->
name,
"immediatering")) {
19039 }
else if (!strcasecmp(v->
name,
"transfertobusy")) {
19041 }
else if (!strcasecmp(v->
name,
"dialmode")) {
19042 if (!strcasecmp(v->
value,
"pulse")) {
19044 }
else if (!strcasecmp(v->
value,
"dtmf") || !strcasecmp(v->
value,
"tone")) {
19046 }
else if (!strcasecmp(v->
value,
"none")) {
19051 }
else if (!strcasecmp(v->
name,
"mwimonitor")) {
19068 }
else if (!strcasecmp(v->
name,
"hwrxgain")) {
19070 if (strcasecmp(v->
value,
"disabled")) {
19077 }
else if (!strcasecmp(v->
name,
"hwtxgain")) {
19079 if (strcasecmp(v->
value,
"disabled")) {
19086 }
else if (!strcasecmp(v->
name,
"cid_rxgain")) {
19090 }
else if (!strcasecmp(v->
name,
"rxgain")) {
19094 }
else if (!strcasecmp(v->
name,
"txgain")) {
19098 }
else if (!strcasecmp(v->
name,
"txdrc")) {
19102 }
else if (!strcasecmp(v->
name,
"rxdrc")) {
19106 }
else if (!strcasecmp(v->
name,
"tonezone")) {
19110 }
else if (!strcasecmp(v->
name,
"callerid")) {
19111 if (!strcasecmp(v->
value,
"asreceived")) {
19117 }
else if (!strcasecmp(v->
name,
"fullname")) {
19119 }
else if (!strcasecmp(v->
name,
"cid_number")) {
19121 }
else if (!strcasecmp(v->
name,
"cid_tag")) {
19123 }
else if (!strcasecmp(v->
name,
"useincomingcalleridondahditransfer")) {
19125 }
else if (!strcasecmp(v->
name,
"restrictcid")) {
19127 }
else if (!strcasecmp(v->
name,
"usecallingpres")) {
19129 }
else if (!strcasecmp(v->
name,
"accountcode")) {
19131 }
else if (!strcasecmp(v->
name,
"amaflags")) {
19137 }
else if (!strcasecmp(v->
name,
"polarityonanswerdelay")) {
19139 }
else if (!strcasecmp(v->
name,
"answeronpolarityswitch")) {
19141 }
else if (!strcasecmp(v->
name,
"ani_info_digits")) {
19143 }
else if (!strcasecmp(v->
name,
"ani_wink_time")) {
19145 }
else if (!strcasecmp(v->
name,
"ani_timeout")) {
19147 }
else if (!strcasecmp(v->
name,
"hanguponpolarityswitch")) {
19149 }
else if (!strcasecmp(v->
name,
"autoreoriginate")) {
19151 }
else if (!strcasecmp(v->
name,
"sendcalleridafter")) {
19153 }
else if (!strcasecmp(v->
name,
"mwimonitornotify")) {
19157 }
else if (!strcasecmp(v->
name,
"mwisendtype")) {
19158#ifndef HAVE_DAHDI_LINEREVERSE_VMWI
19159 if (!strcasecmp(v->
value,
"rpas")) {
19166 memset(&confp->
chan.mwisend_setting, 0,
sizeof(confp->
chan.mwisend_setting));
19168 confp->
chan.mwisend_fsk = 0;
19170 confp->
chan.mwisend_fsk = 1;
19173 confp->
chan.mwisend_rpas = 1;
19175 confp->
chan.mwisend_rpas = 0;
19178 confp->
chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV;
19181 confp->
chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC;
19184 confp->
chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC;
19187 }
else if (
reload != 1) {
19188 if (!strcasecmp(v->
name,
"signalling") || !strcasecmp(v->
name,
"signaling")) {
19196 if (!strcasecmp(v->
value,
"em")) {
19198 }
else if (!strcasecmp(v->
value,
"em_e1")) {
19200 }
else if (!strcasecmp(v->
value,
"em_w")) {
19202 }
else if (!strcasecmp(v->
value,
"fxs_ls")) {
19204 }
else if (!strcasecmp(v->
value,
"fxs_gs")) {
19206 }
else if (!strcasecmp(v->
value,
"fxs_ks")) {
19208 }
else if (!strcasecmp(v->
value,
"fxo_ls")) {
19210 }
else if (!strcasecmp(v->
value,
"fxo_gs")) {
19212 }
else if (!strcasecmp(v->
value,
"fxo_ks")) {
19214 }
else if (!strcasecmp(v->
value,
"fxs_rx")) {
19217 }
else if (!strcasecmp(v->
value,
"fxo_rx")) {
19220 }
else if (!strcasecmp(v->
value,
"fxs_tx")) {
19223 }
else if (!strcasecmp(v->
value,
"fxo_tx")) {
19226 }
else if (!strcasecmp(v->
value,
"em_rx")) {
19229 }
else if (!strcasecmp(v->
value,
"em_tx")) {
19232 }
else if (!strcasecmp(v->
value,
"em_rxtx")) {
19235 }
else if (!strcasecmp(v->
value,
"em_txrx")) {
19238 }
else if (!strcasecmp(v->
value,
"sf")) {
19240 }
else if (!strcasecmp(v->
value,
"sf_w")) {
19242 }
else if (!strcasecmp(v->
value,
"sf_featd")) {
19244 }
else if (!strcasecmp(v->
value,
"sf_featdmf")) {
19246 }
else if (!strcasecmp(v->
value,
"sf_featb")) {
19248 }
else if (!strcasecmp(v->
value,
"sf")) {
19250 }
else if (!strcasecmp(v->
value,
"sf_rx")) {
19253 }
else if (!strcasecmp(v->
value,
"sf_tx")) {
19256 }
else if (!strcasecmp(v->
value,
"sf_rxtx")) {
19259 }
else if (!strcasecmp(v->
value,
"sf_txrx")) {
19262 }
else if (!strcasecmp(v->
value,
"featd")) {
19264 }
else if (!strcasecmp(v->
value,
"featdmf")) {
19266 }
else if (!strcasecmp(v->
value,
"featdmf_ta")) {
19268 }
else if (!strcasecmp(v->
value,
"e911")) {
19270 }
else if (!strcasecmp(v->
value,
"fgccama")) {
19272 }
else if (!strcasecmp(v->
value,
"fgccamamf")) {
19274 }
else if (!strcasecmp(v->
value,
"featb")) {
19277 }
else if (!strcasecmp(v->
value,
"pri_net")) {
19279 confp->pri.pri.nodetype = PRI_NETWORK;
19280 }
else if (!strcasecmp(v->
value,
"pri_cpe")) {
19282 confp->pri.pri.nodetype = PRI_CPE;
19283 }
else if (!strcasecmp(v->
value,
"bri_cpe")) {
19285 confp->pri.pri.nodetype = PRI_CPE;
19286 }
else if (!strcasecmp(v->
value,
"bri_net")) {
19288 confp->pri.pri.nodetype = PRI_NETWORK;
19289 }
else if (!strcasecmp(v->
value,
"bri_cpe_ptmp")) {
19291 confp->pri.pri.nodetype = PRI_CPE;
19292 }
else if (!strcasecmp(v->
value,
"bri_net_ptmp")) {
19293#if defined(HAVE_PRI_CALL_HOLD)
19295 confp->pri.pri.nodetype = PRI_NETWORK;
19297 ast_log(
LOG_WARNING,
"How cool would it be if someone implemented this mode! For now, sucks for you. (line %d)\n", v->
lineno);
19300#if defined(HAVE_SS7)
19301 }
else if (!strcasecmp(v->
value,
"ss7")) {
19305 }
else if (!strcasecmp(v->
value,
"mfcr2")) {
19308 }
else if (!strcasecmp(v->
value,
"auto")) {
19316 }
else if (!strcasecmp(v->
name,
"outsignalling") || !strcasecmp(v->
name,
"outsignaling")) {
19317 if (!strcasecmp(v->
value,
"em")) {
19319 }
else if (!strcasecmp(v->
value,
"em_e1")) {
19321 }
else if (!strcasecmp(v->
value,
"em_w")) {
19323 }
else if (!strcasecmp(v->
value,
"sf")) {
19325 }
else if (!strcasecmp(v->
value,
"sf_w")) {
19327 }
else if (!strcasecmp(v->
value,
"sf_featd")) {
19329 }
else if (!strcasecmp(v->
value,
"sf_featdmf")) {
19331 }
else if (!strcasecmp(v->
value,
"sf_featb")) {
19333 }
else if (!strcasecmp(v->
value,
"sf")) {
19335 }
else if (!strcasecmp(v->
value,
"featd")) {
19337 }
else if (!strcasecmp(v->
value,
"featdmf")) {
19339 }
else if (!strcasecmp(v->
value,
"featdmf_ta")) {
19341 }
else if (!strcasecmp(v->
value,
"e911")) {
19343 }
else if (!strcasecmp(v->
value,
"fgccama")) {
19345 }
else if (!strcasecmp(v->
value,
"fgccamamf")) {
19347 }
else if (!strcasecmp(v->
value,
"featb")) {
19353 }
else if (!strcasecmp(v->
name,
"pridialplan")) {
19354 if (!strcasecmp(v->
value,
"national")) {
19355 confp->pri.pri.dialplan = PRI_NATIONAL_ISDN + 1;
19356 }
else if (!strcasecmp(v->
value,
"unknown")) {
19357 confp->pri.pri.dialplan = PRI_UNKNOWN + 1;
19358 }
else if (!strcasecmp(v->
value,
"private")) {
19359 confp->pri.pri.dialplan = PRI_PRIVATE + 1;
19360 }
else if (!strcasecmp(v->
value,
"international")) {
19361 confp->pri.pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
19362 }
else if (!strcasecmp(v->
value,
"local")) {
19363 confp->pri.pri.dialplan = PRI_LOCAL_ISDN + 1;
19364 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19365 confp->pri.pri.dialplan = -1;
19366 }
else if (!strcasecmp(v->
value,
"redundant")) {
19367 confp->pri.pri.dialplan = -2;
19371 }
else if (!strcasecmp(v->
name,
"prilocaldialplan")) {
19372 if (!strcasecmp(v->
value,
"national")) {
19373 confp->pri.pri.localdialplan = PRI_NATIONAL_ISDN + 1;
19374 }
else if (!strcasecmp(v->
value,
"unknown")) {
19375 confp->pri.pri.localdialplan = PRI_UNKNOWN + 1;
19376 }
else if (!strcasecmp(v->
value,
"private")) {
19377 confp->pri.pri.localdialplan = PRI_PRIVATE + 1;
19378 }
else if (!strcasecmp(v->
value,
"international")) {
19379 confp->pri.pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
19380 }
else if (!strcasecmp(v->
value,
"local")) {
19381 confp->pri.pri.localdialplan = PRI_LOCAL_ISDN + 1;
19382 }
else if (!strcasecmp(v->
value,
"from_channel")) {
19383 confp->pri.pri.localdialplan = 0;
19384 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19385 confp->pri.pri.localdialplan = -1;
19386 }
else if (!strcasecmp(v->
value,
"redundant")) {
19387 confp->pri.pri.localdialplan = -2;
19391 }
else if (!strcasecmp(v->
name,
"pricpndialplan")) {
19392 if (!strcasecmp(v->
value,
"national")) {
19393 confp->pri.pri.cpndialplan = PRI_NATIONAL_ISDN + 1;
19394 }
else if (!strcasecmp(v->
value,
"unknown")) {
19395 confp->pri.pri.cpndialplan = PRI_UNKNOWN + 1;
19396 }
else if (!strcasecmp(v->
value,
"private")) {
19397 confp->pri.pri.cpndialplan = PRI_PRIVATE + 1;
19398 }
else if (!strcasecmp(v->
value,
"international")) {
19399 confp->pri.pri.cpndialplan = PRI_INTERNATIONAL_ISDN + 1;
19400 }
else if (!strcasecmp(v->
value,
"local")) {
19401 confp->pri.pri.cpndialplan = PRI_LOCAL_ISDN + 1;
19402 }
else if (!strcasecmp(v->
value,
"from_channel")) {
19403 confp->pri.pri.cpndialplan = 0;
19404 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19405 confp->pri.pri.cpndialplan = -1;
19406 }
else if (!strcasecmp(v->
value,
"redundant")) {
19407 confp->pri.pri.cpndialplan = -2;
19411 }
else if (!strcasecmp(v->
name,
"switchtype")) {
19412 if (!strcasecmp(v->
value,
"national"))
19413 confp->pri.pri.switchtype = PRI_SWITCH_NI2;
19414 else if (!strcasecmp(v->
value,
"ni1"))
19415 confp->pri.pri.switchtype = PRI_SWITCH_NI1;
19416 else if (!strcasecmp(v->
value,
"dms100"))
19417 confp->pri.pri.switchtype = PRI_SWITCH_DMS100;
19418 else if (!strcasecmp(v->
value,
"4ess"))
19419 confp->pri.pri.switchtype = PRI_SWITCH_ATT4ESS;
19420 else if (!strcasecmp(v->
value,
"5ess"))
19421 confp->pri.pri.switchtype = PRI_SWITCH_LUCENT5E;
19422 else if (!strcasecmp(v->
value,
"euroisdn"))
19423 confp->pri.pri.switchtype = PRI_SWITCH_EUROISDN_E1;
19424 else if (!strcasecmp(v->
value,
"qsig"))
19425 confp->pri.pri.switchtype = PRI_SWITCH_QSIG;
19430 }
else if (!strcasecmp(v->
name,
"msn")) {
19432 sizeof(confp->pri.pri.msn_list));
19433 }
else if (!strcasecmp(v->
name,
"nsf")) {
19434 if (!strcasecmp(v->
value,
"sdn"))
19435 confp->pri.pri.nsf = PRI_NSF_SDN;
19436 else if (!strcasecmp(v->
value,
"megacom"))
19437 confp->pri.pri.nsf = PRI_NSF_MEGACOM;
19438 else if (!strcasecmp(v->
value,
"tollfreemegacom"))
19439 confp->pri.pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;
19440 else if (!strcasecmp(v->
value,
"accunet"))
19441 confp->pri.pri.nsf = PRI_NSF_ACCUNET;
19442 else if (!strcasecmp(v->
value,
"none"))
19443 confp->pri.pri.nsf = PRI_NSF_NONE;
19446 confp->pri.pri.nsf = PRI_NSF_NONE;
19448 }
else if (!strcasecmp(v->
name,
"priindication")) {
19449 if (!strcasecmp(v->
value,
"outofband"))
19451 else if (!strcasecmp(v->
value,
"inband"))
19454 ast_log(
LOG_WARNING,
"'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d.\n",
19456 }
else if (!strcasecmp(v->
name,
"priexclusive")) {
19458 }
else if (!strcasecmp(v->
name,
"internationalprefix")) {
19459 ast_copy_string(confp->pri.pri.internationalprefix, v->
value,
sizeof(confp->pri.pri.internationalprefix));
19460 }
else if (!strcasecmp(v->
name,
"nationalprefix")) {
19461 ast_copy_string(confp->pri.pri.nationalprefix, v->
value,
sizeof(confp->pri.pri.nationalprefix));
19462 }
else if (!strcasecmp(v->
name,
"localprefix")) {
19464 }
else if (!strcasecmp(v->
name,
"privateprefix")) {
19465 ast_copy_string(confp->pri.pri.privateprefix, v->
value,
sizeof(confp->pri.pri.privateprefix));
19466 }
else if (!strcasecmp(v->
name,
"unknownprefix")) {
19467 ast_copy_string(confp->pri.pri.unknownprefix, v->
value,
sizeof(confp->pri.pri.unknownprefix));
19468 }
else if (!strcasecmp(v->
name,
"resetinterval")) {
19469 if (!strcasecmp(v->
value,
"never"))
19470 confp->pri.pri.resetinterval = -1;
19471 else if (atoi(v->
value) >= 60)
19472 confp->pri.pri.resetinterval = atoi(v->
value);
19474 ast_log(
LOG_WARNING,
"'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n",
19476 }
else if (!strcasecmp(v->
name,
"force_restart_unavailable_chans")) {
19477 confp->pri.pri.force_restart_unavailable_chans =
ast_true(v->
value);
19478 }
else if (!strcasecmp(v->
name,
"minunused")) {
19479 confp->pri.pri.minunused = atoi(v->
value);
19480 }
else if (!strcasecmp(v->
name,
"minidle")) {
19481 confp->pri.pri.minidle = atoi(v->
value);
19482 }
else if (!strcasecmp(v->
name,
"idleext")) {
19484 }
else if (!strcasecmp(v->
name,
"idledial")) {
19486 }
else if (!strcasecmp(v->
name,
"overlapdial")) {
19489 }
else if (!strcasecmp(v->
value,
"incoming")) {
19491 }
else if (!strcasecmp(v->
value,
"outgoing")) {
19498#ifdef HAVE_PRI_PROG_W_CAUSE
19499 }
else if (!strcasecmp(v->
name,
"qsigchannelmapping")) {
19500 if (!strcasecmp(v->
value,
"logical")) {
19502 }
else if (!strcasecmp(v->
value,
"physical")) {
19508 }
else if (!strcasecmp(v->
name,
"discardremoteholdretrieval")) {
19509 confp->pri.pri.discardremoteholdretrieval =
ast_true(v->
value);
19510#if defined(HAVE_PRI_SERVICE_MESSAGES)
19511 }
else if (!strcasecmp(v->
name,
"service_message_support")) {
19513 if ((confp->pri.pri.switchtype == PRI_SWITCH_ATT4ESS
19514 || confp->pri.pri.switchtype == PRI_SWITCH_LUCENT5E
19515 || confp->pri.pri.switchtype == PRI_SWITCH_NI2) &&
ast_true(v->
value)) {
19516 confp->pri.pri.enable_service_message_support = 1;
19518 confp->pri.pri.enable_service_message_support = 0;
19521#ifdef HAVE_PRI_INBANDDISCONNECT
19522 }
else if (!strcasecmp(v->
name,
"inbanddisconnect")) {
19525 }
else if (!strcasecmp(v->
name,
"pritimer")) {
19526#ifdef PRI_GETSET_TIMERS
19537 timeridx = pri_timer2idx(timerc);
19539 if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) {
19541 "'%s' is not a valid ISDN timer at line %d.\n", timerc,
19543 }
else if (!
timer) {
19545 "'%s' is not a valid value for ISDN timer '%s' at line %d.\n",
19548 confp->pri.pri.pritimers[timeridx] =
timer;
19552 "'%s' is not a valid ISDN timer configuration string at line %d.\n",
19556 }
else if (!strcasecmp(v->
name,
"facilityenable")) {
19558#if defined(HAVE_PRI_AOC_EVENTS)
19559 }
else if (!strcasecmp(v->
name,
"aoc_enable")) {
19560 confp->pri.pri.aoc_passthrough_flag = 0;
19561 if (strchr(v->
value,
's') || strchr(v->
value,
'S')) {
19564 if (strchr(v->
value,
'd') || strchr(v->
value,
'D')) {
19567 if (strchr(v->
value,
'e') || strchr(v->
value,
'E')) {
19570 }
else if (!strcasecmp(v->
name,
"aoce_delayhangup")) {
19573#if defined(HAVE_PRI_CALL_HOLD)
19574 }
else if (!strcasecmp(v->
name,
"hold_disconnect_transfer")) {
19575 confp->pri.pri.hold_disconnect_transfer =
ast_true(v->
value);
19577 }
else if (!strcasecmp(v->
name,
"moh_signaling")
19578 || !strcasecmp(v->
name,
"moh_signalling")) {
19579 if (!strcasecmp(v->
value,
"moh")) {
19581 }
else if (!strcasecmp(v->
value,
"notify")) {
19583#if defined(HAVE_PRI_CALL_HOLD)
19584 }
else if (!strcasecmp(v->
value,
"hold")) {
19585 confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_HOLD;
19590#if defined(HAVE_PRI_CCSS)
19591 }
else if (!strcasecmp(v->
name,
"cc_ptmp_recall_mode")) {
19592 if (!strcasecmp(v->
value,
"global")) {
19593 confp->pri.pri.cc_ptmp_recall_mode = 0;
19594 }
else if (!strcasecmp(v->
value,
"specific")) {
19595 confp->pri.pri.cc_ptmp_recall_mode = 1;
19597 confp->pri.pri.cc_ptmp_recall_mode = 1;
19599 }
else if (!strcasecmp(v->
name,
"cc_qsig_signaling_link_req")) {
19600 if (!strcasecmp(v->
value,
"release")) {
19601 confp->pri.pri.cc_qsig_signaling_link_req = 0;
19602 }
else if (!strcasecmp(v->
value,
"retain")) {
19603 confp->pri.pri.cc_qsig_signaling_link_req = 1;
19604 }
else if (!strcasecmp(v->
value,
"do_not_care")) {
19605 confp->pri.pri.cc_qsig_signaling_link_req = 2;
19607 confp->pri.pri.cc_qsig_signaling_link_req = 1;
19609 }
else if (!strcasecmp(v->
name,
"cc_qsig_signaling_link_rsp")) {
19610 if (!strcasecmp(v->
value,
"release")) {
19611 confp->pri.pri.cc_qsig_signaling_link_rsp = 0;
19612 }
else if (!strcasecmp(v->
value,
"retain")) {
19613 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;
19615 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;
19618#if defined(HAVE_PRI_CALL_WAITING)
19619 }
else if (!strcasecmp(v->
name,
"max_call_waiting_calls")) {
19620 confp->pri.pri.max_call_waiting_calls = atoi(v->
value);
19621 if (confp->pri.pri.max_call_waiting_calls < 0) {
19623 confp->pri.pri.max_call_waiting_calls = 0;
19625 }
else if (!strcasecmp(v->
name,
"allow_call_waiting_calls")) {
19626 confp->pri.pri.allow_call_waiting_calls =
ast_true(v->
value);
19628#if defined(HAVE_PRI_MWI)
19629 }
else if (!strcasecmp(v->
name,
"mwi_mailboxes")) {
19631 sizeof(confp->pri.pri.mwi_mailboxes));
19632 }
else if (!strcasecmp(v->
name,
"mwi_vm_boxes")) {
19634 sizeof(confp->pri.pri.mwi_vm_boxes));
19635 }
else if (!strcasecmp(v->
name,
"mwi_vm_numbers")) {
19637 sizeof(confp->pri.pri.mwi_vm_numbers));
19639 }
else if (!strcasecmp(v->
name,
"append_msn_to_cid_tag")) {
19640 confp->pri.pri.append_msn_to_user_tag =
ast_true(v->
value);
19641 }
else if (!strcasecmp(v->
name,
"inband_on_setup_ack")) {
19643 }
else if (!strcasecmp(v->
name,
"inband_on_proceeding")) {
19645#if defined(HAVE_PRI_DISPLAY_TEXT)
19646 }
else if (!strcasecmp(v->
name,
"display_send")) {
19647 confp->pri.pri.display_flags_send = dahdi_display_text_option(v->
value);
19648 }
else if (!strcasecmp(v->
name,
"display_receive")) {
19649 confp->pri.pri.display_flags_receive = dahdi_display_text_option(v->
value);
19651#if defined(HAVE_PRI_MCID)
19652 }
else if (!strcasecmp(v->
name,
"mcid_send")) {
19655#if defined(HAVE_PRI_DATETIME_SEND)
19656 }
else if (!strcasecmp(v->
name,
"datetime_send")) {
19657 confp->pri.pri.datetime_send = dahdi_datetime_send_option(v->
value);
19659 }
else if (!strcasecmp(v->
name,
"layer1_presence")) {
19660 if (!strcasecmp(v->
value,
"required")) {
19661 confp->pri.pri.layer1_ignored = 0;
19662 }
else if (!strcasecmp(v->
value,
"ignore")) {
19663 confp->pri.pri.layer1_ignored = 1;
19666 confp->pri.pri.layer1_ignored = 0;
19668#if defined(HAVE_PRI_L2_PERSISTENCE)
19669 }
else if (!strcasecmp(v->
name,
"layer2_persistence")) {
19670 if (!strcasecmp(v->
value,
"keep_up")) {
19671 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_KEEP_UP;
19672 }
else if (!strcasecmp(v->
value,
"leave_down")) {
19673 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_LEAVE_DOWN;
19675 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_DEFAULT;
19678 }
else if (!strcasecmp(v->
name,
"colp_send")) {
19679 if (!strcasecmp(v->
value,
"block")) {
19681 }
else if (!strcasecmp(v->
value,
"connect")) {
19683 }
else if (!strcasecmp(v->
value,
"update")) {
19689#if defined(HAVE_SS7)
19690 }
else if (!strcasecmp(v->
name,
"ss7type")) {
19691 if (!strcasecmp(v->
value,
"itu")) {
19692 cur_ss7type = SS7_ITU;
19693 }
else if (!strcasecmp(v->
value,
"ansi")) {
19694 cur_ss7type = SS7_ANSI;
19698 }
else if (!strcasecmp(v->
name,
"slc")) {
19699 cur_slc = atoi(v->
value);
19700 }
else if (!strcasecmp(v->
name,
"linkset")) {
19701 cur_linkset = atoi(v->
value);
19702 }
else if (!strcasecmp(v->
name,
"pointcode")) {
19703 cur_pointcode = parse_pointcode(v->
value);
19704 }
else if (!strcasecmp(v->
name,
"adjpointcode")) {
19705 cur_adjpointcode = parse_pointcode(v->
value);
19706 }
else if (!strcasecmp(v->
name,
"defaultdpc")) {
19707 cur_defaultdpc = parse_pointcode(v->
value);
19708 }
else if (!strcasecmp(v->
name,
"cicbeginswith")) {
19709 cur_cicbeginswith = atoi(v->
value);
19710 }
else if (!strcasecmp(v->
name,
"networkindicator")) {
19711 if (!strcasecmp(v->
value,
"national")) {
19712 cur_networkindicator = SS7_NI_NAT;
19713 }
else if (!strcasecmp(v->
value,
"national_spare")) {
19714 cur_networkindicator = SS7_NI_NAT_SPARE;
19715 }
else if (!strcasecmp(v->
value,
"international")) {
19716 cur_networkindicator = SS7_NI_INT;
19717 }
else if (!strcasecmp(v->
value,
"international_spare")) {
19718 cur_networkindicator = SS7_NI_INT_SPARE;
19720 cur_networkindicator = -1;
19722 }
else if (!strcasecmp(v->
name,
"ss7_internationalprefix")) {
19723 ast_copy_string(confp->ss7.ss7.internationalprefix, v->
value,
sizeof(confp->ss7.ss7.internationalprefix));
19724 }
else if (!strcasecmp(v->
name,
"ss7_nationalprefix")) {
19725 ast_copy_string(confp->ss7.ss7.nationalprefix, v->
value,
sizeof(confp->ss7.ss7.nationalprefix));
19726 }
else if (!strcasecmp(v->
name,
"ss7_subscriberprefix")) {
19727 ast_copy_string(confp->ss7.ss7.subscriberprefix, v->
value,
sizeof(confp->ss7.ss7.subscriberprefix));
19728 }
else if (!strcasecmp(v->
name,
"ss7_unknownprefix")) {
19729 ast_copy_string(confp->ss7.ss7.unknownprefix, v->
value,
sizeof(confp->ss7.ss7.unknownprefix));
19730 }
else if (!strcasecmp(v->
name,
"ss7_networkroutedprefix")) {
19731 ast_copy_string(confp->ss7.ss7.networkroutedprefix, v->
value,
sizeof(confp->ss7.ss7.networkroutedprefix));
19732 }
else if (!strcasecmp(v->
name,
"ss7_called_nai")) {
19733 if (!strcasecmp(v->
value,
"national")) {
19734 confp->ss7.ss7.called_nai = SS7_NAI_NATIONAL;
19735 }
else if (!strcasecmp(v->
value,
"international")) {
19736 confp->ss7.ss7.called_nai = SS7_NAI_INTERNATIONAL;
19737 }
else if (!strcasecmp(v->
value,
"subscriber")) {
19738 confp->ss7.ss7.called_nai = SS7_NAI_SUBSCRIBER;
19739 }
else if (!strcasecmp(v->
value,
"unknown")) {
19740 confp->ss7.ss7.called_nai = SS7_NAI_UNKNOWN;
19741 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19746 }
else if (!strcasecmp(v->
name,
"ss7_calling_nai")) {
19747 if (!strcasecmp(v->
value,
"national")) {
19748 confp->ss7.ss7.calling_nai = SS7_NAI_NATIONAL;
19749 }
else if (!strcasecmp(v->
value,
"international")) {
19750 confp->ss7.ss7.calling_nai = SS7_NAI_INTERNATIONAL;
19751 }
else if (!strcasecmp(v->
value,
"subscriber")) {
19752 confp->ss7.ss7.calling_nai = SS7_NAI_SUBSCRIBER;
19753 }
else if (!strcasecmp(v->
value,
"unknown")) {
19754 confp->ss7.ss7.calling_nai = SS7_NAI_UNKNOWN;
19755 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19760 }
else if (!strcasecmp(v->
name,
"sigchan")) {
19762 sigchan = atoi(v->
value);
19763 res = linkset_addsigchan(sigchan);
19767 }
else if (!strcasecmp(v->
name,
"ss7_explicitacm")) {
19768 struct dahdi_ss7 *link;
19769 link = ss7_resolve_linkset(cur_linkset);
19777 link->ss7.flags &= ~LINKSET_FLAG_EXPLICITACM;
19779 }
else if (!strcasecmp(v->
name,
"ss7_autoacm")) {
19780 struct dahdi_ss7 *link;
19781 link = ss7_resolve_linkset(cur_linkset);
19789 link->ss7.flags &= ~LINKSET_FLAG_AUTOACM;
19791 }
else if (!strcasecmp(v->
name,
"ss7_initialhwblo")) {
19792 struct dahdi_ss7 *link;
19793 link = ss7_resolve_linkset(cur_linkset);
19801 link->ss7.flags &= ~LINKSET_FLAG_INITIALHWBLO;
19803 }
else if (!strcasecmp(v->
name,
"ss7_use_echocontrol")) {
19804 struct dahdi_ss7 *link;
19805 link = ss7_resolve_linkset(cur_linkset);
19813 link->ss7.flags &= ~LINKSET_FLAG_USEECHOCONTROL;
19815 }
else if (!strcasecmp(v->
name,
"ss7_default_echocontrol")) {
19816 struct dahdi_ss7 *link;
19817 link = ss7_resolve_linkset(cur_linkset);
19825 link->ss7.flags &= ~LINKSET_FLAG_DEFAULTECHOCONTROL;
19827 }
else if (!strncasecmp(v->
name,
"isup_timer.", 11)) {
19828 struct dahdi_ss7 *link;
19829 link = ss7_resolve_linkset(cur_linkset);
19834 if (!link->ss7.ss7) {
19837 }
else if (!ss7_set_isup_timer(link->ss7.ss7, (
char*) strstr(v->
name,
".") + 1, atoi(v->
value))) {
19840 }
else if (!strncasecmp(v->
name,
"mtp3_timer.", 11)) {
19841 struct dahdi_ss7 *link;
19842 link = ss7_resolve_linkset(cur_linkset);
19847 if (!link->ss7.ss7) {
19850 }
else if (!ss7_set_mtp3_timer(link->ss7.ss7, (
char*) strstr(v->
name,
".") + 1, atoi(v->
value))) {
19853 }
else if (!strcasecmp(v->
name,
"inr_if_no_calling")) {
19854 struct dahdi_ss7 *link;
19855 link = ss7_resolve_linkset(cur_linkset);
19860 if (!link->ss7.ss7) {
19863 ss7_set_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
19865 ss7_clear_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
19867 }
else if (!strcasecmp(v->
name,
"non_isdn_access")) {
19868 struct dahdi_ss7 *link;
19869 link = ss7_resolve_linkset(cur_linkset);
19874 if (!link->ss7.ss7) {
19877 ss7_clear_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
19879 ss7_set_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
19881 }
else if (!strcasecmp(v->
name,
"sls_shift")) {
19882 struct dahdi_ss7 *link;
19883 int sls_shift = atoi(v->
value);
19885 if (sls_shift < 0 || sls_shift > 7) {
19890 link = ss7_resolve_linkset(cur_linkset);
19895 if (!link->ss7.ss7) {
19898 ss7_set_sls_shift(link->ss7.ss7, sls_shift);
19900 }
else if (!strcasecmp(v->
name,
"cause_location")) {
19901 struct dahdi_ss7 *link;
19902 int cause_location = atoi(v->
value);
19904 if (cause_location < 0 || cause_location > 15) {
19905 ast_log(
LOG_ERROR,
"Invalid cause_location value. Must be between 0 and 15\n");
19908 link = ss7_resolve_linkset(cur_linkset);
19913 if (!link->ss7.ss7) {
19916 ss7_set_cause_location(link->ss7.ss7, cause_location);
19920 }
else if (!strcasecmp(v->
name,
"mfcr2_advanced_protocol_file")) {
19922 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);
19923 }
else if (!strcasecmp(v->
name,
"mfcr2_logdir")) {
19925 }
else if (!strcasecmp(v->
name,
"mfcr2_variant")) {
19926 confp->mfcr2.variant = openr2_proto_get_variant(v->
value);
19927 if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) {
19929 confp->mfcr2.variant = OR2_VAR_ITU;
19931 }
else if (!strcasecmp(v->
name,
"mfcr2_mfback_timeout")) {
19932 confp->mfcr2.mfback_timeout = atoi(v->
value);
19933 if (!confp->mfcr2.mfback_timeout) {
19934 ast_log(
LOG_WARNING,
"MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n");
19935 confp->mfcr2.mfback_timeout = -1;
19936 }
else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) {
19937 ast_log(
LOG_WARNING,
"MF timeout less than 500ms is not recommended, you have been warned!\n");
19939 }
else if (!strcasecmp(v->
name,
"mfcr2_metering_pulse_timeout")) {
19940 confp->mfcr2.metering_pulse_timeout = atoi(v->
value);
19941 if (confp->mfcr2.metering_pulse_timeout > 500) {
19942 ast_log(
LOG_WARNING,
"Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n");
19944#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
19945 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_detection")) {
19947 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_dialing")) {
19949 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_time_on")) {
19950 confp->mfcr2.dtmf_time_on = atoi(v->
value);
19951 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_time_off")) {
19952 confp->mfcr2.dtmf_time_off = atoi(v->
value);
19954#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
19955 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_end_timeout")) {
19956 confp->mfcr2.dtmf_end_timeout = atoi(v->
value);
19958 }
else if (!strcasecmp(v->
name,
"mfcr2_get_ani_first")) {
19960 }
else if (!strcasecmp(v->
name,
"mfcr2_double_answer")) {
19962 }
else if (!strcasecmp(v->
name,
"mfcr2_charge_calls")) {
19964 }
else if (!strcasecmp(v->
name,
"mfcr2_accept_on_offer")) {
19966 }
else if (!strcasecmp(v->
name,
"mfcr2_allow_collect_calls")) {
19967 confp->mfcr2.allow_collect_calls =
ast_true(v->
value) ? 1 : 0;
19968 }
else if (!strcasecmp(v->
name,
"mfcr2_forced_release")) {
19970 }
else if (!strcasecmp(v->
name,
"mfcr2_immediate_accept")) {
19971 confp->mfcr2.immediate_accept =
ast_true(v->
value) ? 1 : 0;
19972#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
19973 }
else if (!strcasecmp(v->
name,
"mfcr2_skip_category")) {
19974 confp->mfcr2.skip_category_request =
ast_true(v->
value) ? 1 : 0;
19976 }
else if (!strcasecmp(v->
name,
"mfcr2_call_files")) {
19978 }
else if (!strcasecmp(v->
name,
"mfcr2_max_ani")) {
19979 confp->mfcr2.max_ani = atoi(v->
value);
19983 }
else if (!strcasecmp(v->
name,
"mfcr2_max_dnis")) {
19984 confp->mfcr2.max_dnis = atoi(v->
value);
19988 }
else if (!strcasecmp(v->
name,
"mfcr2_category")) {
19989 confp->mfcr2.category = openr2_proto_get_category(v->
value);
19990 if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) {
19991 confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
19992 ast_log(
LOG_WARNING,
"Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n",
19995 }
else if (!strcasecmp(v->
name,
"mfcr2_logging")) {
19996 openr2_log_level_t tmplevel;
20003 clevel =
strsep(&logval,
",");
20004 if (-1 == (tmplevel = openr2_log_get_level(clevel))) {
20008 confp->mfcr2.loglevel |= tmplevel;
20011 }
else if (!strcasecmp(v->
name,
"cadence")) {
20013 int element_count,
c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
20015 struct dahdi_ring_cadence new_cadence;
20016 int cid_location = -1;
20017 int firstcadencepos = 0;
20018 char original_args[80];
20019 int cadence_is_ok = 1;
20023 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]);
20026 if (element_count % 2 == 1) {
20027 ast_log(
LOG_ERROR,
"Must be a silence duration for each ring duration: %s at line %d.\n", original_args, v->
lineno);
20037 for (i = 0; i < element_count; i++) {
20039 ast_log(
LOG_ERROR,
"Ring or silence duration cannot be zero: %s at line %d.\n", original_args, v->
lineno);
20042 }
else if (
c[i] < 0) {
20045 if (cid_location == -1) {
20054 if (firstcadencepos == 0) {
20055 firstcadencepos = i;
20058 ast_log(
LOG_ERROR,
"First cadence position specified twice: %s at line %d.\n", original_args, v->
lineno);
20067 for (i = 0; i < 16; i++) {
20068 new_cadence.ringcadence[i] =
c[i];
20071 if (cadence_is_ok) {
20073 if (element_count < 2) {
20076 if (cid_location == -1) {
20081 cid_location = (cid_location + 1) / 2;
20096 }
else if (!strcasecmp(v->
name,
"ringtimeout")) {
20098 }
else if (!strcasecmp(v->
name,
"prewink")) {
20100 }
else if (!strcasecmp(v->
name,
"preflash")) {
20102 }
else if (!strcasecmp(v->
name,
"wink")) {
20104 }
else if (!strcasecmp(v->
name,
"flash")) {
20106 }
else if (!strcasecmp(v->
name,
"start")) {
20108 }
else if (!strcasecmp(v->
name,
"rxwink")) {
20110 }
else if (!strcasecmp(v->
name,
"rxflash")) {
20112 }
else if (!strcasecmp(v->
name,
"debounce")) {
20114 }
else if (!strcasecmp(v->
name,
"toneduration")) {
20118 struct dahdi_dialparams dps;
20120 ctlfd = open(
"/dev/dahdi/ctl", O_RDWR);
20126 toneduration = atoi(v->
value);
20127 if (toneduration > -1) {
20128 memset(&dps, 0,
sizeof(dps));
20130 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
20131 res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps);
20139 }
else if (!strcasecmp(v->
name,
"defaultcic")) {
20141 }
else if (!strcasecmp(v->
name,
"defaultozz")) {
20143 }
else if (!strcasecmp(v->
name,
"mwilevel")) {
20145 }
else if (!strcasecmp(v->
name,
"dtmfcidlevel")) {
20147 }
else if (!strcasecmp(v->
name,
"reportalarms")) {
20148 if (!strcasecmp(v->
value,
"all"))
20150 if (!strcasecmp(v->
value,
"none"))
20152 else if (!strcasecmp(v->
value,
"channels"))
20154 else if (!strcasecmp(v->
value,
"spans"))
20166 "Dahdichan '%s' failure ignored: ignore_failed_channels.\n",
20184 for (tmp =
iflist, y=-1; tmp; tmp = tmp->
next) {
20202 if (
conf.chan.cc_params) {
20208 ast_verb(3,
"Automatically generated pseudo channel\n");
20272 static int had_cfg_before = 1;
20275 have_cfg_now = !!cfg;
20278 if (had_cfg_before) {
20289 have_cfg_now = !!cfg;
20291 if (had_cfg_before) {
20310 had_cfg_before = have_cfg_now;
20319 if (!strcasecmp(v->
name,
"trunkgroup")) {
20320 trunkgroup = atoi(v->
value);
20321 if (trunkgroup > 0) {
20322 if ((
c = strchr(v->
value,
','))) {
20324 memset(dchannels, 0,
sizeof(dchannels));
20326 dchannels[i] = atoi(
c + 1);
20327 if (dchannels[i] < 0) {
20328 ast_log(
LOG_WARNING,
"D-channel for trunk group %d must be a positive number at line %d of chan_dahdi.conf\n", trunkgroup, v->
lineno);
20331 c = strchr(
c + 1,
',');
20334 if (pri_create_trunkgroup(trunkgroup, dchannels)) {
20335 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);
20337 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");
20339 ast_log(
LOG_WARNING,
"Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->
lineno);
20341 ast_log(
LOG_WARNING,
"Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->
lineno);
20343 ast_log(
LOG_WARNING,
"Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->
lineno);
20344 }
else if (!strcasecmp(v->
name,
"spanmap")) {
20345 spanno = atoi(v->
value);
20347 if ((
c = strchr(v->
value,
','))) {
20348 trunkgroup = atoi(
c + 1);
20349 if (trunkgroup > 0) {
20350 if ((
c = strchr(
c + 1,
',')))
20351 logicalspan = atoi(
c + 1);
20354 if (logicalspan >= 0) {
20355 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
20356 ast_log(
LOG_WARNING,
"Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
20358 ast_verb(2,
"Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
20360 ast_log(
LOG_WARNING,
"Logical span must be a positive number, or '0' (for unspecified) at line %d of chan_dahdi.conf\n", v->
lineno);
20394 if (!strcasecmp(cat,
"general") ||
20395 !strcasecmp(cat,
"trunkgroups") ||
20396 !strcasecmp(cat,
"globals") ||
20397 !strcasecmp(cat,
"channels")) {
20424 if (pris[x].pri.
pvts[0] &&
20426 prepare_pri(pris + x);
20431 ast_verb(2,
"Starting D-Channel on span %d\n", x + 1);
20436#if defined(HAVE_SS7)
20440 if (linksets[x].ss7.
ss7) {
20445 ast_verb(2,
"Starting SS7 linkset on span %d\n", x + 1);
20452 struct r2link_entry *cur;
20456 struct dahdi_mfcr2 *r2 = &cur->mfcr2;
20459 ast_log(
LOG_ERROR,
"Unable to start R2 monitor on channel group %d\n", x + 1);
20462 ast_verb(2,
"Starting R2 monitor on channel group %d\n", x + 1);
20516#if defined(HAVE_PRI) || defined(HAVE_SS7)
20537 memset(pris, 0,
sizeof(pris));
20541 pri_set_error(dahdi_pri_error);
20542 pri_set_message(dahdi_pri_message);
20544#ifdef HAVE_PRI_PROG_W_CAUSE
20547#if defined(HAVE_PRI_CCSS)
20555#
if defined(HAVE_PRI_CCSS)
20565#if defined(HAVE_SS7)
20566 memset(linksets, 0,
sizeof(linksets));
20570 ss7_set_error(dahdi_ss7_error);
20571 ss7_set_message(dahdi_ss7_message);
20590#if defined(HAVE_SS7)
20611#if defined(HAVE_PRI)
20625#define END_SILENCE_LEN 400
20626#define HEADER_MS 50
20627#define TRAILER_MS 5
20628#define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
20629#define ASCII_BYTES_PER_CHAR 80
20631 unsigned char *
buf,*mybuf;
20633 struct pollfd fds[1];
20634 int size,res,fd,
len,x;
20656 if ((!p->
tdd) && (!p->
mate)) {
20657#if defined(HAVE_PRI)
20658#if defined(HAVE_PRI_DISPLAY_TEXT)
20683 for (x = 0;
text[x]; x++) {
20711 fds[0].events = POLLOUT | POLLPRI;
20712 fds[0].revents = 0;
20713 res = poll(fds, 1, -1);
20719 if (fds[0].revents & POLLPRI) {
20723 if (!(fds[0].revents & POLLOUT)) {
20727 res = write(fd,
buf, size);
20766 .
requires =
"ccss",
20767 .optional_modules =
"res_smdi",
Common implementation-independent jitterbuffer stuff.
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
ADSI Support (built upon Caller*ID)
void ast_cli_unregister_multiple(void)
A-Law to Signed linear conversion.
struct sla_ringing_trunk * last
static int copy(char *infile, char *outfile)
Utility function to copy a file.
Persistent data storage (akin to *doze registry)
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
char * strsep(char **str, const char *delims)
char * strcasestr(const char *, const char *)
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
@ AST_BRIDGE_TRANSFER_SUCCESS
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
void dahdi_native_unload(void)
int dahdi_native_load(const struct ast_channel_tech *tech)
Native DAHDI bridging support.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
int ast_callerid_callwaiting_full_generate(unsigned char *buf, const char *name, const char *number, const char *ddn, int redirecting, int pres, int qualifier, struct ast_format *codec)
Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)
#define CID_UNKNOWN_NUMBER
int ast_gen_cas(unsigned char *outbuf, int sas, int len, struct ast_format *codec)
Generate a CAS (CPE Alert Signal) tone for 'n' samples.
int ast_callerid_full_generate(unsigned char *buf, const char *name, const char *number, const char *ddn, int redirecting, int pres, int qualifier, int format, struct ast_format *codec)
Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format)
int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int samples, struct ast_format *codec)
Read samples into the state machine.
#define AST_PRES_USER_NUMBER_UNSCREENED
#define AST_PRES_UNAVAILABLE
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.
#define AST_PRES_RESTRICTED
void callerid_free(struct callerid_state *cid)
This function frees callerid_state cid.
void callerid_get_with_redirecting(struct callerid_state *cid, char **name, char **number, int *flags, int *redirecting)
Extract info out of callerID state machine. Flags are listed above.
#define MAX_CALLERID_SIZE
const char * ast_redirecting_reason_name(const struct ast_party_redirecting_reason *data)
Convert redirecting reason value to text code.
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)
#define CID_PRIVATE_NUMBER
struct callerid_state * callerid_new(int cid_signalling)
Create a callerID state machine.
int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, struct ast_format *codec)
Read samples into the state machine.
#define CID_MWI_TYPE_MDMF_FULL
void callerid_get_dtmf(char *cidstring, char *number, int *flags)
Get and parse DTMF-based callerid.
#define CID_START_POLARITY
void callerid_get(struct callerid_state *cid, char **number, char **name, int *flags)
Extract info out of callerID state machine. Flags are listed above.
#define CID_START_POLARITY_IN
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
#define CID_START_DTMF_NOALERT
Internal Asterisk hangup causes.
#define AST_CAUSE_SWITCH_CONGESTION
#define AST_CAUSE_CONGESTION
#define AST_CAUSE_UNALLOCATED
#define AST_CAUSE_INTERWORKING
#define AST_CAUSE_PROTOCOL_ERROR
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
#define AST_CAUSE_NO_USER_RESPONSE
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
#define AST_CAUSE_NOTDEFINED
#define AST_CAUSE_CALL_REJECTED
#define AST_CAUSE_NETWORK_OUT_OF_ORDER
#define AST_CAUSE_UNREGISTERED
#define AST_CAUSE_NO_ANSWER
#define AST_CAUSE_NORMAL_CLEARING
#define AST_CAUSE_USER_BUSY
Call Completion Supplementary Services API.
#define ast_cc_config_params_init()
Allocate and initialize an ast_cc_config_params structure.
#define AST_CC_GENERIC_MONITOR_TYPE
int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks)
Register a set of monitor callbacks with the core.
void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
Free memory from CCSS configuration params.
void(* ast_cc_callback_fn)(struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)
Callback made from ast_cc_callback for certain channel types.
int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks)
Register a set of agent callbacks with the core.
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
void ast_cc_monitor_unregister(const struct ast_cc_monitor_callbacks *callbacks)
Unregister a set of monitor callbacks with the core.
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
void ast_cc_agent_unregister(const struct ast_cc_agent_callbacks *callbacks)
Unregister a set of agent callbacks with the core.
int ast_cc_is_config_param(const char *const name)
Is this a CCSS configuration parameter?
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
static struct ao2_container * pvts
#define CALLPROGRESS_FAX_INCOMING
static int dahdi_create_channel_range(int start, int end)
static int dahdi_confmute(struct dahdi_pvt *p, int muted)
static ast_mutex_t ss_thread_lock
static int calc_energy(const unsigned char *buf, int len, struct ast_format *law)
#define CALLWAITING_SUPPRESS_SAMPLES
static int isourconf(struct dahdi_pvt *p, struct dahdi_subchannel *c)
static void release_doomed_pris(void)
static struct dahdi_pvt * round_robin[64]
static void my_set_new_owner(void *pvt, struct ast_channel *new_owner)
static int restore_gains(struct dahdi_pvt *p)
static void publish_channel_alarm_clear(int channel)
static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index)
static char * dahdi_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void my_set_confirmanswer(void *pvt, int flag)
#define CIDCW_EXPIRE_SAMPLES
static int my_dahdi_write(struct dahdi_pvt *p, unsigned char *buf, int len, int idx, int linear)
static int my_callwait(void *pvt)
static int restore_conference(struct dahdi_pvt *p)
static void publish_span_alarm_clear(int span)
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt's)
static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
static void notify_message(char *mailbox, int thereornot)
Send MWI state change.
static struct dahdi_pvt * mkintf(int channel, const struct dahdi_chan_conf *conf, int reloading)
static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel)
static int unalloc_sub(struct dahdi_pvt *p, int x)
static int my_check_confirmanswer(void *pvt)
static const char *const events[]
static int reset_conf(struct dahdi_pvt *p)
static int my_is_dialing(void *pvt, enum analog_sub sub)
static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoperation *dop)
static struct ast_manager_event_blob * dahdichannel_to_ami(struct stasis_message *msg)
static void my_cancel_cidspill(void *pvt)
static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out)
static int my_set_echocanceller(void *pvt, int enable)
static int dahdi_wink(struct dahdi_pvt *p, int index)
static char mwimonitornotify[PATH_MAX]
static char * alarm2str(int alm)
static void my_hangup_polarityswitch(void *pvt)
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 dahdi_ring_phone(struct dahdi_pvt *p)
static char * dahdi_show_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define CALLWAITING_REPEAT_SAMPLES
static void dahdi_lock_sub_owner(struct dahdi_pvt *pvt, int sub_idx)
#define CALLPROGRESS_FAX_OUTGOING
static int dahdi_call(struct ast_channel *ast, const char *rdest, int timeout)
static int my_stop_cid_detect(void *pvt)
static int my_get_sub_fd(void *pvt, enum analog_sub sub)
static void my_set_needringing(void *pvt, int value)
static char * dahdi_destroy_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_jb_conf default_jbconf
static int dahdi_cc_callback(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback)
Callback made when dial failed to get a channel out of dahdi_request().
static struct dahdi_pvt * find_channel_from_str(const char *channel)
static int __unload_module(void)
static void dahdi_softhangup_all(void)
static void dahdi_train_ec(struct dahdi_pvt *p)
static int build_channels(struct dahdi_chan_conf *conf, const char *value, int reload, int lineno)
static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
static enum analog_event dahdievent_to_analogevent(int event)
static int dahdi_digit_begin(struct ast_channel *ast, char digit)
static void my_unlock_private(void *pvt)
static int dahdichan_helper(struct ast_channel *chan, char *data, const char *value, char *buffer, size_t buflen)
static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
static void my_set_dialing(void *pvt, int is_dialing)
static void my_handle_dtmf(void *pvt, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
static void publish_dnd_state(int channel, const char *status)
static int my_on_hook(void *pvt)
static int attempt_transfer(struct dahdi_pvt *p)
static int cidrings[NUM_CADENCE_MAX]
cidrings says in which pause to transmit the cid information, where the first pause is 1,...
static void my_set_pulsedial(void *pvt, int flag)
static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
static char * dahdi_set_hwgain(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int dahdi_wait_event(int fd)
Avoid the silly dahdi_waitevent which ignores a bunch of events.
static void publish_channel_alarm(int channel, const char *alarm_txt)
static int canmatch_featurecode(const char *pickupexten, const char *exten)
static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law)
struct analog_callback analog_callbacks
static void dahdi_destroy_channel_range(int start, int end)
static char * dahdi_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int my_unallocate_sub(void *pvt, enum analog_sub analogsub)
static void my_set_alarm(void *pvt, int in_alarm)
static int num_restart_pending
static int my_dsp_set_digitmode(void *pvt, enum analog_dsp_digitmode mode)
static int my_get_event(void *pvt)
static int available(struct dahdi_pvt **pvt, int is_specific_channel)
static int dahdi_devicestate(const char *data)
static int user_has_defined_cadences
static int dahdi_callwait(struct ast_channel *ast)
static void wakeup_sub(struct dahdi_pvt *p, int a)
static void my_set_callwaiting(void *pvt, int callwaiting_enable)
static int distinctiveringaftercid
static int my_is_off_hook(void *pvt)
static int mwi_send_init(struct dahdi_pvt *pvt)
static int dahdi_open(char *fn)
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.
static int my_check_waitingfordt(void *pvt)
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 void publish_span_alarm(int span, const char *alarm_txt)
static int dahdichan_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
static void my_set_outgoing(void *pvt, int is_outgoing)
static int dahdi_fake_event(struct dahdi_pvt *p, int mode)
static void my_set_inthreeway(void *pvt, enum analog_sub sub, int inthreeway)
static void destroy_dahdi_pvt(struct dahdi_pvt *pvt)
static int dahdi_hangup(struct ast_channel *ast)
static void * analog_ss_thread(void *data)
static int dahdi_sendtext(struct ast_channel *c, const char *text)
static void dahdi_ami_channel_event(struct dahdi_pvt *p, struct ast_channel *chan)
static int dahdichan_read_property(struct dahdi_pvt *p, struct dahdi_params *dahdip, const char *property, char *buffer, size_t len)
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)
#define PROC_DAHDI_OPT_NOCHAN
static void parse_busy_pattern(struct ast_variable *v, struct ast_dsp_busy_pattern *busy_cadence)
static int analogsub_to_dahdisub(enum analog_sub analogsub)
static void my_get_and_handle_alarms(void *pvt)
static void my_lock_private(void *pvt)
static int dahdi_answer(struct ast_channel *ast)
static const char tdesc[]
static void fill_txgain(struct dahdi_gains *g, float gain, float drc, int law)
static int dahdi_restart(void)
static int action_transfer(struct mansession *s, const struct message *m)
static int bump_gains(struct dahdi_pvt *p)
static void * do_monitor(void *data)
static int save_conference(struct dahdi_pvt *p)
static char * dahdi_set_dnd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void handle_clear_alarms(struct dahdi_pvt *p)
static int dahdi_queryoption(struct ast_channel *chan, int option, void *data, int *datalen)
static char * dahdi_sig2str(int sig)
static int dahdi_set_hook(int fd, int hs)
static int my_stop_callwait(void *pvt)
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 int check_for_conference(struct dahdi_pvt *p)
static struct dahdi_ring_cadence AS_RP_cadence
static int dahdichan_read(struct ast_channel *chan, const char *cmd, char *data, char *buffer, size_t buflen)
static int my_distinctive_ring(struct ast_channel *chan, void *pvt, int idx, int *ringdata)
void dahdi_ec_enable(struct dahdi_pvt *p)
static int dahdi_setlinear(int dfd, int linear)
static int restart_monitor(void)
static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent)
static int my_confmute(void *pvt, int mute)
static void * mwi_thread(void *data)
static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *caller)
static int sigtype_to_signalling(int sigtype)
static void my_decrease_ss_count(void)
static char * handle_dahdi_show_cadences(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int has_voicemail(struct dahdi_pvt *p)
static void dahdi_iflist_extract(struct dahdi_pvt *pvt)
void dahdi_conf_update(struct dahdi_pvt *p)
static int alloc_sub(struct dahdi_pvt *p, int x)
static void my_start_polarityswitch(void *pvt)
static int digit_to_dtmfindex(char digit)
static int setup_dahdi(int reload)
static char * dahdi_set_mwi(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int action_dahdidndon(struct mansession *s, const struct message *m)
static struct dahdi_pvt * iflist
#define NEED_MFDETECT(p)
Signaling types that need to use MF detection should be placed in this macro.
static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen)
static int set_actual_txgain(int fd, float gain, float drc, int law)
static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value)
static int my_wait_event(void *pvt)
static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
static struct ast_channel * my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
static int analog_tone_to_dahditone(enum analog_tone tone)
static struct ast_str * create_channel_name(struct dahdi_pvt *i)
static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout)
static int set_actual_rxgain(int fd, float gain, float drc, int law)
static int my_start(void *pvt)
static ast_mutex_t restart_lock
static struct ast_frame * dahdi_handle_event(struct ast_channel *ast)
static char defaultcic[64]
static const char config[]
static int action_dahdishowchannels(struct mansession *s, const struct message *m)
void dahdi_dtmf_detect_enable(struct dahdi_pvt *p)
static struct dahdi_pvt * find_next_iface_in_span(struct dahdi_pvt *cur)
static ast_cond_t ss_thread_complete
static void process_echocancel(struct dahdi_chan_conf *confp, const char *data, unsigned int line)
static void dahdi_iflist_insert(struct dahdi_pvt *pvt)
static struct ast_frame * dahdi_exception(struct ast_channel *ast)
static void my_answer_polarityswitch(void *pvt)
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)
#define SMDI_MD_WAIT_TIMEOUT
static int my_have_progressdetect(void *pvt)
static char * dahdi_set_swgain(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
#define CANPROGRESSDETECT(p)
static char * dahdi_create_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void fill_rxgain(struct dahdi_gains *g, float gain, float drc, int law)
static int my_train_echocanceller(void *pvt)
static const char * event2str(int event)
#define CALLPROGRESS_PROGRESS
static void dahdi_close_sub(struct dahdi_pvt *chan_pvt, int sub_num)
#define CHAN_IS_FXO_SIG(sig)
static void my_set_polarity(void *pvt, int value)
void dahdi_ec_disable(struct dahdi_pvt *p)
static struct ast_frame * __dahdi_exception(struct ast_channel *ast)
static void handle_alarms(struct dahdi_pvt *p, int alms)
static void dahdi_handle_dtmf(struct ast_channel *ast, int idx, struct ast_frame **dest)
static struct dahdi_chan_conf dahdi_chan_conf_default(void)
static struct dahdi_pvt * duplicate_pseudo(struct dahdi_pvt *src)
static void swap_subs(struct dahdi_pvt *p, int a, int b)
static int my_set_linear_mode(void *pvt, enum analog_sub sub, int linear_mode)
static int dahdi_dnd(struct dahdi_pvt *dahdichan, int flag)
enable or disable the chan_dahdi Do-Not-Disturb mode for a DAHDI channel
static 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 int drc_sample(int sample, float drc)
static int dahdi_get_event(int fd)
Avoid the silly dahdi_getevent which ignores a bunch of events.
static int ringt_base
Configured ring timeout base.
void dahdi_master_slave_unlink(struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
static ast_mutex_t monlock
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing some...
#define ASCII_BYTES_PER_CHAR
static void my_all_subchannels_hungup(void *pvt)
static int my_ring(void *pvt)
static int my_start_cid_detect(void *pvt, int cid_signalling)
static int parse_buffers_policy(const char *parse, int *num_buffers, int *policy)
static struct dahdi_pvt * ifend
static char * dahdi_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int my_complete_conference_update(void *pvt, int needconference)
#define DEFAULT_DIALTONE_DETECT_TIMEOUT
#define IS_FXO_SIG(p)
Whether a channel is FXO signaled.
static int mwi_send_process_buffer(struct dahdi_pvt *pvt, int num_read)
static void my_set_cadence(void *pvt, int *cid_rings, struct ast_channel *ast)
static void my_increase_ss_count(void)
#define REPORT_CHANNEL_ALARMS
static int my_play_tone(void *pvt, enum analog_sub sub, enum analog_tone tone)
static int my_wink(void *pvt, enum analog_sub sub)
static struct ast_channel_tech dahdi_tech
static struct ast_jb_conf global_jbconf
#define REQUIRE_FXO_SIG()
static int my_conf_add(void *pvt, enum analog_sub sub)
static int my_dsp_reset_and_flush_digits(void *pvt)
void dahdi_dtmf_detect_disable(struct dahdi_pvt *p)
#define PROC_DAHDI_OPT_NOWARN
#define MIN_MS_SINCE_FLASH
static int my_has_voicemail(void *pvt)
static int load_module(void)
Load the module.
static struct ast_custom_function dahdichan_function
static struct ast_frame * dahdi_read(struct ast_channel *ast)
static const char * my_get_orig_dialstring(void *pvt)
static int action_dahdirestart(struct mansession *s, const struct message *m)
static struct ast_custom_function polarity_function
static int get_alarms(struct dahdi_pvt *p)
static struct dahdi_pvt * determine_starting_point(const char *data, struct dahdi_starting_point *param)
#define gen_pvt_field_callback(type, field)
static int polarity_read(struct ast_channel *chan, const char *cmd, char *data, char *buffer, size_t buflen)
static int send_cwcidspill(struct dahdi_pvt *p)
static int my_conf_del(void *pvt, enum analog_sub sub)
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX]
static int action_dahdidndoff(struct mansession *s, const struct message *m)
static int unload_module(void)
static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct ast_variable *v, int reload, int options)
static struct ast_cli_entry dahdi_cli[]
#define DEFAULT_CIDRINGS
Typically, how many rings before we should send Caller*ID.
static int dahdichan_write_property(struct dahdi_pvt *p, struct dahdi_params *dahdip, const char *property, const char *value)
static enum analog_sigtype dahdisig_to_analogsig(int sig)
static void dahdi_close(int fd)
static char defaultozz[64]
void dahdi_master_slave_link(struct dahdi_pvt *slave, struct dahdi_pvt *master)
static int my_off_hook(void *pvt)
const char *const subnames[]
static int my_allocate_sub(void *pvt, enum analog_sub analogsub)
static int usedistinctiveringdetection
static int polarity_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int print_subchannel(struct dahdi_pvt *p, int subchan, char *buffer, size_t len)
static char * dahdi_restart_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct dahdi_pvt * find_channel(int channel)
static void * my_get_sigpvt_bridged_channel(struct ast_channel *chan)
static int send_callerid(struct dahdi_pvt *p)
static int set_hwgain(int fd, float gain, int tx_direction)
static void my_set_waitingfordt(void *pvt, struct ast_channel *ast)
static void build_alarm_info(char *restrict alarmstr, struct dahdi_spaninfo *spaninfo)
static struct @116 alarms[]
static int my_check_for_conference(void *pvt)
static int mwi_send_process_event(struct dahdi_pvt *pvt, int event)
static int my_flash(void *pvt)
static int ss_thread_count
static const char *const lbostr[]
int _dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line)
#define REPORT_SPAN_ALARMS
static void deep_copy_dahdi_chan_conf(struct dahdi_chan_conf *dest, const struct dahdi_chan_conf *src)
static void my_deadlock_avoidance_private(void *pvt)
static struct dahdi_pvt * handle_init_event(struct dahdi_pvt *i, int event)
static void destroy_channel(struct dahdi_pvt *cur, int now)
static void my_set_ringtimeout(void *pvt, int ringt)
static void monitor_pfds_clean(void *arg)
static int action_dahdidialoffhook(struct mansession *s, const struct message *m)
static int dahdi_dial_str(struct dahdi_pvt *pvt, int operation, const char *dial_str)
static pthread_t monitor_thread
This is the thread for the monitor which checks for input on the channels which are not currently in ...
static int action_transferhangup(struct mansession *s, const struct message *m)
static int revert_fax_buffers(struct dahdi_pvt *p, struct ast_channel *ast)
static void destroy_all_channels(void)
static int action_dahdishowstatus(struct mansession *s, const struct message *m)
DAHDI internal API definitions.
static int dahdi_sig_pri_lib_handles(int signaling)
static int dahdi_analog_lib_handles(int signalling, int radio, int oprmode)
#define SIG_PRI_LIB_HANDLE_CASES
#define dahdi_get_index(ast, p, nullok)
static struct ast_timer * timer
General Asterisk PBX channel definitions.
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
const char * ast_channel_name(const struct ast_channel *chan)
static int ast_fdisset(struct pollfd *pfds, int fd, int maximum, int *start)
Helper function for migrating select to poll.
void ast_channel_rings_set(struct ast_channel *chan, int value)
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
void ast_party_name_init(struct ast_party_name *init)
Initialize the given name structure.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_format * ast_channel_rawreadformat(struct ast_channel *chan)
void ast_party_number_init(struct ast_party_number *init)
Initialize the given number structure.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
#define CHECK_BLOCKING(c)
Set the blocking indication on the channel.
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
#define ast_channel_lock(chan)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
struct ast_namedgroups * ast_ref_namedgroups(struct ast_namedgroups *groups)
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
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.
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
unsigned long long ast_group_t
#define ast_channel_ref(c)
Increase channel reference count.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_channel_accountcode(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
void ast_party_caller_set(struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update)
Set the caller information based on another caller source.
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
#define ast_channel_trylock(chan)
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
void ast_party_name_free(struct ast_party_name *doomed)
Destroy the party name contents.
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.
int ast_channel_fd(const struct ast_channel *chan, int which)
void ast_channel_internal_fd_set(struct ast_channel *chan, int which, int value)
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
void ast_party_caller_free(struct ast_party_caller *doomed)
Destroy the caller party contents.
int ast_active_channels(void)
returns number of active/allocated channels
struct ast_namedgroups * ast_get_namedgroups(const char *s)
Create an ast_namedgroups set with group names from comma separated string.
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
int ast_channel_hangupcause(const struct ast_channel *chan)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)